Version 2.2.1-dev.4.0 Merge commit '523e3789e05ea07cdd21feadb04dc8ea0174204e' into dev
diff --git a/.packages b/.packages index cf69a8b..08c0d29 100644 --- a/.packages +++ b/.packages
@@ -97,7 +97,6 @@ typed_data:third_party/pkg/typed_data/lib unittest:third_party/pkg/unittest/lib usage:third_party/pkg/usage/lib -utf:third_party/pkg/utf/lib vm:pkg/vm/lib watcher:third_party/pkg/watcher/lib web_components:third_party/pkg/web_components/lib
diff --git a/CHANGELOG.md b/CHANGELOG.md index f3ef64c7..8aa7a1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md
@@ -1,3 +1,21 @@ +## 2.2.1-dev.4.0 + +### Dart VM + +* The VM service now requires an authentication code by default. This behavior + can be disabled by providing the `--disable-service-auth-codes` flag. + +### Tool Changes + +#### Linter + +The Linter was updated to `0.1.85` which includes the following changes: + +* (**BREAKING**) renamed `spread_collections` to `prefer_spread_collections` +* new lint: `prefer_for_elements_to_map_fromIterable` +* new lint: `prefer_if_elements_to_conditional_expressions` +* new lint: `diagnostic_describe_all_properties` + ## 2.2.1-dev.3.1 * Cherry-pick 245576a096a2da54ef21d664d37d1f50f6f8dbb7 to dev @@ -13,6 +31,10 @@ ## 2.2.1-dev.3.0 +### Dart VM + +* Support for deprecated flags '-c' and '--checked' has been removed + ### Core library changes #### `dart:isolate` @@ -33,13 +55,10 @@ The Linter was updated to `0.1.83` which includes the following changes: * updated `file_names` to skip prefixed-extension Dart files (e.g., `.css.dart`, `.g.dart`) -* updated SDK constraint to `2.2.0` * miscellaneous rule documentation fixes -* (internal) updated sources to use Set literals * fixed NPE in `avoid_shadowing_type_parameters` * added linter version numbering for use in analyzer summaries * fixed type utilities to handle inheritance cycles -* (internal) changes to adopt new `package:analyzer` APIs * fixed `unnecessary_parenthesis` false positives ## 2.2.1-dev.2.0
diff --git a/DEPS b/DEPS index 5c76e5a..9d0806f 100644 --- a/DEPS +++ b/DEPS
@@ -36,7 +36,7 @@ "chromium_git": "https://chromium.googlesource.com", "fuchsia_git": "https://fuchsia.googlesource.com", - "co19_2_rev": "c3b33ee90c5ee7f88fdb0ead08fdbb40c54954d2", + "co19_2_rev": "7e743ef29b4c06f1a2b8b9dc70ead60b31aab526", # As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision # should be kept up to date with the revisions pulled by the Flutter engine. @@ -84,7 +84,7 @@ "dartdoc_tag" : "v0.28.2", "fixnum_tag": "0.10.9", "glob_tag": "1.1.7", - "html_tag" : "0.13.4+1", + "html_tag" : "0.14.0", "http_io_rev": "57da05a66f5bf7df3dd7aebe7b7efe0dfc477baa", "http_multi_server_tag" : "2.0.5", "http_parser_tag" : "3.1.3", @@ -95,7 +95,7 @@ "intl_tag": "0.15.7", "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1", "json_rpc_2_tag": "2.0.9", - "linter_tag": "0.1.83", + "linter_tag": "0.1.85", "logging_tag": "0.11.3+2", "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783", "markdown_tag": "2.0.2", @@ -135,7 +135,6 @@ "typed_data_tag": "1.1.6", "unittest_rev": "2b8375bc98bb9dc81c539c91aaea6adce12e1072", "usage_tag": "3.4.0", - "utf_tag": "0.9.0+5", "watcher_rev": "0.9.7+12", "web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02", "web_socket_channel_tag": "1.0.9", @@ -156,7 +155,7 @@ Var("dart_root") + "/tools/sdks": { "packages": [{ "package": "dart/dart-sdk/${{platform}}", - "version": "version:2.2.1-dev.1.1", + "version": "version:2.2.1-dev.3.1", }], "dep_type": "cipd", }, @@ -362,8 +361,6 @@ "@" + Var("unittest_rev"), Var("dart_root") + "/third_party/pkg/usage": Var("dart_git") + "usage.git" + "@" + Var("usage_tag"), - Var("dart_root") + "/third_party/pkg/utf": - Var("dart_git") + "utf.git" + "@" + Var("utf_tag"), Var("dart_root") + "/third_party/pkg/watcher": Var("dart_git") + "watcher.git" + "@" + Var("watcher_rev"), Var("dart_root") + "/third_party/pkg/web_components":
diff --git a/WATCHLISTS b/WATCHLISTS index 598f0ab..415a9bd 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -80,7 +80,7 @@ 'alexmarkov@google.com' ], 'messages_review': [ 'dart-uxr+reviews@google.com' ], 'mirrors' : [ 'rmacnak@google.com' ], - 'observatory': [ 'rmacnak@google.com' ], + 'observatory': [ 'bkonyi@google.com', 'rmacnak@google.com' ], 'package_vm': [ 'alexmarkov@google.com' ], 'runtime': [ 'vm-dev@dartlang.org' ], 'vm_compiler': [ 'dart-vm-compiler-team+reviews@google.com' ],
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html index f384766..204d162 100644 --- a/pkg/analysis_server/doc/api.html +++ b/pkg/analysis_server/doc/api.html
@@ -109,7 +109,7 @@ <body> <h1>Analysis Server API Specification</h1> <h1 style="color:#999999">Version - 1.25.0 + 1.26.0 </h1> <p> This document contains a specification of the API provided by the
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart index 0125a30..35174b9 100644 --- a/pkg/analysis_server/lib/protocol/protocol_constants.dart +++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -6,7 +6,7 @@ // To regenerate the file, use the script // "pkg/analysis_server/tool/spec/generate_files". -const String PROTOCOL_VERSION = '1.25.0'; +const String PROTOCOL_VERSION = '1.26.0'; const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles'; const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories'; @@ -201,6 +201,7 @@ const String EDIT_REQUEST_IMPORT_ELEMENTS = 'edit.importElements'; const String EDIT_REQUEST_IMPORT_ELEMENTS_ELEMENTS = 'elements'; const String EDIT_REQUEST_IMPORT_ELEMENTS_FILE = 'file'; +const String EDIT_REQUEST_IMPORT_ELEMENTS_OFFSET = 'offset'; const String EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE = 'edit.isPostfixCompletionApplicable'; const String EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE_FILE = 'file';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart index ad7e249..6e7da59 100644 --- a/pkg/analysis_server/lib/protocol/protocol_generated.dart +++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -10303,6 +10303,7 @@ * { * "file": FilePath * "elements": List<ImportedElements> + * "offset": optional int * } * * Clients may not extend, implement or mix-in this class. @@ -10312,6 +10313,8 @@ List<ImportedElements> _elements; + int _offset; + /** * The file in which the specified elements are to be made accessible. */ @@ -10338,9 +10341,29 @@ this._elements = value; } - EditImportElementsParams(String file, List<ImportedElements> elements) { + /** + * The offset at which the specified elements need to be made accessible. If + * provided, this is used to guard against adding imports for text that would + * be inserted into a comment, string literal, or other location where the + * imports would not be necessary. + */ + int get offset => _offset; + + /** + * The offset at which the specified elements need to be made accessible. If + * provided, this is used to guard against adding imports for text that would + * be inserted into a comment, string literal, or other location where the + * imports would not be necessary. + */ + void set offset(int value) { + this._offset = value; + } + + EditImportElementsParams(String file, List<ImportedElements> elements, + {int offset}) { this.file = file; this.elements = elements; + this.offset = offset; } factory EditImportElementsParams.fromJson( @@ -10365,7 +10388,11 @@ } else { throw jsonDecoder.mismatch(jsonPath, "elements"); } - return new EditImportElementsParams(file, elements); + int offset; + if (json.containsKey("offset")) { + offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); + } + return new EditImportElementsParams(file, elements, offset: offset); } else { throw jsonDecoder.mismatch(jsonPath, "edit.importElements params", json); } @@ -10382,6 +10409,9 @@ result["file"] = file; result["elements"] = elements.map((ImportedElements value) => value.toJson()).toList(); + if (offset != null) { + result["offset"] = offset; + } return result; } @@ -10398,7 +10428,8 @@ if (other is EditImportElementsParams) { return file == other.file && listEqual(elements, other.elements, - (ImportedElements a, ImportedElements b) => a == b); + (ImportedElements a, ImportedElements b) => a == b) && + offset == other.offset; } return false; } @@ -10408,6 +10439,7 @@ int hash = 0; hash = JenkinsSmiHash.combine(hash, file.hashCode); hash = JenkinsSmiHash.combine(hash, elements.hashCode); + hash = JenkinsSmiHash.combine(hash, offset.hashCode); return JenkinsSmiHash.finish(hash); } } @@ -21541,7 +21573,7 @@ * * { * "lexeme": String - * "type": String + * "type": optional String * "validElementKinds": optional List<String> * } * @@ -21555,12 +21587,12 @@ List<String> _validElementKinds; /** - * The raw token text. + * The token's lexeme. */ String get lexeme => _lexeme; /** - * The raw token text. + * The token's lexeme. */ void set lexeme(String value) { assert(value != null); @@ -21568,31 +21600,38 @@ } /** - * The type of this token. + * A unique id for the type of the identifier. Omitted if the token is not an + * identifier in a reference position. */ String get type => _type; /** - * The type of this token. + * A unique id for the type of the identifier. Omitted if the token is not an + * identifier in a reference position. */ void set type(String value) { - assert(value != null); this._type = value; } /** - * The kinds of elements which could validly replace this token. + * An indication of whether this token is in a declaration or reference + * position. (If no other purpose is found for this field then it should be + * renamed and converted to a boolean value.) Omitted if the token is not an + * identifier. */ List<String> get validElementKinds => _validElementKinds; /** - * The kinds of elements which could validly replace this token. + * An indication of whether this token is in a declaration or reference + * position. (If no other purpose is found for this field then it should be + * renamed and converted to a boolean value.) Omitted if the token is not an + * identifier. */ void set validElementKinds(List<String> value) { this._validElementKinds = value; } - TokenDetails(String lexeme, String type, {List<String> validElementKinds}) { + TokenDetails(String lexeme, {String type, List<String> validElementKinds}) { this.lexeme = lexeme; this.type = type; this.validElementKinds = validElementKinds; @@ -21613,8 +21652,6 @@ String type; if (json.containsKey("type")) { type = jsonDecoder.decodeString(jsonPath + ".type", json["type"]); - } else { - throw jsonDecoder.mismatch(jsonPath, "type"); } List<String> validElementKinds; if (json.containsKey("validElementKinds")) { @@ -21623,8 +21660,8 @@ json["validElementKinds"], jsonDecoder.decodeString); } - return new TokenDetails(lexeme, type, - validElementKinds: validElementKinds); + return new TokenDetails(lexeme, + type: type, validElementKinds: validElementKinds); } else { throw jsonDecoder.mismatch(jsonPath, "TokenDetails", json); } @@ -21634,7 +21671,9 @@ Map<String, dynamic> toJson() { Map<String, dynamic> result = {}; result["lexeme"] = lexeme; - result["type"] = type; + if (type != null) { + result["type"] = type; + } if (validElementKinds != null) { result["validElementKinds"] = validElementKinds; }
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart index 50834b3..3ed2774 100644 --- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart +++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -70,7 +70,8 @@ '**/*.${AnalysisEngine.SUFFIX_HTM}', '**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}', '**/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}', - '**/${AnalysisEngine.PUBSPEC_YAML_FILE}' + '**/${AnalysisEngine.PUBSPEC_YAML_FILE}', + '**/${AnalysisEngine.ANDROID_MANIFEST_FILE}' ]; /// The [ResourceProvider] using which paths are converted into [Resource]s.
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart index f9ce8ac..b8adeca 100644 --- a/pkg/analysis_server/lib/src/context_manager.dart +++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -24,6 +24,7 @@ import 'package:analyzer/src/generated/source.dart'; import 'package:analyzer/src/generated/source_io.dart'; import 'package:analyzer/src/plugin/resolver_provider.dart'; +import 'package:analyzer/src/manifest/manifest_validator.dart'; import 'package:analyzer/src/pubspec/pubspec_validator.dart'; import 'package:analyzer/src/source/package_map_resolver.dart'; import 'package:analyzer/src/source/path_filter.dart'; @@ -394,6 +395,11 @@ static const String LIB_DIR_NAME = 'lib'; /** + * File name of Android manifest files. + */ + static const String MANIFEST_NAME = 'AndroidManifest.xml'; + + /** * File name of pubspec files. */ static const String PUBSPEC_NAME = 'pubspec.yaml'; @@ -891,6 +897,32 @@ convertedErrors ?? <protocol.AnalysisError>[]); } + /** + * Use the given analysis [driver] to analyze the content of the + * AndroidManifest file at the given [path]. + */ + void _analyzeManifestFile(AnalysisDriver driver, String path) { + List<protocol.AnalysisError> convertedErrors; + try { + String content = _readFile(path); + ManifestValidator validator = + new ManifestValidator(resourceProvider.getFile(path).createSource()); + LineInfo lineInfo = _computeLineInfo(content); + List<AnalysisError> errors = validator.validate( + content, driver.analysisOptions.chromeOsManifestChecks); + AnalyzerConverter converter = new AnalyzerConverter(); + convertedErrors = converter.convertAnalysisErrors(errors, + lineInfo: lineInfo, options: driver.analysisOptions); + } catch (exception) { + // If the file cannot be analyzed, fall through to clear any previous + // errors. + } + callbacks.notificationManager.recordAnalysisErrors( + NotificationManager.serverId, + path, + convertedErrors ?? <protocol.AnalysisError>[]); + } + void _checkForAnalysisOptionsUpdate(String path, ContextInfo info) { if (AnalysisEngine.isAnalysisOptionsFileName(path, pathContext)) { AnalysisDriver driver = info.analysisDriver; @@ -936,6 +968,19 @@ } } + void _checkForManifestUpdate(String path, ContextInfo info) { + if (_isManifest(path)) { + AnalysisDriver driver = info.analysisDriver; + if (driver == null) { + // I suspect that this happens as a result of a race condition: server + // has determined that the file (at [path]) is in a context, but hasn't + // yet created a driver for that context. + return; + } + _analyzeManifestFile(driver, path); + } + } + /** * 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 @@ -1094,6 +1139,10 @@ if (pubspecFile.exists) { _analyzePubspecFile(info.analysisDriver, pubspecFile.path); } + File manifestFile = folder.getChildAssumingFile(MANIFEST_NAME); + if (manifestFile.exists) { + _analyzeManifestFile(info.analysisDriver, manifestFile.path); + } return info; } @@ -1409,6 +1458,7 @@ _checkForPackagespecUpdate(path, info); _checkForAnalysisOptionsUpdate(path, info); _checkForPubspecUpdate(path, info); + _checkForManifestUpdate(path, info); } /** @@ -1465,6 +1515,8 @@ bool _isPubspec(String path) => pathContext.basename(path) == PUBSPEC_NAME; + bool _isManifest(String path) => pathContext.basename(path) == MANIFEST_NAME; + /** * Merges [info] context into its parent. */
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart index e5d221d..3951541 100644 --- a/pkg/analysis_server/lib/src/domain_completion.dart +++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -39,7 +39,7 @@ /** * The completion services that the client is currently subscribed. */ - final Set<CompletionService> _subscriptions = Set<CompletionService>(); + final Set<CompletionService> subscriptions = Set<CompletionService>(); /** * The next completion response id. @@ -365,7 +365,7 @@ // create the kinds set, so signal the completion manager about opt-in. Set<ElementKind> includedElementKinds; List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags; - if (_subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) { + if (subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) { includedElementKinds = Set<ElementKind>(); includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[]; } @@ -461,10 +461,10 @@ Response setSubscriptions(Request request) { var params = CompletionSetSubscriptionsParams.fromRequest(request); - _subscriptions.clear(); - _subscriptions.addAll(params.subscriptions); + subscriptions.clear(); + subscriptions.addAll(params.subscriptions); - if (_subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) { + if (subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) { server.createDeclarationsTracker((change) { server.sendNotification( createCompletionAvailableSuggestionsNotification(change),
diff --git a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart index c3085a7..bbe879f 100644 --- a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart +++ b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
@@ -72,13 +72,7 @@ ) { return protocol.CompletionAvailableSuggestionsParams( changedLibraries: change.changed.map((library) { - return protocol.AvailableSuggestionSet( - library.id, - library.uriStr, - library.declarations.map((declaration) { - return _protocolAvailableSuggestion(declaration); - }).toList(), - ); + return _protocolAvailableSuggestionSet(library); }).toList(), removedLibraries: change.removed, ).toNotification(); @@ -103,13 +97,13 @@ Declaration declaration) { var label = declaration.name; if (declaration.kind == DeclarationKind.CONSTRUCTOR) { - label = declaration.name2; + label = declaration.parent.name; if (declaration.name.isNotEmpty) { label += '.${declaration.name}'; } } if (declaration.kind == DeclarationKind.ENUM_CONSTANT) { - label = '${declaration.name2}.${declaration.name}'; + label = '${declaration.parent.name}.${declaration.name}'; } List<String> relevanceTags; @@ -134,6 +128,23 @@ ); } +protocol.AvailableSuggestionSet _protocolAvailableSuggestionSet( + Library library) { + var items = <protocol.AvailableSuggestion>[]; + + void addItem(Declaration declaration) { + var suggestion = _protocolAvailableSuggestion(declaration); + items.add(suggestion); + declaration.children.forEach(addItem); + } + + for (var declaration in library.declarations) { + addItem(declaration); + } + + return protocol.AvailableSuggestionSet(library.id, library.uriStr, items); +} + protocol.Element _protocolElement(Declaration declaration) { return protocol.Element( _protocolElementKind(declaration.kind),
diff --git a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart index 931932e..0525b77 100644 --- a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart +++ b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
@@ -21,6 +21,7 @@ final AnalysisServer server; final Request request; + final pkgFolders = <Folder>[]; final fixFolders = <Folder>[]; final fixFiles = <File>[]; @@ -78,6 +79,11 @@ contextManager.isInAnalysisRoot(filePath))) { return new Response.fileNotAnalyzed(request, filePath); } + var pkgFolder = + findPkgFolder(contextManager.getContextFolderFor(filePath)); + if (pkgFolder != null && !pkgFolders.contains(pkgFolder)) { + pkgFolders.add(pkgFolder); + } if (res is Folder) { fixFolders.add(res); } else { @@ -85,6 +91,11 @@ } } + // Process each package + for (Folder pkgFolder in pkgFolders) { + await processPackage(pkgFolder); + } + // Process each source file. bool hasErrors = false; String changedPath; @@ -135,6 +146,17 @@ ).toResponse(request.id); } + Folder findPkgFolder(Folder folder) { + while (folder != null) { + if (folder.getChild('analysis_options.yaml').exists || + folder.getChild('pubspec.yaml').exists) { + return folder; + } + folder = folder.parent; + } + return null; + } + /// Return `true` if the path in within the set of `included` files /// or is within an `included` directory. bool isIncluded(String filePath) {
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart index 6b7a5a9..12a1d18 100644 --- a/pkg/analysis_server/lib/src/edit/edit_domain.dart +++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -22,6 +22,7 @@ import 'package:analysis_server/src/services/correction/assist_internal.dart'; import 'package:analysis_server/src/services/correction/change_workspace.dart'; import 'package:analysis_server/src/services/correction/fix.dart'; +import 'package:analysis_server/src/services/correction/fix/analysis_options/fix_generator.dart'; import 'package:analysis_server/src/services/correction/fix_internal.dart'; import 'package:analysis_server/src/services/correction/organize_directives.dart'; import 'package:analysis_server/src/services/correction/sort_members.dart'; @@ -33,16 +34,23 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/error/error.dart' as engine; +import 'package:analyzer/file_system/file_system.dart'; +// ignore: deprecated_member_use +import 'package:analyzer/source/analysis_options_provider.dart'; +import 'package:analyzer/source/line_info.dart'; import 'package:analyzer/src/dart/ast/utilities.dart'; import 'package:analyzer/src/dart/scanner/scanner.dart' as engine; import 'package:analyzer/src/error/codes.dart' as engine; import 'package:analyzer/src/generated/engine.dart' as engine; +import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/generated/parser.dart' as engine; import 'package:analyzer/src/generated/source.dart'; +import 'package:analyzer/src/task/options.dart'; import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin; import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; import 'package:dart_style/dart_style.dart'; +import 'package:yaml/yaml.dart'; int test_resetCount = 0; @@ -231,9 +239,7 @@ new EditGetDartfixInfoResult(allFixes.map((i) => i.asDartFix()).toList()) .toResponse(request.id); - Future getFixes(Request request) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; + Future<void> getFixes(Request request) async { EditGetFixesParams params = new EditGetFixesParams.fromRequest(request); String file = params.file; int offset = params.offset; @@ -241,7 +247,6 @@ if (server.sendResponseErrorIfInvalidFilePath(request, file)) { return; } - // // Allow plugins to start computing fixes. // @@ -569,12 +574,49 @@ } /** - * Compute and return the fixes associated with server-generated errors. + * Compute and return the fixes associated with server-generated errors in + * analysis options files. */ - Future<List<AnalysisErrorFixes>> _computeServerErrorFixes( + Future<List<AnalysisErrorFixes>> _computeAnalysisOptionsFixes( String file, int offset) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; + List<AnalysisErrorFixes> errorFixesList = <AnalysisErrorFixes>[]; + File optionsFile = server.resourceProvider.getFile(file); + String content = _safelyRead(optionsFile); + if (content == null) { + return errorFixesList; + } + LineInfo lineInfo = new LineInfo.fromContent(content); + SourceFactory sourceFactory = server.getAnalysisDriver(file).sourceFactory; + List<engine.AnalysisError> errors = analyzeAnalysisOptions( + optionsFile.createSource(), content, sourceFactory); + YamlMap options = _getOptions(sourceFactory, content); + if (options == null) { + return errorFixesList; + } + for (engine.AnalysisError error in errors) { + AnalysisOptionsFixGenerator generator = + new AnalysisOptionsFixGenerator(error, content, options); + List<Fix> fixes = await generator.computeFixes(); + if (fixes.isNotEmpty) { + fixes.sort(Fix.SORT_BY_RELEVANCE); + AnalysisError serverError = + newAnalysisError_fromEngine(lineInfo, error); + AnalysisErrorFixes errorFixes = new AnalysisErrorFixes(serverError); + errorFixesList.add(errorFixes); + fixes.forEach((fix) { + errorFixes.fixes.add(fix.change); + }); + } + } + return errorFixesList; + } + + /** + * Compute and return the fixes associated with server-generated errors in + * Dart files. + */ + Future<List<AnalysisErrorFixes>> _computeDartFixes( + String file, int offset) async { List<AnalysisErrorFixes> errorFixesList = <AnalysisErrorFixes>[]; var result = await server.getResolvedUnit(file); if (result != null) { @@ -603,6 +645,20 @@ return errorFixesList; } + /** + * Compute and return the fixes associated with server-generated errors. + */ + Future<List<AnalysisErrorFixes>> _computeServerErrorFixes( + String file, int offset) async { + if (AnalysisEngine.isDartFileName(file)) { + return _computeDartFixes(file, offset); + } else if (AnalysisEngine.isAnalysisOptionsFileName( + file, server.resourceProvider.pathContext)) { + return _computeAnalysisOptionsFixes(file, offset); + } + return <AnalysisErrorFixes>[]; + } + Response _getAvailableRefactorings(Request request) { _getAvailableRefactoringsImpl(request); return Response.DELAYED_RESPONSE; @@ -676,6 +732,16 @@ server.sendResponse(result.toResponse(request.id)); } + YamlMap _getOptions(SourceFactory sourceFactory, String content) { + AnalysisOptionsProvider optionsProvider = + new AnalysisOptionsProvider(sourceFactory); + try { + return optionsProvider.getOptionsFromString(content); + } on OptionsFormatException { + return null; + } + } + Response _getRefactoring(Request request) { if (refactoringManager.hasPendingRequest) { refactoringManager.cancel(); @@ -692,6 +758,16 @@ refactoringManager = new _RefactoringManager(server, refactoringWorkspace); } + /// Return the contents of the [file], or `null` if the file does not exist or + /// cannot be read. + String _safelyRead(File file) { + try { + return file.readAsStringSync(); + } on FileSystemException { + return null; + } + } + static int _getNumberOfScanParseErrors(List<engine.AnalysisError> errors) { int numScanParseErrors = 0; for (engine.AnalysisError error in errors) {
diff --git a/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart b/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart index 3e6c9c8..728bb580 100644 --- a/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart +++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
@@ -8,8 +8,11 @@ import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart'; import 'package:analysis_server/src/edit/fix/fix_error_task.dart'; import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart'; +import 'package:analysis_server/src/edit/fix/prefer_for_elements_to_map_fromIterable_fix.dart'; +import 'package:analysis_server/src/edit/fix/prefer_if_elements_to_conditional_expressions_fix.dart'; import 'package:analysis_server/src/edit/fix/prefer_int_literals_fix.dart'; import 'package:analysis_server/src/edit/fix/prefer_mixin_fix.dart'; +import 'package:analysis_server/src/edit/fix/prefer_spread_collections_fix.dart'; const allFixes = <DartFixInfo>[ // @@ -33,22 +36,40 @@ const DartFixInfo( 'double-to-int', 'Find double literals ending in .0 and remove the .0\n' - 'wherever double context can be inferred.', + 'wherever double context can be inferred.', PreferIntLiteralsFix.task, ), // - // Expermimental fixes + // Experimental fixes // const DartFixInfo( 'non-nullable', // TODO(danrubel) update description and make default/required // when NNBD fix is ready 'Experimental: Update sources to be non-nullable by default.\n' - 'Requires the experimental non-nullable flag to be enabled.\n' - 'This is not applied unless explicitly included.', + 'Requires the experimental non-nullable flag to be enabled.\n' + 'This is not applied unless explicitly included.', NonNullableFix.task, isDefault: false, ), + const DartFixInfo( + 'use-spread-collections', + 'Convert to using collection spread operators.', + PreferSpreadCollectionsFix.task, + isDefault: false, + ), + const DartFixInfo( + 'collection-if-elements', + 'Convert to using if elements when building collections.', + PreferIfElementsToConditionalExpressionsFix.task, + isDefault: false, + ), + const DartFixInfo( + 'map-for-elements', + 'Convert to for elements when building maps from iterables.', + PreferForElementsToMapFromIterableFix.task, + isDefault: false, + ), ]; /// [DartFixInfo] represents a fix that can be applied by [EditDartFix].
diff --git a/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart b/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart index eaa28ad..e4f0b2e 100644 --- a/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart +++ b/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart
@@ -6,12 +6,17 @@ import 'package:analysis_server/src/edit/edit_dartfix.dart'; import 'package:analyzer/dart/analysis/results.dart'; +import 'package:analyzer/file_system/file_system.dart'; /// A general task for performing a fix. abstract class FixCodeTask { /// Number of times [processUnit] should be called for each compilation unit. int get numPhases; + /// [processPackage] is called once for each package + /// before [processUnit] is called for any compilation unit in any package. + Future<void> processPackage(Folder pkgFolder); + /// [processUnit] is called for each phase and compilation unit. /// /// First [processUnit] will be called once for each compilation unit with @@ -44,6 +49,12 @@ } } + void processPackage(Folder pkgFolder) async { + for (FixCodeTask task in _codeTasks) { + await task.processPackage(pkgFolder); + } + } + void registerCodeTask(FixCodeTask task) { _codeTasks.add(task); _numPhases = max(_numPhases, task.numPhases);
diff --git a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart index bc5b11b..61d3984 100644 --- a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart +++ b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
@@ -7,7 +7,12 @@ import 'package:analysis_server/src/edit/fix/fix_code_task.dart'; import 'package:analysis_server/src/nullability/provisional_api.dart'; import 'package:analyzer/dart/analysis/results.dart'; +import 'package:analyzer/file_system/file_system.dart'; +import 'package:analyzer/src/dart/analysis/experiments.dart'; +import 'package:analyzer/src/task/options.dart'; import 'package:analyzer_plugin/protocol/protocol_common.dart'; +import 'package:yaml/yaml.dart'; +import 'package:source_span/source_span.dart'; /// [NonNullableFix] visits each named type in a resolved compilation unit /// and determines whether the associated variable or parameter can be null @@ -21,6 +26,11 @@ final NullabilityMigration migration; + /// If this flag has a value of `false`, then something happened to prevent + /// at least one package from being marked as non-nullable. + /// If this occurs, then don't update any code. + bool _packageIsNNBD = true; + NonNullableFix(this.listener) : migration = new NullabilityMigration( new NullabilityMigrationAdapter(listener), @@ -34,8 +44,123 @@ migration.finish(); } + /// If the package contains an analysis_options.yaml file, then update the + /// file to enabled NNBD. If that file does not exist, but the package + /// contains a pubspec.yaml, then create the analysis_options.yaml file. + @override + Future<void> processPackage(Folder pkgFolder) async { + if (!_packageIsNNBD) { + return; + } + + // TODO(danrubel): Update pubspec.yaml to enable NNBD + + File optionsFile = pkgFolder.getChildAssumingFile('analysis_options.yaml'); + String optionsContent; + YamlNode optionsMap; + if (optionsFile.exists) { + try { + optionsContent = optionsFile.readAsStringSync(); + } on FileSystemException catch (e) { + processYamlException('read', optionsFile.path, e); + return; + } + try { + optionsMap = loadYaml(optionsContent); + } on YamlException catch (e) { + processYamlException('parse', optionsFile.path, e); + return; + } + } + + SourceSpan parentSpan; + String content; + YamlNode analyzerOptions; + if (optionsMap is YamlMap) { + analyzerOptions = optionsMap.nodes[AnalyzerOptions.analyzer]; + } + if (analyzerOptions == null) { + var start = new SourceLocation(0, line: 0, column: 0); + parentSpan = new SourceSpan(start, start, ''); + content = ''' +analyzer: + enable-experiment: + - non-nullable + +'''; + } else if (analyzerOptions is YamlMap) { + YamlNode experiments = + analyzerOptions.nodes[AnalyzerOptions.enableExperiment]; + if (experiments == null) { + parentSpan = analyzerOptions.span; + content = ''' + + enable-experiment: + - non-nullable'''; + } else if (experiments is YamlList) { + experiments.nodes.firstWhere( + (node) => node.span.text == EnableString.non_nullable, + orElse: () { + parentSpan = experiments.span; + content = ''' + + - non-nullable'''; + }, + ); + } + } + + if (parentSpan != null) { + final space = ' '.codeUnitAt(0); + final cr = '\r'.codeUnitAt(0); + final lf = '\n'.codeUnitAt(0); + + int line = parentSpan.end.line; + int offset = parentSpan.end.offset; + while (offset > 0) { + int ch = optionsContent.codeUnitAt(offset - 1); + if (ch == space || ch == cr) { + --offset; + } else if (ch == lf) { + --offset; + --line; + } else { + break; + } + } + listener.addSourceFileEdit( + 'enable non-nullable analysis', + new Location( + optionsFile.path, + offset, + content.length, + line, + 0, + ), + new SourceFileEdit(optionsFile.path, 0, + edits: [new SourceEdit(offset, 0, content)])); + } + } + + void processYamlException(String action, String optionsFilePath, error) { + listener.addRecommendation('''Failed to $action options file + $optionsFilePath + $error + + Manually update this file to enable non-nullable by adding: + + analyzer: + enable-experiment: + - non-nullable +'''); + _packageIsNNBD = false; + } + @override Future<void> processUnit(int phase, ResolvedUnitResult result) async { + if (!_packageIsNNBD) { + return; + } switch (phase) { case 0: migration.prepareInput(result);
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_for_elements_to_map_fromIterable_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_for_elements_to_map_fromIterable_fix.dart new file mode 100644 index 0000000..84ecff9 --- /dev/null +++ b/pkg/analysis_server/lib/src/edit/fix/prefer_for_elements_to_map_fromIterable_fix.dart
@@ -0,0 +1,69 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analysis_server/plugin/edit/assist/assist_core.dart'; +import 'package:analysis_server/src/edit/fix/dartfix_listener.dart'; +import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart'; +import 'package:analysis_server/src/edit/fix/fix_lint_task.dart'; +import 'package:analysis_server/src/services/correction/assist.dart'; +import 'package:analysis_server/src/services/correction/assist_internal.dart'; +import 'package:analysis_server/src/services/correction/change_workspace.dart'; +import 'package:analyzer/dart/analysis/results.dart'; +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer/error/error.dart'; +import 'package:analyzer/src/lint/registry.dart'; + +class PreferForElementsToMapFromIterableFix extends FixLintTask { + final List<AstNode> nodes = <AstNode>[]; + + PreferForElementsToMapFromIterableFix(DartFixListener listener) + : super(listener); + + @override + Future<void> applyLocalFixes(ResolvedUnitResult result) async { + while (nodes.isNotEmpty) { + AstNode node = nodes.removeLast(); + AssistProcessor processor = new AssistProcessor( + new DartAssistContextImpl( + DartChangeWorkspace(listener.server.currentSessions), + result, + node.offset, + node.length), + ); + List<Assist> assists = + await processor.computeAssist(DartAssistKind.CONVERT_TO_FOR_ELEMENT); + + final location = listener.locationFor(result, node.offset, node.length); + if (assists.isNotEmpty) { + for (Assist assist in assists) { + listener.addSourceChange( + assist.kind.message, location, assist.change); + } + } else { + listener.addRecommendation( + 'Convert to for elements assist not found', location); + } + } + + return null; + } + + @override + Future<void> applyRemainingFixes() { + return null; + } + + @override + void reportErrorForNode(ErrorCode errorCode, AstNode node, + [List<Object> arguments]) { + nodes.add(node); + } + + static void task(DartFixRegistrar registrar, DartFixListener listener) { + registrar.registerLintTask( + Registry.ruleRegistry['prefer_for_elements_to_map_fromIterable'], + new PreferForElementsToMapFromIterableFix(listener), + ); + } +}
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_if_elements_to_conditional_expressions_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_if_elements_to_conditional_expressions_fix.dart new file mode 100644 index 0000000..0dbdf26 --- /dev/null +++ b/pkg/analysis_server/lib/src/edit/fix/prefer_if_elements_to_conditional_expressions_fix.dart
@@ -0,0 +1,69 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analysis_server/plugin/edit/assist/assist_core.dart'; +import 'package:analysis_server/src/edit/fix/dartfix_listener.dart'; +import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart'; +import 'package:analysis_server/src/edit/fix/fix_lint_task.dart'; +import 'package:analysis_server/src/services/correction/assist.dart'; +import 'package:analysis_server/src/services/correction/assist_internal.dart'; +import 'package:analysis_server/src/services/correction/change_workspace.dart'; +import 'package:analyzer/dart/analysis/results.dart'; +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer/error/error.dart'; +import 'package:analyzer/src/lint/registry.dart'; + +class PreferIfElementsToConditionalExpressionsFix extends FixLintTask { + final List<AstNode> nodes = <AstNode>[]; + + PreferIfElementsToConditionalExpressionsFix(DartFixListener listener) + : super(listener); + + @override + Future<void> applyLocalFixes(ResolvedUnitResult result) async { + while (nodes.isNotEmpty) { + AstNode node = nodes.removeLast(); + AssistProcessor processor = new AssistProcessor( + new DartAssistContextImpl( + DartChangeWorkspace(listener.server.currentSessions), + result, + node.offset, + node.length), + ); + List<Assist> assists = + await processor.computeAssist(DartAssistKind.CONVERT_TO_IF_ELEMENT); + + final location = listener.locationFor(result, node.offset, node.length); + if (assists.isNotEmpty) { + for (Assist assist in assists) { + listener.addSourceChange( + assist.kind.message, location, assist.change); + } + } else { + listener.addRecommendation( + 'Convert to if elements assist not found', location); + } + } + + return null; + } + + @override + Future<void> applyRemainingFixes() { + return null; + } + + @override + void reportErrorForNode(ErrorCode errorCode, AstNode node, + [List<Object> arguments]) { + nodes.add(node); + } + + static void task(DartFixRegistrar registrar, DartFixListener listener) { + registrar.registerLintTask( + Registry.ruleRegistry['prefer_if_elements_to_conditional_expressions'], + new PreferIfElementsToConditionalExpressionsFix(listener), + ); + } +}
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_spread_collections_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_spread_collections_fix.dart new file mode 100644 index 0000000..caff2e6 --- /dev/null +++ b/pkg/analysis_server/lib/src/edit/fix/prefer_spread_collections_fix.dart
@@ -0,0 +1,68 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analysis_server/plugin/edit/assist/assist_core.dart'; +import 'package:analysis_server/src/edit/fix/dartfix_listener.dart'; +import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart'; +import 'package:analysis_server/src/edit/fix/fix_lint_task.dart'; +import 'package:analysis_server/src/services/correction/assist.dart'; +import 'package:analysis_server/src/services/correction/assist_internal.dart'; +import 'package:analysis_server/src/services/correction/change_workspace.dart'; +import 'package:analyzer/dart/analysis/results.dart'; +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer/error/error.dart'; +import 'package:analyzer/src/lint/registry.dart'; + +class PreferSpreadCollectionsFix extends FixLintTask { + final List<AstNode> nodes = <AstNode>[]; + + PreferSpreadCollectionsFix(DartFixListener listener) : super(listener); + + @override + Future<void> applyLocalFixes(ResolvedUnitResult result) async { + while (nodes.isNotEmpty) { + AstNode node = nodes.removeLast(); + AssistProcessor processor = new AssistProcessor( + new DartAssistContextImpl( + DartChangeWorkspace(listener.server.currentSessions), + result, + node.offset, + 0), + ); + List<Assist> assists = + await processor.computeAssist(DartAssistKind.CONVERT_TO_SPREAD); + + final location = listener.locationFor(result, node.offset, node.length); + if (assists.isNotEmpty) { + for (Assist assist in assists) { + listener.addSourceChange( + assist.kind.message, location, assist.change); + } + } else { + listener.addRecommendation( + 'Convert to spread assist not found', location); + } + } + + return null; + } + + @override + Future<void> applyRemainingFixes() { + return null; + } + + @override + void reportErrorForNode(ErrorCode errorCode, AstNode node, + [List<Object> arguments]) { + nodes.add(node); + } + + static void task(DartFixRegistrar registrar, DartFixListener listener) { + registrar.registerLintTask( + Registry.ruleRegistry['prefer_spread_collections'], + new PreferSpreadCollectionsFix(listener), + ); + } +}
diff --git a/pkg/analysis_server/lib/src/nullability/conditional_discard.dart b/pkg/analysis_server/lib/src/nullability/conditional_discard.dart index 4b47370..3e09ed4 100644 --- a/pkg/analysis_server/lib/src/nullability/conditional_discard.dart +++ b/pkg/analysis_server/lib/src/nullability/conditional_discard.dart
@@ -2,6 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:analysis_server/src/nullability/nullability_node.dart'; import 'package:analysis_server/src/nullability/unit_propagation.dart'; /// Container for information gathered during nullability migration about a @@ -11,15 +12,21 @@ /// whose boolean value influences control flow (e.g. the condition of an `if` /// statement). class ConditionalDiscard { - /// Constraint variable whose value will be `true` if the code path that - /// results from the condition evaluating to `true` will be reachable after + /// Nullability node that will be `nullable` if the code path that results + /// from the condition evaluating to `true` will be reachable after /// nullability migration, and therefore should be kept. - final ConstraintVariable keepTrue; + /// + /// `null` if the code path should be kept regardless of the outcome of + /// migration. + final NullabilityNode trueGuard; - /// Constraint variable whose value will be `false` if the code path that - /// results from the condition evaluating to `false` will be reachable after + /// Nullability node that will be `nullable` if the code path that results + /// from the condition evaluating to `false` will be reachable after /// nullability migration, and therefore should be kept. - final ConstraintVariable keepFalse; + /// + /// `null` if the code path should be kept regardless of the outcome of + /// migration. + final NullabilityNode falseGuard; /// Indicates whether the condition is pure (free from side effects). /// @@ -27,11 +34,19 @@ /// variable or static variable), because evaluating it has no user-visible /// effect other than returning a boolean value. /// - /// If [pureCondition] is `false`, and either [keepTrue] or [keepFalse] is + /// If [pureCondition] is `false`, and either [trueGuard] or [falseGuard] is /// `false`, that it is safe to delete the condition expression as well as the /// dead code branch (e.g. it means that `if (x == null) f(); else g();` could /// be changed to simply `g();`). final bool pureCondition; - ConditionalDiscard(this.keepTrue, this.keepFalse, this.pureCondition); + ConditionalDiscard(this.trueGuard, this.falseGuard, this.pureCondition); + + /// Indicates whether the code path that results from the condition evaluating + /// to `false` is reachable after migration. + bool get keepFalse => falseGuard == null || falseGuard.isNullable; + + /// Indicates whether the code path that results from the condition evaluating + /// to `true` is reachable after migration. + bool get keepTrue => trueGuard == null || trueGuard.isNullable; }
diff --git a/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart b/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart index d0802ad..a723c9a 100644 --- a/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart +++ b/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart
@@ -6,6 +6,7 @@ import 'package:analysis_server/src/nullability/constraint_variable_gatherer.dart'; import 'package:analysis_server/src/nullability/decorated_type.dart'; import 'package:analysis_server/src/nullability/expression_checks.dart'; +import 'package:analysis_server/src/nullability/nullability_node.dart'; import 'package:analysis_server/src/nullability/transitional_api.dart'; import 'package:analysis_server/src/nullability/unit_propagation.dart'; import 'package:analyzer/dart/ast/ast.dart'; @@ -63,13 +64,13 @@ /// boolean value could possibly affect nullability analysis. _ConditionInfo _conditionInfo; - /// The set of constraint variables that would have to be assigned the value - /// of `true` for the code currently being visited to be reachable. + /// The set of nullability nodes that would have to be `nullable` for the code + /// currently being visited to be reachable. /// /// Guard variables are attached to the left hand side of any generated /// constraints, so that constraints do not take effect if they come from /// code that can be proven unreachable by the migration tool. - final _guards = <ConstraintVariable>[]; + final _guards = <NullabilityNode>[]; /// Indicates whether the statement or expression being visited is within /// conditional control flow. If `true`, this means that the enclosing @@ -79,11 +80,14 @@ ConstraintGatherer(TypeProvider typeProvider, this._variables, this._constraints, this._source, this._permissive, this.assumptions) - : _notNullType = DecoratedType(typeProvider.objectType, null), - _nonNullableBoolType = DecoratedType(typeProvider.boolType, null), - _nonNullableTypeType = DecoratedType(typeProvider.typeType, null), + : _notNullType = + DecoratedType(typeProvider.objectType, NullabilityNode.never), + _nonNullableBoolType = + DecoratedType(typeProvider.boolType, NullabilityNode.never), + _nonNullableTypeType = + DecoratedType(typeProvider.typeType, NullabilityNode.never), _nullType = - DecoratedType(typeProvider.nullType, ConstraintVariable.always); + DecoratedType(typeProvider.nullType, NullabilityNode.always); /// Gets the decorated type of [element] from [_variables], performing any /// necessary substitutions. @@ -132,7 +136,8 @@ if (identical(_conditionInfo?.condition, node.condition)) { if (!_inConditionalControlFlow && _conditionInfo.trueDemonstratesNonNullIntent != null) { - _recordFact(_conditionInfo.trueDemonstratesNonNullIntent); + _conditionInfo.trueDemonstratesNonNullIntent + ?.recordNonNullIntent(_constraints, _guards); } } node.message?.accept(this); @@ -154,8 +159,8 @@ bool isPure = node.leftOperand is SimpleIdentifier; var conditionInfo = _ConditionInfo(node, isPure: isPure, - trueGuard: leftType.nullable, - falseDemonstratesNonNullIntent: leftType.nonNullIntent); + trueGuard: leftType.node, + falseDemonstratesNonNullIntent: leftType.node); _conditionInfo = node.operator.type == TokenType.EQ_EQ ? conditionInfo : conditionInfo.not(node); @@ -182,7 +187,7 @@ @override DecoratedType visitBooleanLiteral(BooleanLiteral node) { - return DecoratedType(node.staticType, null); + return DecoratedType(node.staticType, NullabilityNode.never); } @override @@ -199,8 +204,10 @@ assert(_isSimple(thenType)); // TODO(paulberry) var elseType = node.elseExpression.accept(this); assert(_isSimple(elseType)); // TODO(paulberry) - var overallType = DecoratedType(node.staticType, - _joinNullabilities(node, thenType.nullable, elseType.nullable)); + var overallType = DecoratedType( + node.staticType, + NullabilityNode.forConditionalexpression( + node, thenType.node, elseType.node, _joinNullabilities)); _variables.recordDecoratedExpressionType(node, overallType); return overallType; } @@ -215,7 +222,13 @@ } else if (node.declaredElement.isOptionalPositional || assumptions.namedNoDefaultParameterHeuristic == NamedNoDefaultParameterHeuristic.assumeNullable) { - _recordFact(getOrComputeElementType(node.declaredElement).nullable); + NullabilityNode.recordAssignment( + NullabilityNode.always, + getOrComputeElementType(node.declaredElement).node, + null, + _guards, + _constraints, + false); } else { assert(assumptions.namedNoDefaultParameterHeuristic == NamedNoDefaultParameterHeuristic.assumeRequired); @@ -255,16 +268,13 @@ // treated like an implicit `assert(b != null)`? Probably. _handleAssignment(_notNullType, node.condition); _inConditionalControlFlow = true; - ConstraintVariable trueGuard; - ConstraintVariable falseGuard; + NullabilityNode trueGuard; + NullabilityNode falseGuard; if (identical(_conditionInfo?.condition, node.condition)) { trueGuard = _conditionInfo.trueGuard; falseGuard = _conditionInfo.falseGuard; - _variables.recordConditionalDiscard( - _source, - node, - ConditionalDiscard(trueGuard ?? ConstraintVariable.always, - falseGuard ?? ConstraintVariable.always, _conditionInfo.isPure)); + _variables.recordConditionalDiscard(_source, node, + ConditionalDiscard(trueGuard, falseGuard, _conditionInfo.isPure)); } if (trueGuard != null) { _guards.add(trueGuard); @@ -291,7 +301,7 @@ @override DecoratedType visitIntegerLiteral(IntegerLiteral node) { - return DecoratedType(node.staticType, null); + return DecoratedType(node.staticType, NullabilityNode.never); } @override @@ -337,10 +347,9 @@ } } // Any parameters not supplied must be optional. - for (var entry in calleeType.namedParameterOptionalVariables.entries) { - assert(entry.value != null); + for (var entry in calleeType.namedParameters.entries) { if (suppliedNamedParameters.contains(entry.key)) continue; - _recordFact(entry.value); + entry.value.node.recordNamedParameterNotSupplied(_constraints, _guards); } return calleeType.returnType; } @@ -393,24 +402,24 @@ @override DecoratedType visitStringLiteral(StringLiteral node) { - return DecoratedType(node.staticType, null); + return DecoratedType(node.staticType, NullabilityNode.never); } @override DecoratedType visitThisExpression(ThisExpression node) { - return DecoratedType(node.staticType, null); + return DecoratedType(node.staticType, NullabilityNode.never); } @override DecoratedType visitThrowExpression(ThrowExpression node) { node.expression.accept(this); // TODO(paulberry): do we need to check the expression type? I think not. - return DecoratedType(node.staticType, null); + return DecoratedType(node.staticType, NullabilityNode.never); } @override DecoratedType visitTypeName(TypeName typeName) { - return DecoratedType(typeName.type, null); + return DecoratedType(typeName.type, NullabilityNode.never); } /// Creates the necessary constraint(s) for an assignment from [sourceType] to @@ -419,40 +428,14 @@ /// where a nullable source is assigned to a non-nullable destination. void _checkAssignment(DecoratedType destinationType, DecoratedType sourceType, Expression expression) { - if (sourceType.nullable != null) { - _guards.add(sourceType.nullable); - var destinationNonNullIntent = destinationType.nonNullIntent; - try { - CheckExpression checkNotNull; - if (expression != null) { - checkNotNull = CheckExpression(expression); - _variables.recordExpressionChecks( - _source, expression, ExpressionChecks(checkNotNull)); - } - // nullable_src => nullable_dst | check_expr - _recordFact(ConstraintVariable.or( - _constraints, destinationType.nullable, checkNotNull)); - if (checkNotNull != null) { - // nullable_src & nonNullIntent_dst => check_expr - if (destinationNonNullIntent != null) { - _recordConstraint(destinationNonNullIntent, checkNotNull); - } - } - } finally { - _guards.removeLast(); - } - var sourceNonNullIntent = sourceType.nonNullIntent; - if (!_inConditionalControlFlow && sourceNonNullIntent != null) { - if (destinationType.nullable == null) { - // The destination type can never be nullable so this demonstrates - // non-null intent. - _recordFact(sourceNonNullIntent); - } else if (destinationNonNullIntent != null) { - // Propagate non-null intent from the destination to the source. - _recordConstraint(destinationNonNullIntent, sourceNonNullIntent); - } - } + CheckExpression checkNotNull; + if (expression != null) { + checkNotNull = CheckExpression(expression); + _variables.recordExpressionChecks( + _source, expression, ExpressionChecks(checkNotNull)); } + NullabilityNode.recordAssignment(sourceType.node, destinationType.node, + checkNotNull, _guards, _constraints, _inConditionalControlFlow); // TODO(paulberry): it's a cheat to pass in expression=null for the // recursive checks. Really we want to unify all the checks in a single // ExpressionChecks object. @@ -524,31 +507,11 @@ return ConstraintVariable.always; } var result = TypeIsNullable(node.offset); - _recordConstraint(a, result); - _recordConstraint(b, result); - _recordConstraint(result, ConstraintVariable.or(_constraints, a, b)); + _constraints.record([a], result); + _constraints.record([b], result); + _constraints.record([result], ConstraintVariable.or(_constraints, a, b)); return result; } - - /// Records a constraint having [condition] as its left hand side and - /// [consequence] as its right hand side. Any [_guards] are included in the - /// left hand side. - void _recordConstraint( - ConstraintVariable condition, ConstraintVariable consequence) { - _guards.add(condition); - try { - _recordFact(consequence); - } finally { - _guards.removeLast(); - } - } - - /// Records a constraint having [consequence] as its right hand side. Any - /// [_guards] are used as the right hand side. - void _recordFact(ConstraintVariable consequence) { - assert(consequence != null); - _constraints.record(_guards, consequence); - } } /// Information about a binary expression whose boolean value could possibly @@ -564,21 +527,21 @@ /// effect other than returning a boolean value. final bool isPure; - /// If not `null`, the [ConstraintVariable] whose value must be `true` in + /// If not `null`, the [NullabilityNode] that would need to be nullable in /// order for [condition] to evaluate to `true`. - final ConstraintVariable trueGuard; + final NullabilityNode trueGuard; - /// If not `null`, the [ConstraintVariable] whose value must be `true` in + /// If not `null`, the [NullabilityNode] that would need to be nullable in /// order for [condition] to evaluate to `false`. - final ConstraintVariable falseGuard; + final NullabilityNode falseGuard; - /// If not `null`, the [ConstraintVariable] whose value should be set to - /// `true` if [condition] is asserted to be `true`. - final ConstraintVariable trueDemonstratesNonNullIntent; + /// If not `null`, the [NullabilityNode] that should be asserted to have + // /// non-null intent if [condition] is asserted to be `true`. + final NullabilityNode trueDemonstratesNonNullIntent; - /// If not `null`, the [ConstraintVariable] whose value should be set to - /// `true` if [condition] is asserted to be `false`. - final ConstraintVariable falseDemonstratesNonNullIntent; + /// If not `null`, the [NullabilityNode] that should be asserted to have + /// non-null intent if [condition] is asserted to be `false`. + final NullabilityNode falseDemonstratesNonNullIntent; _ConditionInfo(this.condition, {@required this.isPure,
diff --git a/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart b/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart index f917e72..8f5f170 100644 --- a/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart +++ b/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart
@@ -5,6 +5,7 @@ import 'package:analysis_server/src/nullability/conditional_discard.dart'; import 'package:analysis_server/src/nullability/decorated_type.dart'; import 'package:analysis_server/src/nullability/expression_checks.dart'; +import 'package:analysis_server/src/nullability/nullability_node.dart'; import 'package:analysis_server/src/nullability/transitional_api.dart'; import 'package:analysis_server/src/nullability/unit_propagation.dart'; import 'package:analyzer/dart/ast/ast.dart'; @@ -50,28 +51,19 @@ // TODO(danrubel): Return something other than this // to indicate that we should insert a type for the declaration // that is missing a type reference. - ? new DecoratedType(DynamicTypeImpl.instance, ConstraintVariable.always) + ? new DecoratedType( + DynamicTypeImpl.instance, NullabilityNode.forInferredDynamicType()) : type.accept(this); } @override DecoratedType visitDefaultFormalParameter(DefaultFormalParameter node) { var decoratedType = node.parameter.accept(this); - ConstraintVariable optional; - if (node.declaredElement.hasRequired) { - optional = null; - } else if (node.defaultValue != null) { - optional = ConstraintVariable.always; - } else { - optional = decoratedType.nullable; - _variables.recordPossiblyOptional(_source, node, optional); + if (node.declaredElement.hasRequired || node.defaultValue != null) { + return null; } - if (optional != null) { - _currentFunctionType - .namedParameterOptionalVariables[node.declaredElement.name] = - optional; - } - return null; + decoratedType.node.trackPossiblyOptional(); + _variables.recordPossiblyOptional(_source, node, decoratedType.node); } @override @@ -117,8 +109,7 @@ DecoratedType visitSimpleFormalParameter(SimpleFormalParameter node) { var type = decorateType(node.type); var declaredElement = node.declaredElement; - assert(type.nonNullIntent == null); - type.nonNullIntent = NonNullIntent(node.offset); + type.node.trackNonNullIntent(node.offset); _variables.recordDecoratedElementType(declaredElement, type); if (declaredElement.isNamed) { _currentFunctionType.namedParameters[declaredElement.name] = type; @@ -133,7 +124,10 @@ assert(node != null); // TODO(paulberry) assert(node is NamedType); // TODO(paulberry) var type = node.type; - if (type.isVoid) return DecoratedType(type, ConstraintVariable.always); + if (type.isVoid) { + return DecoratedType( + type, NullabilityNode.forTypeAnnotation(node.end, always: true)); + } assert( type is InterfaceType || type is TypeParameterType); // TODO(paulberry) var typeArguments = const <DecoratedType>[]; @@ -146,10 +140,11 @@ assert(false); // TODO(paulberry): is this possible? } } - var nullable = node.question == null - ? TypeIsNullable(node.end) - : ConstraintVariable.always; - var decoratedType = DecoratedTypeAnnotation(type, nullable, node.end, + var decoratedType = DecoratedTypeAnnotation( + type, + NullabilityNode.forTypeAnnotation(node.end, + always: node.question != null), + node.end, typeArguments: typeArguments); _variables.recordDecoratedTypeAnnotation(_source, node, decoratedType); return decoratedType; @@ -165,11 +160,11 @@ var previousFunctionType = _currentFunctionType; // TODO(paulberry): test that it's correct to use `null` for the nullability // of the function type - var functionType = DecoratedType(declaredElement.type, null, + var functionType = DecoratedType( + declaredElement.type, NullabilityNode.never, returnType: decoratedReturnType, positionalParameters: [], - namedParameters: {}, - namedParameterOptionalVariables: {}); + namedParameters: {}); _currentFunctionType = functionType; try { parameters.accept(this); @@ -194,11 +189,11 @@ void recordDecoratedTypeAnnotation( Source source, TypeAnnotation node, DecoratedTypeAnnotation type); - /// Associates a constraint variable with the question of whether the given - /// named parameter should be optional (should not have a `required` + /// Records that [node] is associated with the question of whether the named + /// [parameter] should be optional (should not have a `required` /// annotation added to it). - void recordPossiblyOptional(Source source, DefaultFormalParameter parameter, - ConstraintVariable variable); + void recordPossiblyOptional( + Source source, DefaultFormalParameter parameter, NullabilityNode node); } /// Repository of constraint variables and decorated types corresponding to the
diff --git a/pkg/analysis_server/lib/src/nullability/decorated_type.dart b/pkg/analysis_server/lib/src/nullability/decorated_type.dart index 2dde11f..41fef69 100644 --- a/pkg/analysis_server/lib/src/nullability/decorated_type.dart +++ b/pkg/analysis_server/lib/src/nullability/decorated_type.dart
@@ -2,6 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:analysis_server/src/nullability/nullability_node.dart'; import 'package:analysis_server/src/nullability/transitional_api.dart'; import 'package:analysis_server/src/nullability/unit_propagation.dart'; import 'package:analyzer/dart/element/element.dart'; @@ -15,18 +16,7 @@ class DecoratedType { final DartType type; - /// [ConstraintVariable] whose value will be set to `true` if this type needs - /// to be nullable. - /// - /// If `null`, that means that an external constraint (outside the code being - /// migrated) forces this type to be non-nullable. - final ConstraintVariable nullable; - - /// [ConstraintVariable] whose value will be set to `true` if the usage of - /// this type suggests that it is intended to be non-null (because of the - /// presence of a statement or expression that would unconditionally lead to - /// an exception being thrown in the case of a `null` value at runtime). - ConstraintVariable nonNullIntent; + final NullabilityNode node; /// If `this` is a function type, the [DecoratedType] of its return type. final DecoratedType returnType; @@ -40,31 +30,21 @@ /// parameters. final Map<String, DecoratedType> namedParameters; - /// If `this` is a function type, [ConstraintVariable] for each of its named - /// parameters indicating whether the given named parameter needs to be - /// optional (no `required` annotation). - /// - /// If there is no entry in this map corresponding to a given named parameter, - /// that means that it has already been decided (prior to migration) that the - /// given named parameter is required. TODO(paulberry): test that this works - /// for already-migrated code. - final Map<String, ConstraintVariable> namedParameterOptionalVariables; - /// If `this` is a parameterized type, the [DecoratedType] of each of its /// type parameters. /// /// TODO(paulberry): how should we handle generic typedefs? final List<DecoratedType> typeArguments; - DecoratedType(this.type, this.nullable, + DecoratedType(this.type, this.node, {this.returnType, this.positionalParameters = const [], this.namedParameters = const {}, - this.namedParameterOptionalVariables = const {}, this.typeArguments = const []}) { + assert(node != null); // The type system doesn't have a non-nullable version of `dynamic`. So if // the type is `dynamic`, verify that `nullable` is `always`. - assert(!type.isDynamic || identical(nullable, ConstraintVariable.always)); + assert(!type.isDynamic || node.isAlwaysNullable); } /// Creates a [DecoratedType] corresponding to the given [element], which is @@ -74,7 +54,7 @@ assert((type as TypeImpl).nullability == Nullability.indeterminate); // TODO(paulberry) if (type is FunctionType) { - var decoratedType = DecoratedType(type, null, + var decoratedType = DecoratedType(type, NullabilityNode.never, returnType: decorate(type.returnType), positionalParameters: []); for (var parameter in type.parameters) { assert(parameter.isPositional); // TODO(paulberry) @@ -83,7 +63,7 @@ return decoratedType; } else if (type is InterfaceType) { assert(type.typeParameters.isEmpty); // TODO(paulberry) - return DecoratedType(type, null); + return DecoratedType(type, NullabilityNode.never); } else { throw type.runtimeType; // TODO(paulberry) } @@ -112,7 +92,7 @@ @override String toString() { - var trailing = nullable == null ? '' : '?($nullable)'; + var trailing = node.debugSuffix; var type = this.type; if (type is TypeParameterType || type is VoidType) { return '$type$trailing'; @@ -155,14 +135,14 @@ newPositionalParameters.add(positionalParameters[i] ._substitute(constraints, substitution, undecoratedParameterType)); } - return DecoratedType(undecoratedResult, nullable, + return DecoratedType(undecoratedResult, node, returnType: returnType._substitute( constraints, substitution, undecoratedResult.returnType), positionalParameters: newPositionalParameters); } else if (type is TypeParameterType) { var inner = substitution[type.element]; return DecoratedType(undecoratedResult, - ConstraintVariable.or(constraints, inner?.nullable, nullable)); + NullabilityNode.forSubstitution(constraints, inner?.node, node)); } else if (type is VoidType) { return this; } @@ -180,13 +160,12 @@ final int _offset; DecoratedTypeAnnotation( - DartType type, ConstraintVariable nullable, this._offset, + DartType type, NullabilityNode nullabilityNode, this._offset, {List<DecoratedType> typeArguments = const []}) - : super(type, nullable, typeArguments: typeArguments); + : super(type, nullabilityNode, typeArguments: typeArguments); @override - bool get isEmpty => - identical(nullable, ConstraintVariable.always) || !nullable.value; + bool get isEmpty => node.isAlwaysNullable || !node.isNullable; @override Iterable<SourceEdit> get modifications =>
diff --git a/pkg/analysis_server/lib/src/nullability/nullability_node.dart b/pkg/analysis_server/lib/src/nullability/nullability_node.dart new file mode 100644 index 0000000..fd7d82b --- /dev/null +++ b/pkg/analysis_server/lib/src/nullability/nullability_node.dart
@@ -0,0 +1,201 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analysis_server/src/nullability/decorated_type.dart'; +import 'package:analysis_server/src/nullability/transitional_api.dart'; +import 'package:analysis_server/src/nullability/unit_propagation.dart'; +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:meta/meta.dart'; + +/// Representation of a single node in the nullability inference graph. +/// +/// Initially, this is just a wrapper over constraint variables, and the +/// nullability inference graph is encoded into the wrapped constraint +/// variables. Over time this will be replaced by a first class representation +/// of the nullability inference graph. +class NullabilityNode { + /// [NullabilityNode] used for types that are known a priori to be nullable + /// (e.g. the type of the `null` literal). + static final always = NullabilityNode._(ConstraintVariable.always); + + /// [NullabilityNode] used for types that are known a priori to be + /// non-nullable (e.g. the type of an integer literal). + static final never = NullabilityNode._(null); + + /// [ConstraintVariable] whose value will be set to `true` if this type needs + /// to be nullable. + /// + /// If `null`, that means that an external constraint (outside the code being + /// migrated) forces this type to be non-nullable. + final ConstraintVariable nullable; + + ConstraintVariable _nonNullIntent; + + bool _isPossiblyOptional = false; + + /// Creates a [NullabilityNode] representing the nullability of a conditional + /// expression which is nullable iff both [a] and [b] are nullable. + /// + /// The constraint variable contained in the new node is created using the + /// [joinNullabilities] callback. TODO(paulberry): this should become + /// unnecessary once constraint solving is performed directly using + /// [NullabilityNode] objects. + NullabilityNode.forConditionalexpression( + ConditionalExpression conditionalExpression, + NullabilityNode a, + NullabilityNode b, + ConstraintVariable Function( + ConditionalExpression, ConstraintVariable, ConstraintVariable) + joinNullabilities) + : this._( + joinNullabilities(conditionalExpression, a.nullable, b.nullable)); + + /// Creates a [NullabilityNode] representing the nullability of a variable + /// whose type is `dynamic` due to type inference. + /// + /// TODO(paulberry): this should go away; we should decorate the actual + /// inferred type rather than assuming `dynamic`. + NullabilityNode.forInferredDynamicType() : this._(ConstraintVariable.always); + + /// Creates a [NullabilityNode] representing the nullability of a type + /// substitution where [outerNode] is the nullability node for the type + /// variable being eliminated by the substitution, and [innerNode] is the + /// nullability node for the type being substituted in its place. + /// + /// [innerNode] may be `null`. TODO(paulberry): when? + /// + /// Additional constraints are recorded in [constraints] as necessary to make + /// the new nullability node behave consistently with the old nodes. + /// TODO(paulberry): this should become unnecessary once constraint solving is + /// performed directly using [NullabilityNode] objects. + NullabilityNode.forSubstitution(Constraints constraints, + NullabilityNode innerNode, NullabilityNode outerNode) + : this._(ConstraintVariable.or( + constraints, innerNode?.nullable, outerNode.nullable)); + + /// Creates a [NullabilityNode] representing the nullability of a type + /// annotation appearing explicitly in the user's program. + NullabilityNode.forTypeAnnotation(int endOffset, {@required bool always}) + : this._(always ? ConstraintVariable.always : TypeIsNullable(endOffset)); + + NullabilityNode._(this.nullable); + + /// Gets a string that can be appended to a type name during debugging to help + /// annotate the nullability of that type. + String get debugSuffix => nullable == null ? '' : '?($nullable)'; + + /// Indicates whether this node is always nullable, by construction. + bool get isAlwaysNullable => identical(nullable, ConstraintVariable.always); + + /// After constraint solving, this getter can be used to query whether the + /// type associated with this node should be considered nullable. + bool get isNullable => nullable.value; + + /// Indicates whether this node is associated with a named parameter for which + /// nullability migration needs to decide whether it is optional or required. + bool get isPossiblyOptional => _isPossiblyOptional; + + /// [ConstraintVariable] whose value will be set to `true` if the usage of + /// this type suggests that it is intended to be non-null (because of the + /// presence of a statement or expression that would unconditionally lead to + /// an exception being thrown in the case of a `null` value at runtime). + ConstraintVariable get nonNullIntent => _nonNullIntent; + + /// Records the fact that an invocation was made to a function with named + /// parameters, and the named parameter associated with this node was not + /// supplied. + void recordNamedParameterNotSupplied( + Constraints constraints, List<NullabilityNode> guards) { + if (isPossiblyOptional) { + _recordConstraints(constraints, guards, const [], nullable); + } + } + + void recordNonNullIntent( + Constraints constraints, List<NullabilityNode> guards) { + _recordConstraints(constraints, guards, const [], nonNullIntent); + } + + /// Tracks that the possibility that this nullability node might demonstrate + /// non-null intent, based on the fact that it corresponds to a formal + /// parameter declaration at location [offset]. + /// + /// TODO(paulberry): consider eliminating this method altogether, and simply + /// allowing all nullability nodes to track non-null intent if necessary. + void trackNonNullIntent(int offset) { + assert(_nonNullIntent == null); + _nonNullIntent = NonNullIntent(offset); + } + + /// Tracks the possibility that this node is associated with a named parameter + /// for which nullability migration needs to decide whether it is optional or + /// required. + void trackPossiblyOptional() { + _isPossiblyOptional = true; + } + + /// Connect the nullability nodes [sourceNode] and [destinationNode] + /// appopriately to account for an assignment in the source code being + /// analyzed. Any constraints generated are recorded in [constraints]. + /// + /// If [checkNotNull] is non-null, then it tracks the expression that may + /// require null-checking. + /// + /// [inConditionalControlFlow] indicates whether the assignment being analyzed + /// is reachable conditionally or unconditionally from the entry point of the + /// function; this affects how non-null intent is back-propagated. + static void recordAssignment( + NullabilityNode sourceNode, + NullabilityNode destinationNode, + CheckExpression checkNotNull, + List<NullabilityNode> guards, + Constraints constraints, + bool inConditionalControlFlow) { + var additionalConditions = <ConstraintVariable>[]; + if (sourceNode.nullable != null) { + additionalConditions.add(sourceNode.nullable); + var destinationNonNullIntent = destinationNode.nonNullIntent; + // nullable_src => nullable_dst | check_expr + _recordConstraints( + constraints, + guards, + additionalConditions, + ConstraintVariable.or( + constraints, destinationNode.nullable, checkNotNull)); + if (checkNotNull != null) { + // nullable_src & nonNullIntent_dst => check_expr + if (destinationNonNullIntent != null) { + additionalConditions.add(destinationNonNullIntent); + _recordConstraints( + constraints, guards, additionalConditions, checkNotNull); + } + } + additionalConditions.clear(); + var sourceNonNullIntent = sourceNode.nonNullIntent; + if (!inConditionalControlFlow && sourceNonNullIntent != null) { + if (destinationNode.nullable == null) { + // The destination type can never be nullable so this demonstrates + // non-null intent. + _recordConstraints( + constraints, guards, additionalConditions, sourceNonNullIntent); + } else if (destinationNonNullIntent != null) { + // Propagate non-null intent from the destination to the source. + additionalConditions.add(destinationNonNullIntent); + _recordConstraints( + constraints, guards, additionalConditions, sourceNonNullIntent); + } + } + } + } + + static void _recordConstraints( + Constraints constraints, + List<NullabilityNode> guards, + List<ConstraintVariable> additionalConditions, + ConstraintVariable consequence) { + var conditions = guards.map((node) => node.nullable).toList(); + conditions.addAll(additionalConditions); + constraints.record(conditions, consequence); + } +}
diff --git a/pkg/analysis_server/lib/src/nullability/provisional_api.dart b/pkg/analysis_server/lib/src/nullability/provisional_api.dart index 3fa023b..99080c9 100644 --- a/pkg/analysis_server/lib/src/nullability/provisional_api.dart +++ b/pkg/analysis_server/lib/src/nullability/provisional_api.dart
@@ -18,6 +18,10 @@ /// Kinds of fixes that might be performed by nullability migration. class NullabilityFixKind { + /// An import needs to be added. + static const addImport = + const NullabilityFixKind._(appliedMessage: 'Add an import'); + /// A formal parameter needs to have a required annotation added. static const addRequired = const NullabilityFixKind._(appliedMessage: 'Add a required annotation'); @@ -144,9 +148,11 @@ } else if (potentialModification is analyzer.DecoratedTypeAnnotation) { kind = NullabilityFixKind.makeTypeNullable; } else if (potentialModification is analyzer.ConditionalModification) { - kind = potentialModification.discard.keepFalse.value + kind = potentialModification.discard.keepFalse ? NullabilityFixKind.discardThen : NullabilityFixKind.discardElse; + } else if (potentialModification is analyzer.PotentiallyAddImport) { + kind = NullabilityFixKind.addImport; } else if (potentialModification is analyzer.PotentiallyAddRequired) { kind = NullabilityFixKind.addRequired; } else {
diff --git a/pkg/analysis_server/lib/src/nullability/transitional_api.dart b/pkg/analysis_server/lib/src/nullability/transitional_api.dart index ff2a53f..7a1b505 100644 --- a/pkg/analysis_server/lib/src/nullability/transitional_api.dart +++ b/pkg/analysis_server/lib/src/nullability/transitional_api.dart
@@ -7,6 +7,7 @@ import 'package:analysis_server/src/nullability/constraint_variable_gatherer.dart'; import 'package:analysis_server/src/nullability/decorated_type.dart'; import 'package:analysis_server/src/nullability/expression_checks.dart'; +import 'package:analysis_server/src/nullability/nullability_node.dart'; import 'package:analysis_server/src/nullability/unit_propagation.dart'; import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/element.dart'; @@ -60,7 +61,7 @@ this.discard, this.condition, this.thenStatement, this.elseStatement); @override - bool get isEmpty => discard.keepTrue.value && discard.keepFalse.value; + bool get isEmpty => discard.keepTrue && discard.keepFalse; @override Iterable<SourceEdit> get modifications { @@ -72,10 +73,10 @@ if (!discard.pureCondition) { keepNodes.add(condition); // TODO(paulberry): test } - if (discard.keepTrue.value) { + if (discard.keepTrue) { keepNodes.add(thenStatement); // TODO(paulberry): test } - if (discard.keepFalse.value) { + if (discard.keepFalse) { keepNodes.add(elseStatement); // TODO(paulberry): test } // TODO(paulberry): test thoroughly @@ -196,19 +197,54 @@ NamedNoDefaultParameterHeuristic.assumeNullable}); } +/// Records information about the possible addition of an import +/// to the source code. +class PotentiallyAddImport extends PotentialModification { + final _usages = <PotentialModification>[]; + + final int _offset; + final String _importPath; + + PotentiallyAddImport( + AstNode beforeNode, this._importPath, PotentialModification usage) + : _offset = beforeNode.offset { + _usages.add(usage); + } + + get importPath => _importPath; + + @override + bool get isEmpty { + for (PotentialModification usage in _usages) { + if (!usage.isEmpty) { + return false; + } + } + return true; + } + + // TODO(danrubel): change all of dartfix NNBD to use DartChangeBuilder + @override + Iterable<SourceEdit> get modifications => + isEmpty ? const [] : [SourceEdit(_offset, 0, "import '$_importPath';\n")]; + + void addUsage(PotentialModification usage) { + _usages.add(usage); + } +} + /// Records information about the possible addition of a `@required` annotation /// to the source code. class PotentiallyAddRequired extends PotentialModification { - final ConstraintVariable _optionalVariable; + final NullabilityNode _node; final int _offset; - PotentiallyAddRequired( - DefaultFormalParameter parameter, this._optionalVariable) + PotentiallyAddRequired(DefaultFormalParameter parameter, this._node) : _offset = parameter.offset; @override - bool get isEmpty => _optionalVariable.value; + bool get isEmpty => _node.isNullable; @override Iterable<SourceEdit> get modifications => @@ -264,10 +300,57 @@ } @override - void recordPossiblyOptional(Source source, DefaultFormalParameter parameter, - ConstraintVariable variable) { + void recordPossiblyOptional( + Source source, DefaultFormalParameter parameter, NullabilityNode node) { + var modification = PotentiallyAddRequired(parameter, node); + _addPotentialModification(source, modification); + _addPotentialImport( + source, parameter, modification, 'package:meta/meta.dart'); + } + + void _addPotentialImport(Source source, AstNode node, + PotentialModification usage, String importPath) { + // Get the compilation unit - assume not null + while (node is! CompilationUnit) { + node = node.parent; + } + var unit = node as CompilationUnit; + + // Find an existing import + for (var directive in unit.directives) { + if (directive is ImportDirective) { + if (directive.uri.stringValue == importPath) { + return; + } + } + } + + // Add the usage to an existing modification if possible + for (var modification in (_potentialModifications[source] ??= [])) { + if (modification is PotentiallyAddImport) { + if (modification.importPath == importPath) { + modification.addUsage(usage); + return; + } + } + } + + // Create a new import modification + AstNode beforeNode; + for (var directive in unit.directives) { + if (directive is ImportDirective || directive is ExportDirective) { + beforeNode = directive; + break; + } + } + if (beforeNode == null) { + for (var declaration in unit.declarations) { + beforeNode = declaration; + break; + } + } _addPotentialModification( - source, PotentiallyAddRequired(parameter, variable)); + source, PotentiallyAddImport(beforeNode, importPath, usage)); } void _addPotentialModification(
diff --git a/pkg/analysis_server/lib/src/nullability/unit_propagation.dart b/pkg/analysis_server/lib/src/nullability/unit_propagation.dart index 1add712..b587e33 100644 --- a/pkg/analysis_server/lib/src/nullability/unit_propagation.dart +++ b/pkg/analysis_server/lib/src/nullability/unit_propagation.dart
@@ -66,7 +66,7 @@ /// The value assigned to this constraint variable by the solution currently /// being computed. - get value => _value; + bool get value => _value; @override String toString() =>
diff --git a/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart b/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart index 7da4335..693b94e 100644 --- a/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart +++ b/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart
@@ -6,6 +6,8 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/syntactic_entity.dart'; import 'package:analyzer/dart/ast/token.dart'; +import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/type.dart'; /// An object used to build the details for each token in the code being /// analyzed. @@ -21,15 +23,29 @@ void visitNode(AstNode node) { for (SyntacticEntity entity in node.childEntities) { if (entity is Token) { - _createDetails(entity, null); + _createDetails(entity, null, null); } else if (entity is SimpleIdentifier) { + String type = _getType(entity); + if (_isTypeName(entity)) { + type = 'dart:core;Type<$type>'; + } List<String> kinds = []; if (entity.inDeclarationContext()) { kinds.add('declaration'); } else { - kinds.add('identifier'); + kinds.add('reference'); } - _createDetails(entity.token, kinds); + _createDetails(entity.token, type, kinds); + } else if (entity is BooleanLiteral) { + _createDetails(entity.literal, _getType(entity), null); + } else if (entity is DoubleLiteral) { + _createDetails(entity.literal, _getType(entity), null); + } else if (entity is IntegerLiteral) { + _createDetails(entity.literal, _getType(entity), null); + } else if (entity is SimpleStringLiteral) { + _createDetails(entity.literal, _getType(entity), null); + } else if (entity is Comment) { + // Ignore comments and the references within them. } else if (entity is AstNode) { visitNode(entity); } @@ -37,8 +53,68 @@ } /// Create the details for a single [token], using the given list of [kinds]. - void _createDetails(Token token, List<String> kinds) { - details.add(new TokenDetails(token.lexeme, token.type.name, - validElementKinds: kinds)); + void _createDetails(Token token, String type, List<String> kinds) { + details.add( + new TokenDetails(token.lexeme, type: type, validElementKinds: kinds)); + } + + /// Return a unique identifier for the type of the given [expression]. + String _getType(Expression expression) { + StringBuffer buffer = new StringBuffer(); + _writeType(buffer, expression.staticType); + return buffer.toString(); + } + + /// Return `true` if the [identifier] represents the name of a type. + bool _isTypeName(SimpleIdentifier identifier) { + AstNode parent = identifier.parent; + if (parent is TypeName && identifier == parent.name) { + return true; + } else if (parent is PrefixedIdentifier && + parent.identifier == identifier) { + AstNode parent2 = parent.parent; + if (parent2 is TypeName && parent == parent2.name) { + return true; + } + } + return false; + } + + /// Return a unique identifier for the type of the given [expression]. + void _writeType(StringBuffer buffer, DartType type) { + if (type == null) { + // This should never happen if the AST has been resolved. + buffer.write('dynamic'); + } else if (type is FunctionType) { + _writeType(buffer, type.returnType); + buffer.write(' Function('); + bool first = true; + for (var parameter in type.parameters) { + if (first) { + first = false; + } else { + buffer.write(', '); + } + _writeType(buffer, parameter.type); + } + buffer.write(')'); + } else if (type is InterfaceType) { + Element element = type.element; + if (element == null || element.isSynthetic) { + buffer.write(type.displayName); + } else { + String uri = element.library.source.uri.toString(); + String name = element.name; + if (element is ClassMemberElement) { + String className = element.enclosingElement.name; + buffer.write('$uri;$className;$name'); + } else { + buffer.write('$uri;$name'); + } + } + } else { + // Handle `void` and `dynamic`. + buffer.write(type.displayName); + } } }
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart index bb459c1..5f64118 100644 --- a/pkg/analysis_server/lib/src/services/correction/assist.dart +++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -88,8 +88,16 @@ 'dart.assist.convert.toConstructorFieldParameter', 30, "Convert to field formal parameter"); + static const CONVERT_TO_FOR_ELEMENT = const AssistKind( + 'dart.assist.convertToForElement', 30, "Convert to a 'for' element", + associatedErrorCodes: <String>[ + 'prefer_for_elements_to_map_fromIterable' + ]); static const CONVERT_TO_IF_ELEMENT = const AssistKind( - 'dart.assist.convertToIfElement', 30, "Convert to an 'if' element"); + 'dart.assist.convertToIfElement', 30, "Convert to an 'if' element", + associatedErrorCodes: <String>[ + 'prefer_if_elements_to_conditional_expressions' + ]); static const CONVERT_TO_INT_LITERAL = const AssistKind( 'dart.assist.convert.toIntLiteral', 30, "Convert to an int literal", associatedErrorCodes: <String>['prefer_int_literals']); @@ -122,7 +130,8 @@ "Convert to single quoted string", associatedErrorCodes: <String>['prefer_single_quotes']); static const CONVERT_TO_SPREAD = const AssistKind( - 'dart.assist.convertToSpread', 30, "Convert to a spread"); + 'dart.assist.convertToSpread', 30, "Convert to a spread", + associatedErrorCodes: <String>['spread_collections']); static const ENCAPSULATE_FIELD = const AssistKind('dart.assist.encapsulateField', 30, "Encapsulate field"); static const EXCHANGE_OPERANDS =
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart index b373465..64d8880 100644 --- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart +++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -150,7 +150,7 @@ if (experimentStatus.control_flow_collections) { await _addProposal_convertConditionalExpressionToIfElement(); - await _addProposal_convertMapFromIterableToIfLiteral(); + await _addProposal_convertMapFromIterableToForLiteral(); } if (experimentStatus.spread_collections) { await _addProposal_convertAddAllToSpread(); @@ -169,6 +169,18 @@ await _addProposal_convertClassToMixin(); } else if (assistKind == DartAssistKind.CONVERT_TO_INT_LITERAL) { await _addProposal_convertToIntLiteral(); + } else if (assistKind == DartAssistKind.CONVERT_TO_SPREAD) { + if (experimentStatus.spread_collections) { + await _addProposal_convertAddAllToSpread(); + } + } else if (assistKind == DartAssistKind.CONVERT_TO_FOR_ELEMENT) { + if (experimentStatus.control_flow_collections) { + await _addProposal_convertMapFromIterableToForLiteral(); + } + } else if (assistKind == DartAssistKind.CONVERT_TO_IF_ELEMENT) { + if (experimentStatus.control_flow_collections) { + await _addProposal_convertConditionalExpressionToIfElement(); + } } return assists; } @@ -484,7 +496,13 @@ elementText ??= '...${utils.getNodeText(argument)}'; DartChangeBuilder changeBuilder = _newDartChangeBuilder(); await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { - builder.addSimpleInsertion(list.elements.last.end, ', $elementText'); + // ['a']..addAll(['b', 'c']); + if (list.elements.isNotEmpty) { + builder.addSimpleInsertion(list.elements.last.end, ', $elementText'); + } else { + // + builder.addSimpleInsertion(list.leftBracket.end, elementText); + } // []..addAll(['b', 'c']); builder.addDeletion(range.node(invocation)); }); _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_SPREAD); @@ -547,8 +565,8 @@ } Future<void> _addProposal_convertConditionalExpressionToIfElement() async { - AstNode node = this.node; - if (node is! ConditionalExpression) { + AstNode node = this.node.thisOrAncestorOfType<ConditionalExpression>(); + if (node == null) { _coverageMarker(); return; } @@ -923,7 +941,7 @@ _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_MAP_LITERAL); } - Future<void> _addProposal_convertMapFromIterableToIfLiteral() async { + Future<void> _addProposal_convertMapFromIterableToForLiteral() async { // // Ensure that the selection is inside an invocation of Map.fromIterable. // @@ -1077,7 +1095,7 @@ builder.write(' }'); }); }); - _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_IF_ELEMENT); + _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_FOR_ELEMENT); } Future<void> _addProposal_convertPartOfToUri() async {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart index b800b5d..3c54bcb 100644 --- a/pkg/analysis_server/lib/src/services/correction/fix.dart +++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -11,9 +11,7 @@ import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart'; import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; -/** - * Return true if this [errorCode] is likely to have a fix associated with it. - */ +/// Return true if this [errorCode] is likely to have a fix associated with it. bool hasFix(ErrorCode errorCode) => errorCode == StaticWarningCode.UNDEFINED_CLASS_BOOLEAN || errorCode == StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER || @@ -103,9 +101,14 @@ errorCode.name == LintNames.unnecessary_this || errorCode.name == LintNames.use_rethrow_when_possible)); -/** - * The implementation of [DartFixContext]. - */ +/// An enumeration of quick fix kinds for the errors found in an analysis +/// options file. +class AnalysisOptionsFixKind { + static const REMOVE_SETTING = + const FixKind('REMOVE_SETTING', 50, "Remove '{0}'"); +} + +/// The implementation of [DartFixContext]. class DartFixContextImpl implements DartFixContext { @override final ChangeWorkspace workspace; @@ -119,9 +122,7 @@ DartFixContextImpl(this.workspace, this.resolveResult, this.error); } -/** - * An enumeration of possible quick fix kinds. - */ +/// An enumeration of quick fix kinds found in a Dart file. class DartFixKind { static const ADD_ASYNC = const FixKind('ADD_ASYNC', 50, "Add 'async' modifier"); @@ -304,6 +305,10 @@ 'REPLACE_WITH_CONDITIONAL_ASSIGNMENT', 50, "Replace with ??="); static const REPLACE_WITH_IDENTIFIER = const FixKind('REPLACE_WITH_IDENTIFIER', 50, "Replace with identifier"); + static const REPLACE_WITH_IS_EMPTY = + const FixKind('REPLACE_WITH_IS_EMPTY', 50, "Replace with 'isEmpty'"); + static const REPLACE_WITH_IS_NOT_EMPTY = const FixKind( + 'REPLACE_WITH_IS_NOT_EMPTY', 50, "Replace with 'isNotEmpty'"); static const REPLACE_WITH_NULL_AWARE = const FixKind( 'REPLACE_WITH_NULL_AWARE', 50,
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart b/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart new file mode 100644 index 0000000..f558372 --- /dev/null +++ b/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
@@ -0,0 +1,238 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:math' as math; + +import 'package:analysis_server/plugin/edit/fix/fix_core.dart'; +import 'package:analysis_server/src/services/correction/fix.dart'; +import 'package:analysis_server/src/services/correction/strings.dart'; +import 'package:analyzer/error/error.dart'; +import 'package:analyzer/source/line_info.dart'; +import 'package:analyzer/source/source_range.dart'; +import 'package:analyzer/src/analysis_options/error/option_codes.dart'; +import 'package:analyzer/src/generated/java_core.dart'; +import 'package:analyzer/src/generated/source.dart'; +import 'package:analyzer_plugin/protocol/protocol_common.dart' + show SourceChange; +import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart'; +import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; +import 'package:meta/meta.dart'; +import 'package:source_span/src/span.dart'; +import 'package:yaml/yaml.dart'; + +/// The generator used to generate fixes in analysis options files. +class AnalysisOptionsFixGenerator { + final AnalysisError error; + + final int errorOffset; + + final int errorLength; + + final String content; + + final YamlMap options; + + final LineInfo lineInfo; + + final List<Fix> fixes = <Fix>[]; + + List<YamlNode> coveringNodePath; + + AnalysisOptionsFixGenerator(this.error, this.content, this.options) + : errorOffset = error.offset, + errorLength = error.length, + lineInfo = new LineInfo.fromContent(content); + + /// Return the absolute, normalized path to the file in which the error was + /// reported. + String get file => error.source.fullName; + + /// Return the list of fixes that apply to the error being fixed. + Future<List<Fix>> computeFixes() async { + YamlNodeLocator locator = new YamlNodeLocator( + start: errorOffset, end: errorOffset + errorLength - 1); + coveringNodePath = locator.searchWithin(options); + if (coveringNodePath.isEmpty) { + return fixes; + } + + ErrorCode errorCode = error.errorCode; +// if (errorCode == AnalysisOptionsErrorCode.INCLUDED_FILE_PARSE_ERROR) { +// } else if (errorCode == AnalysisOptionsErrorCode.PARSE_ERROR) { +// } else if (errorCode == +// AnalysisOptionsHintCode.DEPRECATED_ANALYSIS_OPTIONS_FILE_NAME) { +// } else if (errorCode == +// AnalysisOptionsHintCode.PREVIEW_DART_2_SETTING_DEPRECATED) { +// } else if (errorCode == +// AnalysisOptionsHintCode.STRONG_MODE_SETTING_DEPRECATED) { +// } else + if (errorCode == AnalysisOptionsHintCode.SUPER_MIXINS_SETTING_DEPRECATED) { + await _addFix_removeSetting(); +// } else if (errorCode == +// AnalysisOptionsWarningCode.ANALYSIS_OPTION_DEPRECATED) { +// } else if (errorCode == AnalysisOptionsWarningCode.INCLUDED_FILE_WARNING) { +// } else if (errorCode == AnalysisOptionsWarningCode.INCLUDE_FILE_NOT_FOUND) { +// } else if (errorCode == AnalysisOptionsWarningCode.INVALID_OPTION) { +// } else if (errorCode == AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT) { +// } else if (errorCode == AnalysisOptionsWarningCode.SPEC_MODE_REMOVED) { +// } else if (errorCode == +// AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE) { + } else if (errorCode == + AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITHOUT_VALUES) { + await _addFix_removeSetting(); +// } else if (errorCode == +// AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE) { +// } else if (errorCode == +// AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES) { +// } else if (errorCode == AnalysisOptionsWarningCode.UNSUPPORTED_VALUE) { + } + return fixes; + } + + void _addFix_removeSetting() async { + if (coveringNodePath[0] is YamlScalar) { + SourceRange deletionRange; + int index = 1; + while (index < coveringNodePath.length) { + YamlNode parent = coveringNodePath[index]; + if (parent is YamlList) { + if (parent.nodes.length > 1) { + YamlNode nodeToDelete = coveringNodePath[index - 1]; + deletionRange = _lines( + nodeToDelete.span.start.offset, nodeToDelete.span.end.offset); + break; + } + } else if (parent is YamlMap) { + Map<dynamic, YamlNode> nodes = parent.nodes; + if (nodes.length > 1) { + YamlNode key; + YamlNode value; + YamlNode child = coveringNodePath[index - 1]; + if (nodes.containsKey(child)) { + key = child; + value = nodes[child]; + } else if (nodes.containsValue(child)) { + for (var entry in nodes.entries) { + if (child == entry.value) { + key = entry.key; + value = child; + break; + } + } + } + if (key == null || value == null) { + throw StateError( + 'Child is neither a key nor a value in the parent'); + } + deletionRange = _lines(key.span.start.offset, + _firstNonWhitespaceBefore(value.span.end.offset)); + break; + } + } else if (parent is YamlDocument) { + break; + } + index++; + } + YamlNode nodeToDelete = coveringNodePath[index - 1]; + deletionRange ??= + _lines(nodeToDelete.span.start.offset, nodeToDelete.span.end.offset); + ChangeBuilder builder = new ChangeBuilder(); + await builder.addFileEdit(file, (builder) { + builder.addDeletion(deletionRange); + }); + _addFixFromBuilder(builder, AnalysisOptionsFixKind.REMOVE_SETTING, + args: [coveringNodePath[0].toString()]); + } + } + + /// Add a fix whose edits were built by the [builder] that has the given + /// [kind]. If [args] are provided, they will be used to fill in the message + /// for the fix. + void _addFixFromBuilder(ChangeBuilder builder, FixKind kind, + {List args: null}) { + SourceChange change = builder.sourceChange; + if (change.edits.isEmpty) { + return; + } + change.message = formatList(kind.message, args); + fixes.add(new Fix(kind, change)); + } + + int _firstNonWhitespaceBefore(int offset) { + while (offset > 0 && isWhitespace(content.codeUnitAt(offset - 1))) { + offset--; + } + return offset; + } + + SourceRange _lines(int start, int end) { + CharacterLocation startLocation = lineInfo.getLocation(start); + int startOffset = lineInfo.getOffsetOfLine(startLocation.lineNumber - 1); + CharacterLocation endLocation = lineInfo.getLocation(end); + int endOffset = lineInfo.getOffsetOfLine( + math.min(endLocation.lineNumber, lineInfo.lineCount - 1)); + return new SourceRange(startOffset, endOffset - startOffset); + } +} + +/// An object used to locate the [YamlNode] associated with a source range. +/// More specifically, it will return the deepest [YamlNode] which completely +/// encompasses the specified range. +class YamlNodeLocator { + /// The inclusive start offset of the range used to identify the node. + int _startOffset = 0; + + /// The inclusive end offset of the range used to identify the node. + int _endOffset = 0; + + /// Initialize a newly created locator to locate the deepest [YamlNode] for + /// which `node.offset <= [start]` and `[end] < node.end`. + /// + /// If the [end] offset is not provided, then it is considered the same as the + /// [start] offset. + YamlNodeLocator({@required int start, int end}) + : this._startOffset = start, + this._endOffset = end ?? start; + + /// Search within the given Yaml [node] and return the path to the most deeply + /// nested node that includes the whole target range, or an empty list if no + /// node was found. The path is represented by all of the elements from the + /// starting [node] to the most deeply nested node, in reverse order. + List<YamlNode> searchWithin(YamlNode node) { + List<YamlNode> path = []; + _searchWithin(path, node); + return path; + } + + void _searchWithin(List<YamlNode> path, YamlNode node) { + SourceSpan span = node.span; + if (span.start.offset > _endOffset || span.end.offset < _startOffset) { + return; + } + if (node is YamlList) { + for (YamlNode element in node.nodes) { + _searchWithin(path, element); + if (path.isNotEmpty) { + path.add(node); + return; + } + } + } else if (node is YamlMap) { + Map<dynamic, YamlNode> nodeMap = node.nodes; + for (YamlNode key in nodeMap.keys) { + _searchWithin(path, key); + if (path.isNotEmpty) { + path.add(node); + return; + } + _searchWithin(path, nodeMap[key]); + if (path.isNotEmpty) { + path.add(node); + return; + } + } + } + path.add(node); + } +}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart index 05d16f0..e605378 100644 --- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart +++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -621,6 +621,9 @@ if (name == LintNames.prefer_final_locals) { await _addFix_makeVariableFinal(); } + if (name == LintNames.prefer_is_empty) { + await _addFix_replaceWithIsEmpty(); + } if (name == LintNames.prefer_is_not_empty) { await _addFix_isNotEmpty(); } @@ -1146,7 +1149,7 @@ sessionHelper, namedExpression.parent.parent, ); - return parameters.namedNames; + return parameters?.namedNames; } return null; } @@ -2373,7 +2376,8 @@ DartFixKind.IMPORT_ASYNC, Uri.parse('dart:async')); } - Future<void> _addFix_importLibrary(FixKind kind, Uri library) async { + Future<void> _addFix_importLibrary(FixKind kind, Uri library, + [String relativeURI = null]) async { // TODO(brianwilkerson) Determine whether this await is necessary. await null; String uriText; @@ -2382,6 +2386,16 @@ uriText = builder.importLibrary(library); }); _addFixFromBuilder(changeBuilder, kind, args: [uriText]); + + if (relativeURI != null && relativeURI.isNotEmpty) { + var changeBuilder2 = _newDartChangeBuilder(); + await changeBuilder2.addFileEdit(file, (DartFileEditBuilder builder) { + if (builder is DartFileEditBuilderImpl) { + builder.importLibraryWithRelativeUri(relativeURI); + } + }); + _addFixFromBuilder(changeBuilder2, kind, args: [relativeURI]); + } } Future<void> _addFix_importLibrary_withElement( @@ -2486,7 +2500,9 @@ fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT1; } // Add the fix. - await _addFix_importLibrary(fixKind, librarySource.uri); + var relativeURI = + _getRelativeURIFromLibrary(unitLibraryElement, librarySource); + await _addFix_importLibrary(fixKind, librarySource.uri, relativeURI); } } } @@ -3392,6 +3408,100 @@ } } + Future<void> _addFix_replaceWithIsEmpty() async { + /// Return the value of an integer literal or prefix expression with a + /// minus and then an integer literal. For anything else, returns `null`. + int getIntValue(Expression expressions) { + // Copied from package:linter/src/rules/prefer_is_empty.dart. + if (expressions is IntegerLiteral) { + return expressions.value; + } else if (expressions is PrefixExpression) { + var operand = expressions.operand; + if (expressions.operator.type == TokenType.MINUS && + operand is IntegerLiteral) { + return -operand.value; + } + } + return null; + } + + /// Return the expression producing the object on which `length` is being + /// invoked, or `null` if there is no such expression. + Expression getLengthTarget(Expression expression) { + if (expression is PropertyAccess && + expression.propertyName.name == 'length') { + return expression.target; + } else if (expression is PrefixedIdentifier && + expression.identifier.name == 'length') { + return expression.prefix; + } + return null; + } + + BinaryExpression binary = node.thisOrAncestorOfType(); + TokenType operator = binary.operator.type; + String getter; + FixKind kind; + Expression lengthTarget; + int rightValue = getIntValue(binary.rightOperand); + if (rightValue != null) { + lengthTarget = getLengthTarget(binary.leftOperand); + if (rightValue == 0) { + if (operator == TokenType.EQ_EQ || operator == TokenType.LT_EQ) { + getter = 'isEmpty'; + kind = DartFixKind.REPLACE_WITH_IS_EMPTY; + } else if (operator == TokenType.GT || operator == TokenType.BANG_EQ) { + getter = 'isNotEmpty'; + kind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY; + } + } else if (rightValue == 1) { + // 'length >= 1' is same as 'isNotEmpty', + // and 'length < 1' is same as 'isEmpty' + if (operator == TokenType.GT_EQ) { + getter = 'isNotEmpty'; + kind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY; + } else if (operator == TokenType.LT) { + getter = 'isEmpty'; + kind = DartFixKind.REPLACE_WITH_IS_EMPTY; + } + } + } else { + int leftValue = getIntValue(binary.leftOperand); + if (leftValue != null) { + lengthTarget = getLengthTarget(binary.rightOperand); + if (leftValue == 0) { + if (operator == TokenType.EQ_EQ || operator == TokenType.GT_EQ) { + getter = 'isEmpty'; + kind = DartFixKind.REPLACE_WITH_IS_EMPTY; + } else if (operator == TokenType.LT || + operator == TokenType.BANG_EQ) { + getter = 'isNotEmpty'; + kind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY; + } + } else if (leftValue == 1) { + // '1 <= length' is same as 'isNotEmpty', + // and '1 > length' is same as 'isEmpty' + if (operator == TokenType.LT_EQ) { + getter = 'isNotEmpty'; + kind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY; + } else if (operator == TokenType.GT) { + getter = 'isEmpty'; + kind = DartFixKind.REPLACE_WITH_IS_EMPTY; + } + } + } + } + if (lengthTarget == null || getter == null || kind == null) { + return; + } + String target = utils.getNodeText(lengthTarget); + DartChangeBuilder changeBuilder = _newDartChangeBuilder(); + await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { + builder.addSimpleReplacement(range.node(binary), '$target.$getter'); + }); + _addFixFromBuilder(changeBuilder, kind); + } + Future<void> _addFix_replaceWithRethrow() async { if (coveredNode is ThrowExpression) { var changeBuilder = _newDartChangeBuilder(); @@ -4134,6 +4244,27 @@ } /** + * Return the relative uri from the passed [library] to the passed + * [source]. If the [source] is not in the LibraryElement, `null` is returned. + */ + String _getRelativeURIFromLibrary(LibraryElement library, Source source) { + var librarySource = library?.librarySource; + if (librarySource == null) { + return null; + } + var pathCtx = resourceProvider.pathContext; + var libraryDirectory = pathCtx.dirname(librarySource.fullName); + var sourceDirectory = pathCtx.dirname(source.fullName); + if (pathCtx.isWithin(libraryDirectory, source.fullName) || + pathCtx.isWithin(sourceDirectory, libraryDirectory)) { + String relativeFile = + pathCtx.relative(source.fullName, from: libraryDirectory); + return pathCtx.split(relativeFile).join('/'); + } + return null; + } + + /** * Returns an expected [DartType] of [expression], may be `null` if cannot be * inferred. */ @@ -4485,6 +4616,7 @@ 'prefer_equal_for_default_values'; static const String prefer_final_fields = 'prefer_final_fields'; static const String prefer_final_locals = 'prefer_final_locals'; + static const String prefer_is_empty = 'prefer_is_empty'; static const String prefer_is_not_empty = 'prefer_is_not_empty'; static const String type_init_formals = 'type_init_formals'; static const String unawaited_futures = 'unawaited_futures'; @@ -4541,11 +4673,15 @@ factory _ExecutableParameters( AnalysisSessionHelper sessionHelper, AstNode invocation) { Element element; - if (invocation is InstanceCreationExpression) { + // This doesn't handle FunctionExpressionInvocation. + if (invocation is Annotation) { + element = invocation.element; + } else if (invocation is InstanceCreationExpression) { element = invocation.staticElement; - } - if (invocation is MethodInvocation) { + } else if (invocation is MethodInvocation) { element = invocation.methodName.staticElement; + } else if (invocation is ConstructorReferenceNode) { + element = invocation.staticElement; } if (element is ExecutableElement && !element.isSynthetic) { return new _ExecutableParameters._(sessionHelper, element);
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart index 57c725a..2723c18 100644 --- a/pkg/analysis_server/lib/src/status/diagnostics.dart +++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -40,6 +40,7 @@ import 'package:analyzer/src/source/package_map_resolver.dart'; import 'package:analyzer/src/source/sdk_ext.dart'; import 'package:path/path.dart' as pathPackage; +import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart'; final String kCustomCss = ''' .lead, .page-title+.markdown-body>p:first-child { @@ -174,9 +175,6 @@ @override Future generateContent(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; - List<CompletionPerformance> completions = performanceItems; if (completions.isEmpty) { @@ -246,8 +244,6 @@ @override Future<void> generateContent(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; String path = params['file']; if (path == null) { p('No file path provided.'); @@ -274,8 +270,6 @@ @override Future<void> generatePage(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; try { _description = params['file']; await super.generatePage(params); @@ -293,9 +287,6 @@ @override Future generateContent(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; - void writeRow(List<String> data, {List<String> classes}) { buf.write("<tr>"); for (int i = 0; i < data.length; i++) { @@ -420,8 +411,6 @@ @override Future generateContent(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; Map<Folder, AnalysisDriver> driverMap = server.driverMap; if (driverMap.isEmpty) { blankslate('No contexts.'); @@ -560,6 +549,13 @@ buf.write('</p>'); } } + + h3('Dartdoc template info'); + DartdocDirectiveInfo info = (server as AnalysisServer).declarationsTracker + ?.getContext(driver.analysisContext) + ?.dartdocDirectiveInfo ?? + new DartdocDirectiveInfo(); + writeMap(info.templateMap); } void writeList<E>(List<E> list) { @@ -600,14 +596,10 @@ AbstractAnalysisServer get server => site.socketServer.analysisServer; Future<void> generateContainer(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; buf.writeln('<div class="columns docs-layout">'); buf.writeln('<div class="three-fourths column markdown-body">'); h1(title, classes: 'page-title'); await asyncDiv(() async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; p(description); await generateContent(params); }, classes: 'markdown-body'); @@ -646,8 +638,6 @@ } Future<void> generatePage(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; buf.writeln('<!DOCTYPE html><html lang="en">'); buf.write('<head>'); buf.write('<meta charset="utf-8">'); @@ -686,8 +676,6 @@ bool get showInNav => true; Future<void> generateContainer(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; buf.writeln('<div class="columns docs-layout">'); bool shouldShowInNav(Page page) { @@ -711,8 +699,6 @@ buf.writeln('<div class="four-fifths column markdown-body">'); h1(title, classes: 'page-title'); await asyncDiv(() async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; p(description); await generateContent(params); }, classes: 'markdown-body'); @@ -792,8 +778,6 @@ @override Future<void> generateContent(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; String path = params['file']; if (path == null) { p('No file path provided.'); @@ -820,8 +804,6 @@ @override Future<void> generatePage(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; try { _description = params['file']; await super.generatePage(params); @@ -839,8 +821,6 @@ @override Future generateContent(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; buf.writeln('<table>'); buf.writeln('<tr><th>Variable</th><th>Value</th></tr>'); for (String key in Platform.environment.keys.toList()..sort()) { @@ -858,8 +838,6 @@ : super(site, '', '500 Oops', description: message); Future generateContent(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; p(trace.toString(), style: 'white-space: pre'); } } @@ -875,8 +853,6 @@ @override Future generateContent(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; if (exceptions.isEmpty) { blankslate('No exceptions encountered!'); } else { @@ -899,12 +875,10 @@ @override Future generateContent(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; final String issuesUrl = 'https://github.com/dart-lang/sdk/issues'; p( 'To file issues or feature requests, see our ' - '<a href="$issuesUrl">bug tracker</a>. When filing an issue, please describe:', + '<a href="$issuesUrl">bug tracker</a>. When filing an issue, please describe:', raw: true, ); ul([ @@ -941,8 +915,6 @@ @override Future generateContent(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; p( 'Instrumentation can be enabled by starting the analysis server with the ' '<code>--instrumentation-log-file=path/to/file</code> flag.', @@ -1025,8 +997,6 @@ @override Future generateContent(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; UsageInfo usage = await profiler.getProcessUsage(pid); developer.ServiceProtocolInfo serviceProtocolInfo = @@ -1090,8 +1060,6 @@ : super(site, '', '404 Not found', description: "'$path' not found."); Future generateContent(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; } } @@ -1181,8 +1149,6 @@ @override Future generateContent(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; h3('Profiling performance tag data'); // prepare sorted tags @@ -1330,9 +1296,6 @@ @override Future generateContent(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; - buf.writeln('<div class="columns">'); buf.writeln('<div class="column one-half">'); @@ -1369,9 +1332,6 @@ @override Future generateContent(Map<String, String> params) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; - // server domain h3('Server domain subscriptions'); ul(ServerService.VALUES, (item) { @@ -1390,5 +1350,18 @@ buf.write('$item'); }); } + + // completion domain + CompletionDomainHandler handler = server.handlers.firstWhere( + (handler) => handler is CompletionDomainHandler, + orElse: () => null); + h3('Completion domain subscriptions'); + ul(CompletionService.VALUES, (service) { + if (handler.subscriptions.contains(service)) { + buf.write('$service (has subscriptions)'); + } else { + buf.write('$service (no subscriptions)'); + } + }); } }
diff --git a/pkg/analysis_server/test/completion_test_support.dart b/pkg/analysis_server/test/completion_test_support.dart index 0af04a9..8588391 100644 --- a/pkg/analysis_server/test/completion_test_support.dart +++ b/pkg/analysis_server/test/completion_test_support.dart
@@ -13,7 +13,7 @@ /** * A base class for classes containing completion tests. */ -class CompletionTestCase extends CompletionDomainHandlerTest { +class CompletionTestCase extends CompletionDomainHandlerListTokenDetailsTest { static const String CURSOR_MARKER = '!'; List get suggestedCompletions => suggestions
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart index c98af16..3f0e266 100644 --- a/pkg/analysis_server/test/domain_completion_test.dart +++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -24,7 +24,7 @@ main() { defineReflectiveSuite(() { defineReflectiveTests(CompletionDomainHandlerGetSuggestionsTest); - defineReflectiveTests(CompletionDomainHandlerTest); + defineReflectiveTests(CompletionDomainHandlerListTokenDetailsTest); }); } @@ -866,77 +866,348 @@ } @reflectiveTest -class CompletionDomainHandlerTest extends AbstractCompletionDomainTest { - test_listTokenDetails() async { - newFile(testFile, content: ''' -class A { - static A b(String s) {} - c(int i) {} -} -main() { - A.b('s').c(3); -} -'''); +class CompletionDomainHandlerListTokenDetailsTest + extends AbstractCompletionDomainTest { + String testFileUri; + + void expectTokens(String content, List<TokenDetails> expectedTokens) async { + newFile(testFile, content: content); Request request = new CompletionListTokenDetailsParams(testFile).toRequest('0'); Response response = await waitResponse(request); List<Map<String, dynamic>> tokens = response.result['tokens']; - _expectTokens(tokens, [ - _token('class', 'CLASS', null), - _token('A', 'STRING_INT', ['declaration']), - _token('{', 'OPEN_CURLY_BRACKET', null), - _token('static', 'STATIC', null), - _token('A', 'STRING_INT', ['identifier']), - _token('b', 'STRING_INT', ['declaration']), - _token('(', 'OPEN_PAREN', null), - _token('String', 'STRING_INT', ['identifier']), - _token('s', 'STRING_INT', ['declaration']), - _token(')', 'CLOSE_PAREN', null), - _token('{', 'OPEN_CURLY_BRACKET', null), - _token('}', 'CLOSE_CURLY_BRACKET', null), - _token('c', 'STRING_INT', ['declaration']), - _token('(', 'OPEN_PAREN', null), - _token('int', 'STRING_INT', ['identifier']), - _token('i', 'STRING_INT', ['declaration']), - _token(')', 'CLOSE_PAREN', null), - _token('{', 'OPEN_CURLY_BRACKET', null), - _token('}', 'CLOSE_CURLY_BRACKET', null), - _token('}', 'CLOSE_CURLY_BRACKET', null), - _token('main', 'STRING_INT', ['declaration']), - _token('(', 'OPEN_PAREN', null), - _token(')', 'CLOSE_PAREN', null), - _token('{', 'OPEN_CURLY_BRACKET', null), - _token('A', 'STRING_INT', ['identifier']), - _token('.', 'PERIOD', null), - _token('b', 'STRING_INT', ['identifier']), - _token('(', 'OPEN_PAREN', null), - _token("'s'", 'STRING', null), - _token(')', 'CLOSE_PAREN', null), - _token('.', 'PERIOD', null), - _token('c', 'STRING_INT', ['identifier']), - _token('(', 'OPEN_PAREN', null), - _token('3', 'INT', null), - _token(')', 'CLOSE_PAREN', null), - _token(';', 'SEMICOLON', null), - _token('}', 'CLOSE_CURLY_BRACKET', null), + _compareTokens(tokens, expectedTokens); + } + + @override + void setUp() { + super.setUp(); + testFileUri = toUriStr(testFile); + } + + test_classDeclaration() async { + await expectTokens(''' +class A {} +class B extends A {} +class C implements B {} +class D with C {} +''', [ + token('class', null, null), + token('A', 'dart:core;Type', ['declaration']), + token('{', null, null), + token('}', null, null), + token('class', null, null), + token('B', 'dart:core;Type', ['declaration']), + token('extends', null, null), + token('A', 'dart:core;Type<$testFileUri;A>', ['reference']), + token('{', null, null), + token('}', null, null), + token('class', null, null), + token('C', 'dart:core;Type', ['declaration']), + token('implements', null, null), + token('B', 'dart:core;Type<$testFileUri;B>', ['reference']), + token('{', null, null), + token('}', null, null), + token('class', null, null), + token('D', 'dart:core;Type', ['declaration']), + token('with', null, null), + token('C', 'dart:core;Type<$testFileUri;C>', ['reference']), + token('{', null, null), + token('}', null, null), ]); } - void _expectTokens(List<Map<String, dynamic>> actualTokens, + test_genericType() async { + await expectTokens(''' +List<int> x = null; +''', [ + token('List', 'dart:core;Type<dart:core;List>', ['reference']), + token('<', null, null), + token('int', 'dart:core;Type<dart:core;int>', ['reference']), + token('>', null, null), + token('x', 'dart:core;List', ['declaration']), + token('=', null, null), + token('null', null, null), + token(';', null, null), + ]); + } + + test_getterInvocation() async { + await expectTokens(''' +var x = 'a'.length; +''', [ + token('var', null, null), + token('x', 'dart:core;int', ['declaration']), + token('=', null, null), + token("'a'", 'dart:core;String', null), + token('.', null, null), + token('length', 'dart:core;int', ['reference']), + token(';', null, null), + ]); + } + + test_literal_bool() async { + await expectTokens(''' +var x = true; +''', [ + token('var', null, null), + token('x', 'dart:core;bool', ['declaration']), + token('=', null, null), + token('true', 'dart:core;bool', null), + token(';', null, null), + ]); + } + + test_literal_double() async { + await expectTokens(''' +var x = 3.4; +''', [ + token('var', null, null), + token('x', 'dart:core;double', ['declaration']), + token('=', null, null), + token('3.4', 'dart:core;double', null), + token(';', null, null), + ]); + } + + test_literal_int() async { + await expectTokens(''' +var x = 7; +''', [ + token('var', null, null), + token('x', 'dart:core;int', ['declaration']), + token('=', null, null), + token('7', 'dart:core;int', null), + token(';', null, null), + ]); + } + + test_literal_list() async { + await expectTokens(''' +var x = <int>[]; +''', [ + token('var', null, null), + token('x', 'dart:core;List', ['declaration']), + token('=', null, null), + token('<', null, null), + token("int", 'dart:core;Type<dart:core;int>', ['reference']), + token('>', null, null), + token('[', null, null), + token(']', null, null), + token(';', null, null), + ]); + } + + test_literal_map() async { + await expectTokens(''' +var x = <int, int>{}; +''', [ + token('var', null, null), + token('x', 'dart:core;Map', ['declaration']), + token('=', null, null), + token('<', null, null), + token("int", 'dart:core;Type<dart:core;int>', ['reference']), +// token(',', null, null), + token("int", 'dart:core;Type<dart:core;int>', ['reference']), + token('>', null, null), + token('{', null, null), + token('}', null, null), + token(';', null, null), + ]); + } + + test_literal_null() async { + await expectTokens(''' +var x = null; +''', [ + token('var', null, null), + token('x', 'dynamic', ['declaration']), + token('=', null, null), + token('null', null, null), + token(';', null, null), + ]); + } + + test_literal_set() async { + await expectTokens(''' +var x = <int>{}; +''', [ + token('var', null, null), + token('x', 'dart:core;Set', ['declaration']), + token('=', null, null), + token('<', null, null), + token("int", 'dart:core;Type<dart:core;int>', ['reference']), + token('>', null, null), + token('{', null, null), + token('}', null, null), + token(';', null, null), + ]); + } + + test_literal_string() async { + await expectTokens(''' +var x = 'a'; +''', [ + token('var', null, null), + token('x', 'dart:core;String', ['declaration']), + token('=', null, null), + token("'a'", 'dart:core;String', null), + token(';', null, null), + ]); + } + + test_methodDeclaration() async { + await expectTokens(''' +class A { + String c(int x, int y) {} +} +''', [ + token('class', null, null), + token('A', 'dart:core;Type', ['declaration']), + token('{', null, null), + token('String', 'dart:core;Type<dart:core;String>', ['reference']), + token('c', 'dart:core;String Function(dart:core;int, dart:core;int)', + ['declaration']), + token('(', null, null), + token('int', 'dart:core;Type<dart:core;int>', ['reference']), + token('x', 'dart:core;int', ['declaration']), +// token(',', null, null), + token('int', 'dart:core;Type<dart:core;int>', ['reference']), + token('y', 'dart:core;int', ['declaration']), + token(')', null, null), + token('{', null, null), + token('}', null, null), + token('}', null, null), + ]); + } + + test_methodInvocation() async { + await expectTokens(''' +var x = 'radar'.indexOf('r', 1); +''', [ + token('var', null, null), + token('x', 'dart:core;int', ['declaration']), + token('=', null, null), + token("'radar'", 'dart:core;String', null), + token('.', null, null), + token( + 'indexOf', + 'dart:core;int Function(dart:core;Pattern, dart:core;int)', + ['reference']), + token('(', null, null), + token("'r'", 'dart:core;String', null), +// token(',', null, null), + token('1', 'dart:core;int', null), + token(')', null, null), + token(';', null, null), + ]); + } + + test_mixinDeclaration() async { + await expectTokens(''' +class A {} +class B {} +mixin D on A implements B {} +''', [ + token('class', null, null), + token('A', 'dart:core;Type', ['declaration']), + token('{', null, null), + token('}', null, null), + token('class', null, null), + token('B', 'dart:core;Type', ['declaration']), + token('{', null, null), + token('}', null, null), + token('mixin', null, null), + token('D', 'dart:core;Type', ['declaration']), + token('on', null, null), + token('A', 'dart:core;Type<$testFileUri;A>', ['reference']), + token('implements', null, null), + token('B', 'dart:core;Type<$testFileUri;B>', ['reference']), + token('{', null, null), + token('}', null, null), + ]); + } + + test_parameterReference() async { + await expectTokens(''' +int f(int p) { + return p; +} +''', [ + token('int', 'dart:core;Type<dart:core;int>', ['reference']), + token('f', 'dart:core;int Function(dart:core;int)', ['declaration']), + token('(', null, null), + token('int', 'dart:core;Type<dart:core;int>', ['reference']), + token('p', 'dart:core;int', ['declaration']), + token(')', null, null), + token('{', null, null), + token('return', null, null), + token('p', 'dart:core;int', ['reference']), + token(';', null, null), + token('}', null, null), + ]); + } + + test_topLevelVariable_withDocComment() async { + await expectTokens(''' +/// Doc comment [x] with reference. +int x; +''', [ + token('int', 'dart:core;Type<dart:core;int>', ['reference']), + token('x', 'dart:core;int', ['declaration']), + token(';', null, null), + ]); + } + + TokenDetails token(String lexeme, String type, List<String> kinds) { + return new TokenDetails(lexeme, type: type, validElementKinds: kinds); + } + + void _compareTokens(List<Map<String, dynamic>> actualTokens, List<TokenDetails> expectedTokens) { int length = expectedTokens.length; expect(actualTokens, hasLength(length)); + List<String> errors = []; for (int i = 0; i < length; i++) { Map<String, dynamic> actual = actualTokens[i]; TokenDetails expected = expectedTokens[i]; - expect(actual['lexeme'], expected.lexeme); - expect(actual['type'], expected.type); - expect(actual['validElementKinds'], expected.validElementKinds); + if (actual['lexeme'] != expected.lexeme) { + errors.add('Lexeme at $i: ' + 'expected "${expected.lexeme}", ' + 'actual "${actual['lexeme']}"'); + } + if (actual['type'] != expected.type) { + errors.add('Type at $i ("${expected.lexeme}"): ' + 'expected "${expected.type}", ' + 'actual "${actual['type']}"'); + } + if (_differentKinds( + actual['validElementKinds'], expected.validElementKinds)) { + errors.add('Kinds at $i ("${expected.lexeme}"): ' + 'expected "${expected.validElementKinds}", ' + 'actual "${actual['validElementKinds']}"'); + } } + expect(errors, isEmpty); } - TokenDetails _token(String lexeme, String type, List<String> kinds) { - return new TokenDetails(lexeme, type, validElementKinds: kinds); + /// Return `true` if the two lists of kinds are different. + bool _differentKinds(List<String> actual, List<String> expected) { + if (actual == null) { + return expected != null; + } else if (expected == null) { + return true; + } + int expectedLength = expected.length; + if (actual.length != expectedLength) { + return true; + } + for (int i = 0; i < expectedLength; i++) { + if (actual[i] != expected[i]) { + return true; + } + } + return false; } }
diff --git a/pkg/analysis_server/test/domain_edit_dartfix_test.dart b/pkg/analysis_server/test/domain_edit_dartfix_test.dart index 3f322e6..8a0e7b0 100644 --- a/pkg/analysis_server/test/domain_edit_dartfix_test.dart +++ b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
@@ -28,11 +28,12 @@ void expectEdits(List<SourceFileEdit> fileEdits, String expectedSource) { expect(fileEdits, hasLength(1)); expect(fileEdits[0].file, testFile); - List<SourceEdit> edits = fileEdits[0].edits; - String source = testCode; - for (SourceEdit edit in edits) { - source = edit.apply(source); - } + expectFileEdits(testCode, fileEdits[0], expectedSource); + } + + void expectFileEdits( + String originalSource, SourceFileEdit fileEdit, String expectedSource) { + String source = SourceEdit.applySequence(originalSource, fileEdit.edits); expect(source, expectedSource); } @@ -144,6 +145,78 @@ '''); } + test_dartfix_non_nullable_analysis_options_created() async { + // Add pubspec for nnbd migration to detect + newFile('/project/pubspec.yaml', content: ''' +name: testnnbd +'''); + createProject(); + EditDartfixResult result = + await performFix(includedFixes: ['non-nullable']); + expect(result.suggestions.length, greaterThanOrEqualTo(1)); + expect(result.hasErrors, isFalse); + expect(result.edits, hasLength(1)); + expectFileEdits('', result.edits[0], ''' +analyzer: + enable-experiment: + - non-nullable + +'''); + } + + test_dartfix_non_nullable_analysis_options_experiments_added() async { + String originalOptions = ''' +analyzer: + something: + - other + +linter: + - boo +'''; + newFile('/project/analysis_options.yaml', content: originalOptions); + createProject(); + EditDartfixResult result = + await performFix(includedFixes: ['non-nullable']); + expect(result.suggestions.length, greaterThanOrEqualTo(1)); + expect(result.hasErrors, isFalse); + expect(result.edits, hasLength(1)); + expectFileEdits(originalOptions, result.edits[0], ''' +analyzer: + something: + - other + enable-experiment: + - non-nullable + +linter: + - boo +'''); + } + + test_dartfix_non_nullable_analysis_options_nnbd_added() async { + String originalOptions = ''' +analyzer: + enable-experiment: + - other +linter: + - boo +'''; + newFile('/project/analysis_options.yaml', content: originalOptions); + createProject(); + EditDartfixResult result = + await performFix(includedFixes: ['non-nullable']); + expect(result.suggestions.length, greaterThanOrEqualTo(1)); + expect(result.hasErrors, isFalse); + expect(result.edits, hasLength(1)); + expectFileEdits(originalOptions, result.edits[0], ''' +analyzer: + enable-experiment: + - other + - non-nullable +linter: + - boo +'''); + } + test_dartfix_excludedSource() async { // Add analysis options to exclude the lib directory then reanalyze newFile('/project/analysis_options.yaml', content: ''' @@ -200,4 +273,77 @@ const double myDouble = 42; '''); } + + test_dartfix_spread_collections() async { + // Add analysis options to enable ui as code + newFile('/project/analysis_options.yaml', content: ''' +analyzer: + enable-experiment: + - control-flow-collections + - spread-collections +'''); + addTestFile(''' +var l = ['a']..addAll(['b']); +'''); + createProject(); + EditDartfixResult result = + await performFix(includedFixes: ['use-spread-collections']); + expect(result.suggestions.length, greaterThanOrEqualTo(1)); + expect(result.hasErrors, isFalse); + expectEdits(result.edits, ''' +var l = ['a', ...['b']]; +'''); + } + + test_dartfix_collection_if_elements() async { + // Add analysis options to enable ui as code + newFile('/project/analysis_options.yaml', content: ''' +analyzer: + enable-experiment: + - control-flow-collections + - spread-collections +'''); + addTestFile(''' +f(bool b) { + return ['a', b ? 'c' : 'd', 'e']; +} +'''); + createProject(); + EditDartfixResult result = + await performFix(includedFixes: ['collection-if-elements']); + expect(result.suggestions.length, greaterThanOrEqualTo(1)); + expect(result.hasErrors, isFalse); + expectEdits(result.edits, ''' +f(bool b) { + return ['a', if (b) 'c' else 'd', 'e']; +} +'''); + } + + test_dartfix_map_for_elements() async { + // Add analysis options to enable ui as code + newFile('/project/analysis_options.yaml', content: ''' +analyzer: + enable-experiment: + - control-flow-collections + - spread-collections +'''); + addTestFile(''' +f(Iterable<int> i) { + var k = 3; + return Map.fromIterable(i, key: (k) => k * 2, value: (v) => k); +} +'''); + createProject(); + EditDartfixResult result = + await performFix(includedFixes: ['map-for-elements']); + expect(result.suggestions.length, greaterThanOrEqualTo(1)); + expect(result.hasErrors, isFalse); + expectEdits(result.edits, ''' +f(Iterable<int> i) { + var k = 3; + return { for (var e in i) e * 2 : k }; +} +'''); + } }
diff --git a/pkg/analysis_server/test/edit/test_all.dart b/pkg/analysis_server/test/edit/test_all.dart index 79cc139..70251a6 100644 --- a/pkg/analysis_server/test/edit/test_all.dart +++ b/pkg/analysis_server/test/edit/test_all.dart
@@ -4,24 +4,24 @@ import 'package:test_reflective_loader/test_reflective_loader.dart'; -import 'assists_test.dart' as assists_test; -import 'fixes_test.dart' as fixes_test; -import 'format_test.dart' as format_test; -import 'organize_directives_test.dart' as organize_directives_test; -import 'postfix_completion_test.dart' as postfix_completion_test; -import 'refactoring_test.dart' as refactoring_test; -import 'sort_members_test.dart' as sort_members_test; -import 'statement_completion_test.dart' as statement_completion_test; +import 'assists_test.dart' as assists; +import 'fixes_test.dart' as fixes; +import 'format_test.dart' as format; +import 'organize_directives_test.dart' as organize_directives; +import 'postfix_completion_test.dart' as postfix_completion; +import 'refactoring_test.dart' as refactoring; +import 'sort_members_test.dart' as sort_members; +import 'statement_completion_test.dart' as statement_completion; main() { defineReflectiveSuite(() { - assists_test.main(); - fixes_test.main(); - format_test.main(); - organize_directives_test.main(); - postfix_completion_test.main(); - refactoring_test.main(); - sort_members_test.main(); - statement_completion_test.main(); + assists.main(); + fixes.main(); + format.main(); + organize_directives.main(); + postfix_completion.main(); + refactoring.main(); + sort_members.main(); + statement_completion.main(); }, name: 'edit'); }
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart index cfd4d3a..fe67037 100644 --- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart +++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -2026,6 +2026,13 @@ * * The elements to be made accessible in the specified file. * + * offset: int (optional) + * + * The offset at which the specified elements need to be made accessible. + * If provided, this is used to guard against adding imports for text that + * would be inserted into a comment, string literal, or other location + * where the imports would not be necessary. + * * Returns * * edit: SourceFileEdit (optional) @@ -2038,8 +2045,10 @@ * that need to be applied. */ Future<EditImportElementsResult> sendEditImportElements( - String file, List<ImportedElements> elements) async { - var params = new EditImportElementsParams(file, elements).toJson(); + String file, List<ImportedElements> elements, + {int offset}) async { + var params = + new EditImportElementsParams(file, elements, offset: offset).toJson(); var result = await server.send("edit.importElements", params); ResponseDecoder decoder = new ResponseDecoder(null); return new EditImportElementsResult.fromJson(decoder, 'result', result);
diff --git a/pkg/analysis_server/test/integration/support/integration_tests.dart b/pkg/analysis_server/test/integration/support/integration_tests.dart index 16f7d4b..7d348d6 100644 --- a/pkg/analysis_server/test/integration/support/integration_tests.dart +++ b/pkg/analysis_server/test/integration/support/integration_tests.dart
@@ -712,6 +712,7 @@ if (Platform.packageConfig != null) { arguments.add('--packages=${Platform.packageConfig}'); } + arguments.add('--disable-service-auth-codes'); // // Add the server executable. //
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart index 7cee89f..ec50cf1 100644 --- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart +++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -1618,13 +1618,17 @@ * * { * "lexeme": String - * "type": String + * "type": optional String * "validElementKinds": optional List<String> * } */ final Matcher isTokenDetails = new LazyMatcher(() => new MatchesJsonObject( - "TokenDetails", {"lexeme": isString, "type": isString}, - optionalFields: {"validElementKinds": isListOf(isString)})); + "TokenDetails", { + "lexeme": isString + }, optionalFields: { + "type": isString, + "validElementKinds": isListOf(isString) + })); /** * TypeHierarchyItem @@ -2616,11 +2620,13 @@ * { * "file": FilePath * "elements": List<ImportedElements> + * "offset": optional int * } */ final Matcher isEditImportElementsParams = new LazyMatcher(() => new MatchesJsonObject("edit.importElements params", - {"file": isFilePath, "elements": isListOf(isImportedElements)})); + {"file": isFilePath, "elements": isListOf(isImportedElements)}, + optionalFields: {"offset": isInt})); /** * edit.importElements result
diff --git a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart index 2da217e..03fa79b 100644 --- a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart +++ b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
@@ -52,7 +52,9 @@ var uriStr = 'package:test/a.dart'; newFile(path, content: r''' -class A {} +class A { + A.a(); +} '''); var set = await waitForSetWithUri(uriStr); @@ -77,6 +79,27 @@ ] } '''); + assertJsonText(_getSuggestion(set, 'A.a'), ''' +{ + "label": "A.a", + "element": { + "kind": "CONSTRUCTOR", + "name": "a", + "location": { + "file": ${jsonOfPath(path)}, + "offset": 14, + "length": 0, + "startLine": 2, + "startColumn": 5 + }, + "flags": 0, + "parameters": "()" + }, + "parameterNames": [], + "parameterTypes": [], + "requiredParameterCount": 0 +} +'''); } test_suggestion_enum() async {
diff --git a/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart b/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart index e9db0d5..c3b1915 100644 --- a/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart +++ b/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
@@ -7,6 +7,7 @@ import 'package:analysis_server/src/nullability/constraint_variable_gatherer.dart'; import 'package:analysis_server/src/nullability/decorated_type.dart'; import 'package:analysis_server/src/nullability/expression_checks.dart'; +import 'package:analysis_server/src/nullability/nullability_node.dart'; import 'package:analysis_server/src/nullability/transitional_api.dart'; import 'package:analysis_server/src/nullability/unit_propagation.dart'; import 'package:analyzer/dart/ast/ast.dart'; @@ -48,6 +49,14 @@ predicate((_Clause clause) => clause.consequence == consequence)))); } + void assertNonNullIntent(NullabilityNode node, bool expected) { + if (expected) { + assertConstraint([], node.nonNullIntent); + } else { + assertNoConstraints(node.nonNullIntent); + } + } + /// Gets the [ExpressionChecks] associated with the expression whose text /// representation is [text], or `null` if the expression has no /// [ExpressionChecks] associated with it. @@ -78,7 +87,7 @@ } '''); - assertConstraint([], decoratedTypeAnnotation('int i').nonNullIntent); + assertNonNullIntent(decoratedTypeAnnotation('int i').node, true); } test_binaryExpression_add_left_check() async { @@ -86,7 +95,7 @@ int f(int i, int j) => i + j; '''); - assertConstraint([decoratedTypeAnnotation('int i').nullable], + assertConstraint([decoratedTypeAnnotation('int i').node.nullable], checkExpression('i +').nullCheck); } @@ -98,7 +107,7 @@ Int f(Int i, Int j) => i + j; '''); - assertConstraint([decoratedTypeAnnotation('Int i').nullable], + assertConstraint([decoratedTypeAnnotation('Int i').node.nullable], checkExpression('i +').nullCheck); } @@ -111,8 +120,8 @@ '''); assertConstraint( - [decoratedTypeAnnotation('Int operator+').nullable], - _either(decoratedTypeAnnotation('Int f').nullable, + [decoratedTypeAnnotation('Int operator+').node.nullable], + _either(decoratedTypeAnnotation('Int f').node.nullable, checkExpression('(i + j)').nullCheck)); } @@ -121,7 +130,7 @@ int f(int i, int j) => i + j; '''); - assertNoConstraints(decoratedTypeAnnotation('int f').nullable); + assertNoConstraints(decoratedTypeAnnotation('int f').node.nullable); } test_binaryExpression_add_right_check() async { @@ -129,7 +138,7 @@ int f(int i, int j) => i + j; '''); - assertConstraint([decoratedTypeAnnotation('int j').nullable], + assertConstraint([decoratedTypeAnnotation('int j').node.nullable], checkExpression('j;').nullCheck); } @@ -142,8 +151,8 @@ '''); assertConstraint( - [decoratedTypeAnnotation('Int j').nullable], - _either(decoratedTypeAnnotation('Int other').nullable, + [decoratedTypeAnnotation('Int j').node.nullable], + _either(decoratedTypeAnnotation('Int other').node.nullable, checkExpression('j/*check*/').nullCheck)); } @@ -152,7 +161,7 @@ bool f(int i, int j) => i == j; '''); - assertNoConstraints(decoratedTypeAnnotation('bool f').nullable); + assertNoConstraints(decoratedTypeAnnotation('bool f').node.nullable); } test_boolLiteral() async { @@ -161,7 +170,7 @@ return true; } '''); - assertNoConstraints(decoratedTypeAnnotation('bool').nullable); + assertNoConstraints(decoratedTypeAnnotation('bool').node.nullable); } test_conditionalExpression_condition_check() async { @@ -171,7 +180,7 @@ } '''); - var nullable_b = decoratedTypeAnnotation('bool b').nullable; + var nullable_b = decoratedTypeAnnotation('bool b').node.nullable; var check_b = checkExpression('b ?').nullCheck; assertConstraint([nullable_b], check_b); } @@ -183,11 +192,11 @@ } '''); - var nullable_i = decoratedTypeAnnotation('int i').nullable; - var nullable_j = decoratedTypeAnnotation('int j').nullable; + var nullable_i = decoratedTypeAnnotation('int i').node.nullable; + var nullable_j = decoratedTypeAnnotation('int j').node.nullable; var nullable_i_or_nullable_j = _either(nullable_i, nullable_j); - var nullable_conditional = decoratedExpressionType('(b ?').nullable; - var nullable_return = decoratedTypeAnnotation('int f').nullable; + var nullable_conditional = decoratedExpressionType('(b ?').node.nullable; + var nullable_return = decoratedTypeAnnotation('int f').node.nullable; assertConstraint([nullable_i], nullable_conditional); assertConstraint([nullable_j], nullable_conditional); assertConstraint([nullable_conditional], nullable_i_or_nullable_j); @@ -202,8 +211,8 @@ } '''); - var nullable_i = decoratedTypeAnnotation('int i').nullable; - var nullable_conditional = decoratedExpressionType('(b ?').nullable; + var nullable_i = decoratedTypeAnnotation('int i').node.nullable; + var nullable_conditional = decoratedExpressionType('(b ?').node.nullable; expect(nullable_conditional, same(nullable_i)); } @@ -214,7 +223,7 @@ } '''); - var nullable_conditional = decoratedExpressionType('(b ?').nullable; + var nullable_conditional = decoratedExpressionType('(b ?').node.nullable; expect(nullable_conditional, same(ConstraintVariable.always)); } @@ -225,8 +234,8 @@ } '''); - var nullable_i = decoratedTypeAnnotation('int i').nullable; - var nullable_conditional = decoratedExpressionType('(b ?').nullable; + var nullable_i = decoratedTypeAnnotation('int i').node.nullable; + var nullable_conditional = decoratedExpressionType('(b ?').node.nullable; expect(nullable_conditional, same(nullable_i)); } @@ -237,7 +246,7 @@ } '''); - var nullable_conditional = decoratedExpressionType('(b ?').nullable; + var nullable_conditional = decoratedExpressionType('(b ?').node.nullable; expect(nullable_conditional, same(ConstraintVariable.always)); } @@ -247,8 +256,8 @@ '''); assertConstraint( - [decoratedTypeAnnotation('int/*2*/').nullable], - _either(decoratedTypeAnnotation('int/*1*/').nullable, + [decoratedTypeAnnotation('int/*2*/').node.nullable], + _either(decoratedTypeAnnotation('int/*1*/').node.nullable, checkExpression('i/*3*/').nullCheck)); } @@ -257,7 +266,7 @@ void f({int i = 1}) {} '''); - assertNoConstraints(decoratedTypeAnnotation('int').nullable); + assertNoConstraints(decoratedTypeAnnotation('int').node.nullable); } test_functionDeclaration_parameter_named_default_null() async { @@ -265,8 +274,8 @@ void f({int i = null}) {} '''); - assertConstraint( - [ConstraintVariable.always], decoratedTypeAnnotation('int').nullable); + assertConstraint([ConstraintVariable.always], + decoratedTypeAnnotation('int').node.nullable); } test_functionDeclaration_parameter_named_no_default_assume_nullable() async { @@ -277,7 +286,8 @@ namedNoDefaultParameterHeuristic: NamedNoDefaultParameterHeuristic.assumeNullable)); - assertConstraint([], decoratedTypeAnnotation('int').nullable); + assertConstraint([ConstraintVariable.always], + decoratedTypeAnnotation('int').node.nullable); } test_functionDeclaration_parameter_named_no_default_assume_required() async { @@ -288,7 +298,7 @@ namedNoDefaultParameterHeuristic: NamedNoDefaultParameterHeuristic.assumeRequired)); - assertNoConstraints(decoratedTypeAnnotation('int').nullable); + assertNoConstraints(decoratedTypeAnnotation('int').node.nullable); } test_functionDeclaration_parameter_named_no_default_required_assume_nullable() async { @@ -301,7 +311,7 @@ namedNoDefaultParameterHeuristic: NamedNoDefaultParameterHeuristic.assumeNullable)); - assertNoConstraints(decoratedTypeAnnotation('int').nullable); + assertNoConstraints(decoratedTypeAnnotation('int').node.nullable); } test_functionDeclaration_parameter_named_no_default_required_assume_required() async { @@ -314,7 +324,7 @@ namedNoDefaultParameterHeuristic: NamedNoDefaultParameterHeuristic.assumeRequired)); - assertNoConstraints(decoratedTypeAnnotation('int').nullable); + assertNoConstraints(decoratedTypeAnnotation('int').node.nullable); } test_functionDeclaration_parameter_positionalOptional_default_notNull() async { @@ -322,7 +332,7 @@ void f([int i = 1]) {} '''); - assertNoConstraints(decoratedTypeAnnotation('int').nullable); + assertNoConstraints(decoratedTypeAnnotation('int').node.nullable); } test_functionDeclaration_parameter_positionalOptional_default_null() async { @@ -330,8 +340,8 @@ void f([int i = null]) {} '''); - assertConstraint( - [ConstraintVariable.always], decoratedTypeAnnotation('int').nullable); + assertConstraint([ConstraintVariable.always], + decoratedTypeAnnotation('int').node.nullable); } test_functionDeclaration_parameter_positionalOptional_no_default() async { @@ -339,7 +349,8 @@ void f([int i]) {} '''); - assertConstraint([], decoratedTypeAnnotation('int').nullable); + assertConstraint([ConstraintVariable.always], + decoratedTypeAnnotation('int').node.nullable); } test_functionDeclaration_parameter_positionalOptional_no_default_assume_required() async { @@ -352,7 +363,8 @@ namedNoDefaultParameterHeuristic: NamedNoDefaultParameterHeuristic.assumeRequired)); - assertConstraint([], decoratedTypeAnnotation('int').nullable); + assertConstraint([ConstraintVariable.always], + decoratedTypeAnnotation('int').node.nullable); } test_functionDeclaration_resets_unconditional_control_flow() async { @@ -366,9 +378,9 @@ assert(k != null); } '''); - assertConstraint([], decoratedTypeAnnotation('int i').nonNullIntent); - assertNoConstraints(decoratedTypeAnnotation('int j').nonNullIntent); - assertConstraint([], decoratedTypeAnnotation('int k').nonNullIntent); + assertNonNullIntent(decoratedTypeAnnotation('int i').node, true); + assertNonNullIntent(decoratedTypeAnnotation('int j').node, false); + assertNonNullIntent(decoratedTypeAnnotation('int k').node, true); } test_functionInvocation_parameter_fromLocalParameter() async { @@ -382,9 +394,11 @@ var int_1 = decoratedTypeAnnotation('int/*1*/'); var int_2 = decoratedTypeAnnotation('int/*2*/'); var i_3 = checkExpression('i/*3*/'); - assertConstraint([int_2.nullable], _either(int_1.nullable, i_3.nullCheck)); - assertConstraint([int_2.nullable, int_1.nonNullIntent], i_3.nullCheck); - assertConstraint([int_1.nonNullIntent], int_2.nonNullIntent); + assertConstraint( + [int_2.node.nullable], _either(int_1.node.nullable, i_3.nullCheck)); + assertConstraint( + [int_2.node.nullable, int_1.node.nonNullIntent], i_3.nullCheck); + assertConstraint([int_1.node.nonNullIntent], int_2.node.nonNullIntent); } test_functionInvocation_parameter_named() async { @@ -394,8 +408,8 @@ f(i: j/*check*/); } '''); - var nullable_i = decoratedTypeAnnotation('int i').nullable; - var nullable_j = decoratedTypeAnnotation('int j').nullable; + var nullable_i = decoratedTypeAnnotation('int i').node.nullable; + var nullable_j = decoratedTypeAnnotation('int j').node.nullable; assertConstraint([nullable_j], _either(nullable_i, checkExpression('j/*check*/').nullCheck)); } @@ -408,7 +422,7 @@ } '''); var optional_i = possiblyOptionalParameter('int i'); - assertConstraint([], optional_i); + assertConstraint([], optional_i.nullable); } test_functionInvocation_parameter_named_missing_required() async { @@ -424,7 +438,7 @@ // The call at `f()` is presumed to be in error; no constraint is recorded. var optional_i = possiblyOptionalParameter('int i'); expect(optional_i, isNull); - var nullable_i = decoratedTypeAnnotation('int i').nullable; + var nullable_i = decoratedTypeAnnotation('int i').node.nullable; assertNoConstraints(nullable_i); } @@ -438,7 +452,7 @@ assertConstraint( [ConstraintVariable.always], - _either(decoratedTypeAnnotation('int').nullable, + _either(decoratedTypeAnnotation('int').node.nullable, checkExpression('null').nullCheck)); } @@ -451,8 +465,8 @@ '''); assertConstraint( - [decoratedTypeAnnotation('int/*1*/').nullable], - _either(decoratedTypeAnnotation('int/*2*/').nullable, + [decoratedTypeAnnotation('int/*1*/').node.nullable], + _either(decoratedTypeAnnotation('int/*2*/').node.nullable, checkExpression('(f())').nullCheck)); } @@ -463,7 +477,7 @@ } '''); - assertConstraint([(decoratedTypeAnnotation('bool b').nullable)], + assertConstraint([(decoratedTypeAnnotation('bool b').node.nullable)], checkExpression('b) {}').nullCheck); } @@ -477,7 +491,7 @@ } '''); - assertNoConstraints(decoratedTypeAnnotation('int i').nonNullIntent); + assertNonNullIntent(decoratedTypeAnnotation('int i').node, false); } test_if_conditional_control_flow_within() async { @@ -492,7 +506,7 @@ } '''); - assertNoConstraints(decoratedTypeAnnotation('int i').nonNullIntent); + assertNonNullIntent(decoratedTypeAnnotation('int i').node, false); } test_if_guard_equals_null() async { @@ -505,17 +519,17 @@ } } '''); - var nullable_i = decoratedTypeAnnotation('int i').nullable; - var nullable_j = decoratedTypeAnnotation('int j').nullable; - var nullable_k = decoratedTypeAnnotation('int k').nullable; - var nullable_return = decoratedTypeAnnotation('int f').nullable; + var nullable_i = decoratedTypeAnnotation('int i').node.nullable; + var nullable_j = decoratedTypeAnnotation('int j').node.nullable; + var nullable_k = decoratedTypeAnnotation('int k').node.nullable; + var nullable_return = decoratedTypeAnnotation('int f').node.nullable; assertConstraint([nullable_i, nullable_j], _either(nullable_return, checkExpression('j/*check*/').nullCheck)); assertConstraint([nullable_k], _either(nullable_return, checkExpression('k/*check*/').nullCheck)); var discard = statementDiscard('if (i == null)'); - expect(discard.keepTrue, same(nullable_i)); - expect(discard.keepFalse, same(ConstraintVariable.always)); + expect(discard.trueGuard.nullable, same(nullable_i)); + expect(discard.falseGuard, null); expect(discard.pureCondition, true); } @@ -530,9 +544,9 @@ } '''); - var nullable_i = decoratedTypeAnnotation('int i').nullable; - var nullable_j = decoratedTypeAnnotation('int j').nullable; - var nullable_return = decoratedTypeAnnotation('int f').nullable; + var nullable_i = decoratedTypeAnnotation('int i').node.nullable; + var nullable_j = decoratedTypeAnnotation('int j').node.nullable; + var nullable_return = decoratedTypeAnnotation('int f').node.nullable; assertConstraint([nullable_i], _either(nullable_return, checkExpression('i/*check*/').nullCheck)); assertConstraint([nullable_j], @@ -549,8 +563,8 @@ } '''); - var nullable_i = decoratedTypeAnnotation('int i').nullable; - var nullable_return = decoratedTypeAnnotation('int f').nullable; + var nullable_i = decoratedTypeAnnotation('int i').node.nullable; + var nullable_return = decoratedTypeAnnotation('int f').node.nullable; assertConstraint([nullable_i], _either(nullable_return, checkExpression('i/*check*/').nullCheck)); } @@ -561,7 +575,7 @@ return 0; } '''); - assertNoConstraints(decoratedTypeAnnotation('int').nullable); + assertNoConstraints(decoratedTypeAnnotation('int').node.nullable); } test_methodDeclaration_resets_unconditional_control_flow() async { @@ -577,9 +591,9 @@ } } '''); - assertConstraint([], decoratedTypeAnnotation('int i').nonNullIntent); - assertNoConstraints(decoratedTypeAnnotation('int j').nonNullIntent); - assertConstraint([], decoratedTypeAnnotation('int k').nonNullIntent); + assertNonNullIntent(decoratedTypeAnnotation('int i').node, true); + assertNonNullIntent(decoratedTypeAnnotation('int j').node, false); + assertNonNullIntent(decoratedTypeAnnotation('int k').node, true); } test_methodInvocation_parameter_contravariant() async { @@ -592,10 +606,10 @@ } '''); - var nullable_i = decoratedTypeAnnotation('int i').nullable; + var nullable_i = decoratedTypeAnnotation('int i').node.nullable; var nullable_c_t = - decoratedTypeAnnotation('C<int>').typeArguments[0].nullable; - var nullable_t = decoratedTypeAnnotation('T t').nullable; + decoratedTypeAnnotation('C<int>').typeArguments[0].node.nullable; + var nullable_t = decoratedTypeAnnotation('T t').node.nullable; var nullable_c_t_or_nullable_t = _either(nullable_c_t, nullable_t); assertConstraint( [nullable_i], @@ -612,11 +626,11 @@ } '''); - assertConstraint([decoratedTypeAnnotation('int/*3*/').nullable], - decoratedTypeAnnotation('int/*1*/').nullable); + assertConstraint([decoratedTypeAnnotation('int/*3*/').node.nullable], + decoratedTypeAnnotation('int/*1*/').node.nullable); assertConstraint( - [decoratedTypeAnnotation('C<int/*3*/>/*4*/').nullable], - _either(decoratedTypeAnnotation('C<int/*1*/>/*2*/').nullable, + [decoratedTypeAnnotation('C<int/*3*/>/*4*/').node.nullable], + _either(decoratedTypeAnnotation('C<int/*1*/>/*2*/').node.nullable, checkExpression('c/*check*/').nullCheck)); } @@ -629,8 +643,8 @@ c.f(i: j/*check*/); } '''); - var nullable_i = decoratedTypeAnnotation('int i').nullable; - var nullable_j = decoratedTypeAnnotation('int j').nullable; + var nullable_i = decoratedTypeAnnotation('int i').node.nullable; + var nullable_j = decoratedTypeAnnotation('int j').node.nullable; assertConstraint([nullable_j], _either(nullable_i, checkExpression('j/*check*/').nullCheck)); } @@ -645,7 +659,7 @@ } '''); - assertConstraint([decoratedTypeAnnotation('C c').nullable], + assertConstraint([decoratedTypeAnnotation('C c').node.nullable], checkExpression('c.m').nullCheck); } @@ -659,7 +673,7 @@ } '''); - assertConstraint([], decoratedTypeAnnotation('C c').nonNullIntent); + assertNonNullIntent(decoratedTypeAnnotation('C c').node, true); } test_parenthesizedExpression() async { @@ -671,7 +685,7 @@ assertConstraint( [ConstraintVariable.always], - _either(decoratedTypeAnnotation('int').nullable, + _either(decoratedTypeAnnotation('int').node.nullable, checkExpression('(null)').nullCheck)); } @@ -683,8 +697,8 @@ } '''); - assertConstraint( - [ConstraintVariable.always], decoratedTypeAnnotation('int').nullable); + assertConstraint([ConstraintVariable.always], + decoratedTypeAnnotation('int').node.nullable); } test_return_null() async { @@ -696,7 +710,7 @@ assertConstraint( [ConstraintVariable.always], - _either(decoratedTypeAnnotation('int').nullable, + _either(decoratedTypeAnnotation('int').node.nullable, checkExpression('null').nullCheck)); } @@ -707,7 +721,7 @@ return 'x'; } '''); - assertNoConstraints(decoratedTypeAnnotation('String').nullable); + assertNoConstraints(decoratedTypeAnnotation('String').node.nullable); } test_thisExpression() async { @@ -717,7 +731,7 @@ } '''); - assertNoConstraints(decoratedTypeAnnotation('C f').nullable); + assertNoConstraints(decoratedTypeAnnotation('C f').node.nullable); } test_throwExpression() async { @@ -726,7 +740,7 @@ return throw null; } '''); - assertNoConstraints(decoratedTypeAnnotation('int').nullable); + assertNoConstraints(decoratedTypeAnnotation('int').node.nullable); } test_typeName() async { @@ -735,7 +749,7 @@ return int; } '''); - assertNoConstraints(decoratedTypeAnnotation('Type').nullable); + assertNoConstraints(decoratedTypeAnnotation('Type').node.nullable); } /// Creates a variable representing the disjunction of [a] and [b] solely for @@ -777,7 +791,7 @@ var decoratedType = decoratedTypeAnnotation('int?'); expect(decoratedFunctionType('f').positionalParameters[0], same(decoratedType)); - expect(decoratedType.nullable, same(ConstraintVariable.always)); + expect(decoratedType.node.nullable, same(ConstraintVariable.always)); } test_interfaceType_typeParameter() async { @@ -787,10 +801,10 @@ var decoratedListType = decoratedTypeAnnotation('List<int>'); expect(decoratedFunctionType('f').positionalParameters[0], same(decoratedListType)); - expect(decoratedListType.nullable, isNotNull); + expect(decoratedListType.node.nullable, isNotNull); var decoratedIntType = decoratedTypeAnnotation('int'); expect(decoratedListType.typeArguments[0], same(decoratedIntType)); - expect(decoratedIntType.nullable, isNotNull); + expect(decoratedIntType.node.nullable, isNotNull); } test_topLevelFunction_parameterType_implicit_dynamic() async { @@ -802,7 +816,7 @@ expect(decoratedFunctionType('f').positionalParameters[0], same(decoratedType)); expect(decoratedType.type.isDynamic, isTrue); - expect(decoratedType.nullable, same(ConstraintVariable.always)); + expect(decoratedType.node.nullable, same(ConstraintVariable.always)); } test_topLevelFunction_parameterType_named_no_default() async { @@ -812,10 +826,9 @@ var decoratedType = decoratedTypeAnnotation('String'); var functionType = decoratedFunctionType('f'); expect(functionType.namedParameters['s'], same(decoratedType)); - expect(decoratedType.nullable, isNotNull); - expect(decoratedType.nullable, isNot(same(ConstraintVariable.always))); - expect(functionType.namedParameterOptionalVariables['s'], - same(decoratedType.nullable)); + expect(decoratedType.node.nullable, isNotNull); + expect(decoratedType.node.nullable, isNot(same(ConstraintVariable.always))); + expect(functionType.namedParameters['s'].node.isPossiblyOptional, true); } test_topLevelFunction_parameterType_named_no_default_required() async { @@ -827,9 +840,9 @@ var decoratedType = decoratedTypeAnnotation('String'); var functionType = decoratedFunctionType('f'); expect(functionType.namedParameters['s'], same(decoratedType)); - expect(decoratedType.nullable, isNotNull); - expect(decoratedType.nullable, isNot(same(ConstraintVariable.always))); - expect(functionType.namedParameterOptionalVariables['s'], isNull); + expect(decoratedType.node.nullable, isNotNull); + expect(decoratedType.node.nullable, isNot(same(ConstraintVariable.always))); + expect(functionType.namedParameters['s'].node.isPossiblyOptional, false); } test_topLevelFunction_parameterType_named_with_default() async { @@ -839,9 +852,8 @@ var decoratedType = decoratedTypeAnnotation('String'); var functionType = decoratedFunctionType('f'); expect(functionType.namedParameters['s'], same(decoratedType)); - expect(decoratedType.nullable, isNotNull); - expect(functionType.namedParameterOptionalVariables['s'], - same(ConstraintVariable.always)); + expect(decoratedType.node.nullable, isNotNull); + expect(functionType.namedParameters['s'].node.isPossiblyOptional, false); } test_topLevelFunction_parameterType_positionalOptional() async { @@ -851,7 +863,7 @@ var decoratedType = decoratedTypeAnnotation('int'); expect(decoratedFunctionType('f').positionalParameters[0], same(decoratedType)); - expect(decoratedType.nullable, isNotNull); + expect(decoratedType.node.nullable, isNotNull); } test_topLevelFunction_parameterType_simple() async { @@ -861,8 +873,8 @@ var decoratedType = decoratedTypeAnnotation('int'); expect(decoratedFunctionType('f').positionalParameters[0], same(decoratedType)); - expect(decoratedType.nullable, isNotNull); - expect(decoratedType.nonNullIntent, isNotNull); + expect(decoratedType.node.nullable, isNotNull); + expect(decoratedType.node.nonNullIntent, isNotNull); } test_topLevelFunction_returnType_implicit_dynamic() async { @@ -871,7 +883,7 @@ '''); var decoratedType = decoratedFunctionType('f').returnType; expect(decoratedType.type.isDynamic, isTrue); - expect(decoratedType.nullable, same(ConstraintVariable.always)); + expect(decoratedType.node.nullable, same(ConstraintVariable.always)); } test_topLevelFunction_returnType_simple() async { @@ -880,7 +892,7 @@ '''); var decoratedType = decoratedTypeAnnotation('int'); expect(decoratedFunctionType('f').returnType, same(decoratedType)); - expect(decoratedType.nullable, isNotNull); + expect(decoratedType.node.nullable, isNotNull); } } @@ -907,7 +919,7 @@ return _variables.decoratedTypeAnnotation(findNode.typeAnnotation(text)); } - ConstraintVariable possiblyOptionalParameter(String text) { + NullabilityNode possiblyOptionalParameter(String text) { return _variables .possiblyOptionalParameter(findNode.defaultParameter(text)); } @@ -988,7 +1000,7 @@ final _expressionChecks = <Expression, ExpressionChecks>{}; - final _possiblyOptional = <DefaultFormalParameter, ConstraintVariable>{}; + final _possiblyOptional = <DefaultFormalParameter, NullabilityNode>{}; /// Gets the [ExpressionChecks] associated with the given [expression]. ExpressionChecks checkExpression(Expression expression) => @@ -1006,10 +1018,9 @@ DecoratedType decoratedTypeAnnotation(TypeAnnotation typeAnnotation) => _decoratedTypeAnnotations[typeAnnotation]; - /// Gets the [ConstraintVariable] associated with the possibility that + /// Gets the [NullabilityNode] associated with the possibility that /// [parameter] may be optional. - ConstraintVariable possiblyOptionalParameter( - DefaultFormalParameter parameter) => + NullabilityNode possiblyOptionalParameter(DefaultFormalParameter parameter) => _possiblyOptional[parameter]; @override @@ -1038,10 +1049,10 @@ } @override - void recordPossiblyOptional(Source source, DefaultFormalParameter parameter, - ConstraintVariable variable) { - _possiblyOptional[parameter] = variable; - super.recordPossiblyOptional(source, parameter, variable); + void recordPossiblyOptional( + Source source, DefaultFormalParameter parameter, NullabilityNode node) { + _possiblyOptional[parameter] = node; + super.recordPossiblyOptional(source, parameter, node); } /// Unwraps any parentheses surrounding [expression].
diff --git a/pkg/analysis_server/test/src/nullability/provisional_api_test.dart b/pkg/analysis_server/test/src/nullability/provisional_api_test.dart index 1698262..d96f84d 100644 --- a/pkg/analysis_server/test/src/nullability/provisional_api_test.dart +++ b/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
@@ -368,6 +368,31 @@ NamedNoDefaultParameterHeuristic.assumeNullable)); } + test_named_parameter_no_default_unused_option2_assume_nullable_propagate() async { + var content = ''' +void f(String s) {} +void g({String s}) { + f(s); +} +main() { + g(); +} +'''; + var expected = ''' +void f(String? s) {} +void g({String? s}) { + f(s); +} +main() { + g(); +} +'''; + await _checkSingleFileChanges(content, expected, + assumptions: NullabilityMigrationAssumptions( + namedNoDefaultParameterHeuristic: + NamedNoDefaultParameterHeuristic.assumeNullable)); + } + test_named_parameter_no_default_unused_option2_assume_required() async { var content = ''' void f({String s}) {} @@ -387,6 +412,31 @@ NamedNoDefaultParameterHeuristic.assumeRequired)); } + test_named_parameter_no_default_unused_option2_assume_required_propagate() async { + var content = ''' +void f(String s) {} +void g({String s}) { + f(s); +} +main() { + g(); +} +'''; + var expected = ''' +void f(String? s) {} +void g({String? s}) { + f(s); +} +main() { + g(); +} +'''; + await _checkSingleFileChanges(content, expected, + assumptions: NullabilityMigrationAssumptions( + namedNoDefaultParameterHeuristic: + NamedNoDefaultParameterHeuristic.assumeRequired)); + } + test_named_parameter_no_default_unused_required_option2_assume_nullable() async { // The `@required` annotation overrides the assumption of nullability. // The call at `f()` is presumed to be in error. @@ -455,6 +505,31 @@ NamedNoDefaultParameterHeuristic.assumeNullable)); } + test_named_parameter_no_default_used_non_null_option2_assume_nullable_propagate() async { + var content = ''' +void f(String s) {} +void g({String s}) { + f(s); +} +main() { + g(s: 'x'); +} +'''; + var expected = ''' +void f(String? s) {} +void g({String? s}) { + f(s); +} +main() { + g(s: 'x'); +} +'''; + await _checkSingleFileChanges(content, expected, + assumptions: NullabilityMigrationAssumptions( + namedNoDefaultParameterHeuristic: + NamedNoDefaultParameterHeuristic.assumeNullable)); + } + test_named_parameter_no_default_used_non_null_option2_assume_required() async { var content = ''' void f({String s}) {} @@ -463,6 +538,7 @@ } '''; var expected = ''' +import 'package:meta/meta.dart'; void f({@required String s}) {} main() { f(s: 'x'); @@ -474,6 +550,32 @@ NamedNoDefaultParameterHeuristic.assumeRequired)); } + test_named_parameter_no_default_used_non_null_option2_assume_required_propagate() async { + var content = ''' +void f(String s) {} +void g({String s}) { + f(s); +} +main() { + g(s: 'x'); +} +'''; + var expected = ''' +import 'package:meta/meta.dart'; +void f(String s) {} +void g({@required String s}) { + f(s); +} +main() { + g(s: 'x'); +} +'''; + await _checkSingleFileChanges(content, expected, + assumptions: NullabilityMigrationAssumptions( + namedNoDefaultParameterHeuristic: + NamedNoDefaultParameterHeuristic.assumeRequired)); + } + test_named_parameter_no_default_used_non_null_required_option2_assume_required() async { // Even if we are using the "assumeRequired" heuristic, we should not add a // duplicate `@required` annotation.
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart new file mode 100644 index 0000000..597c353 --- /dev/null +++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
@@ -0,0 +1,190 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analysis_server/src/services/correction/assist.dart'; +import 'package:analyzer/src/dart/analysis/experiments.dart'; +import 'package:analyzer_plugin/utilities/assist/assist.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import 'assist_processor.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(ConvertToIfElementTest); + }); +} + +@reflectiveTest +class ConvertToIfElementTest extends AssistProcessorTest { + @override + AssistKind get kind => DartAssistKind.CONVERT_TO_FOR_ELEMENT; + + void setUp() { + createAnalysisOptionsFile( + experiments: [EnableString.control_flow_collections]); + super.setUp(); + } + + test_mapFromIterable_complexKey() async { + await resolveTestUnit(''' +f(Iterable<int> i) { + return Map.fromIt/*caret*/erable(i, key: (e) { + var result = e * 2; + return result; + }, value: (e) => e + 3); +} +'''); + await assertNoAssist(); + } + + test_mapFromIterable_complexValue() async { + await resolveTestUnit(''' +f(Iterable<int> i) { + return Map.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) { + var result = e + 3; + return result; + }); +} +'''); + await assertNoAssist(); + } + + test_mapFromIterable_differentParameterNames_usedInKey_conflictInValue() async { + await resolveTestUnit(''' +f(Iterable<int> i) { + var k = 3; + return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => k); +} +'''); + await assertHasAssist(''' +f(Iterable<int> i) { + var k = 3; + return { for (var e in i) e * 2 : k }; +} +'''); + } + + test_mapFromIterable_differentParameterNames_usedInKey_noConflictInValue() async { + await resolveTestUnit(''' +f(Iterable<int> i) { + return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => 0); +} +'''); + await assertHasAssist(''' +f(Iterable<int> i) { + return { for (var k in i) k * 2 : 0 }; +} +'''); + } + + test_mapFromIterable_differentParameterNames_usedInKeyAndValue_conflictWithDefault() async { + await resolveTestUnit(''' +f(Iterable<int> i) { + var e = 2; + return Map.fromIt/*caret*/erable(i, key: (k) => k * e, value: (v) => v + e); +} +'''); + await assertHasAssist(''' +f(Iterable<int> i) { + var e = 2; + return { for (var e1 in i) e1 * e : e1 + e }; +} +'''); + } + + test_mapFromIterable_differentParameterNames_usedInKeyAndValue_noConflictWithDefault() async { + await resolveTestUnit(''' +f(Iterable<int> i) { + return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => v + 3); +} +'''); + await assertHasAssist(''' +f(Iterable<int> i) { + return { for (var e in i) e * 2 : e + 3 }; +} +'''); + } + + test_mapFromIterable_differentParameterNames_usedInValue_conflictInKey() async { + await resolveTestUnit(''' +f(Iterable<int> i) { + int v = 0; + return Map.fromIt/*caret*/erable(i, key: (k) => v++, value: (v) => v * 10); +} +'''); + await assertHasAssist(''' +f(Iterable<int> i) { + int v = 0; + return { for (var e in i) v++ : e * 10 }; +} +'''); + } + + test_mapFromIterable_differentParameterNames_usedInValue_noConflictInKey() async { + await resolveTestUnit(''' +f(Iterable<int> i) { + int index = 0; + return Map.fromIt/*caret*/erable(i, key: (k) => index++, value: (v) => v * 10); +} +'''); + await assertHasAssist(''' +f(Iterable<int> i) { + int index = 0; + return { for (var v in i) index++ : v * 10 }; +} +'''); + } + + test_mapFromIterable_missingKey() async { + await resolveTestUnit(''' +f(Iterable<int> i) { + return Map.fromIt/*caret*/erable(i, value: (e) => e + 3); +} +'''); + await assertNoAssist(); + } + + test_mapFromIterable_missingKeyAndValue() async { + await resolveTestUnit(''' +f(Iterable<int> i) { + return Map.fromIt/*caret*/erable(i); +} +'''); + await assertNoAssist(); + } + + test_mapFromIterable_missingValue() async { + await resolveTestUnit(''' +f(Iterable<int> i) { + return Map.fromIt/*caret*/erable(i, key: (e) => e * 2); +} +'''); + await assertNoAssist(); + } + + test_mapFromIterable_notMapFromIterable() async { + await resolveTestUnit(''' +f(Iterable<int> i) { + return A.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) => e + 3); +} +class A { + A.fromIterable(i, {key, value}); +} +'''); + await assertNoAssist(); + } + + test_mapFromIterable_sameParameterNames() async { + await resolveTestUnit(''' +f(Iterable<int> i) { + return Map.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) => e + 3); +} +'''); + await assertHasAssist(''' +f(Iterable<int> i) { + return { for (var e in i) e * 2 : e + 3 }; +} +'''); + } +}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart index 8d8e3ef..5caae77 100644 --- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart +++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart
@@ -39,6 +39,19 @@ '''); } + test_conditional_list_caret_at_start_of_expression() async { + await resolveTestUnit(''' +f(bool b) { + return ['a', /*caret*/b ? 'c' : 'd', 'e']; +} +'''); + await assertHasAssist(''' +f(bool b) { + return ['a', if (b) 'c' else 'd', 'e']; +} +'''); + } + test_conditional_list_withParentheses() async { await resolveTestUnit(''' f(bool b) { @@ -104,166 +117,4 @@ } '''); } - - test_mapFromIterable_complexKey() async { - await resolveTestUnit(''' -f(Iterable<int> i) { - return Map.fromIt/*caret*/erable(i, key: (e) { - var result = e * 2; - return result; - }, value: (e) => e + 3); -} -'''); - await assertNoAssist(); - } - - test_mapFromIterable_complexValue() async { - await resolveTestUnit(''' -f(Iterable<int> i) { - return Map.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) { - var result = e + 3; - return result; - }); -} -'''); - await assertNoAssist(); - } - - test_mapFromIterable_differentParameterNames_usedInKey_conflictInValue() async { - await resolveTestUnit(''' -f(Iterable<int> i) { - var k = 3; - return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => k); -} -'''); - await assertHasAssist(''' -f(Iterable<int> i) { - var k = 3; - return { for (var e in i) e * 2 : k }; -} -'''); - } - - test_mapFromIterable_differentParameterNames_usedInKey_noConflictInValue() async { - await resolveTestUnit(''' -f(Iterable<int> i) { - return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => 0); -} -'''); - await assertHasAssist(''' -f(Iterable<int> i) { - return { for (var k in i) k * 2 : 0 }; -} -'''); - } - - test_mapFromIterable_differentParameterNames_usedInKeyAndValue_conflictWithDefault() async { - await resolveTestUnit(''' -f(Iterable<int> i) { - var e = 2; - return Map.fromIt/*caret*/erable(i, key: (k) => k * e, value: (v) => v + e); -} -'''); - await assertHasAssist(''' -f(Iterable<int> i) { - var e = 2; - return { for (var e1 in i) e1 * e : e1 + e }; -} -'''); - } - - test_mapFromIterable_differentParameterNames_usedInKeyAndValue_noConflictWithDefault() async { - await resolveTestUnit(''' -f(Iterable<int> i) { - return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => v + 3); -} -'''); - await assertHasAssist(''' -f(Iterable<int> i) { - return { for (var e in i) e * 2 : e + 3 }; -} -'''); - } - - test_mapFromIterable_differentParameterNames_usedInValue_conflictInKey() async { - await resolveTestUnit(''' -f(Iterable<int> i) { - int v = 0; - return Map.fromIt/*caret*/erable(i, key: (k) => v++, value: (v) => v * 10); -} -'''); - await assertHasAssist(''' -f(Iterable<int> i) { - int v = 0; - return { for (var e in i) v++ : e * 10 }; -} -'''); - } - - test_mapFromIterable_differentParameterNames_usedInValue_noConflictInKey() async { - await resolveTestUnit(''' -f(Iterable<int> i) { - int index = 0; - return Map.fromIt/*caret*/erable(i, key: (k) => index++, value: (v) => v * 10); -} -'''); - await assertHasAssist(''' -f(Iterable<int> i) { - int index = 0; - return { for (var v in i) index++ : v * 10 }; -} -'''); - } - - test_mapFromIterable_missingKey() async { - await resolveTestUnit(''' -f(Iterable<int> i) { - return Map.fromIt/*caret*/erable(i, value: (e) => e + 3); -} -'''); - await assertNoAssist(); - } - - test_mapFromIterable_missingKeyAndValue() async { - await resolveTestUnit(''' -f(Iterable<int> i) { - return Map.fromIt/*caret*/erable(i); -} -'''); - await assertNoAssist(); - } - - test_mapFromIterable_missingValue() async { - await resolveTestUnit(''' -f(Iterable<int> i) { - return Map.fromIt/*caret*/erable(i, key: (e) => e * 2); -} -'''); - await assertNoAssist(); - } - - test_mapFromIterable_notMapFromIterable() async { - await resolveTestUnit(''' -f(Iterable<int> i) { - return A.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) => e + 3); -} -class A { - A.fromIterable(i, {key, value}); -} -'''); - await assertNoAssist(); - } - - test_mapFromIterable_sameParameterNames() async { - await resolveTestUnit(''' -f(Iterable<int> i) { - return Map.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) => e + 3); -} -'''); - await assertHasAssist(''' -f(Iterable<int> i) { - return { for (var e in i) e * 2 : e + 3 }; -} -'''); - } }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart index 648502f..d026fb3 100644 --- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart +++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
@@ -41,6 +41,21 @@ '''); } + test_addAll_expression_to_emptyList() async { + await resolveTestUnit(''' +f() { + var ints = [1, 2, 3]; + print([]..addAl/*caret*/l(ints.map((i) => i.toString()))..addAll(['c'])); +} +'''); + await assertHasAssist(''' +f() { + var ints = [1, 2, 3]; + print([...ints.map((i) => i.toString())]..addAll(['c'])); +} +'''); + } + test_addAll_literal() async { await resolveTestUnit(''' var l = ['a']..add/*caret*/All(['b'])..addAll(['c']);
diff --git a/pkg/analysis_server/test/src/services/correction/assist/test_all.dart b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart index 9bba973..bcf631e 100644 --- a/pkg/analysis_server/test/src/services/correction/assist/test_all.dart +++ b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
@@ -26,6 +26,7 @@ import 'convert_to_double_quoted_string_test.dart' as convert_to_double_quoted_string; import 'convert_to_field_parameter_test.dart' as convert_to_field_parameter; +import 'convert_to_for_element_test.dart' as convert_to_for_element; import 'convert_to_if_element_test.dart' as convert_to_if_element; import 'convert_to_int_literal_test.dart' as convert_to_int_literal; import 'convert_to_list_literal_test.dart' as convert_to_list_literal; @@ -96,6 +97,7 @@ convert_part_of_to_uri.main(); convert_to_double_quoted_string.main(); convert_to_field_parameter.main(); + convert_to_for_element.main(); convert_to_if_element.main(); convert_to_int_literal.main(); convert_to_list_literal.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart new file mode 100644 index 0000000..5a19c8b --- /dev/null +++ b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart
@@ -0,0 +1,122 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analysis_server/plugin/edit/fix/fix_core.dart'; +import 'package:analysis_server/src/protocol_server.dart' show SourceEdit; +import 'package:analysis_server/src/services/correction/fix/analysis_options/fix_generator.dart'; +import 'package:analyzer/error/error.dart' as engine; +import 'package:analyzer/file_system/file_system.dart'; +import 'package:analyzer/src/analysis_options/analysis_options_provider.dart'; +import 'package:analyzer/src/generated/source.dart'; +import 'package:analyzer/src/task/options.dart'; +import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart'; +import 'package:analyzer_plugin/protocol/protocol_common.dart' + show SourceFileEdit; +import 'package:analyzer_plugin/protocol/protocol_common.dart'; +import 'package:test/test.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; +import 'package:yaml/src/yaml_node.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(RemoveSettingTest); + }); +} + +class NonDartFixTest with ResourceProviderMixin { + Future<void> assertHasFix( + String initialContent, String location, String expectedContent) async { + File optionsFile = resourceProvider.getFile('/analysis_options.yaml'); + SourceFactory sourceFactory = new SourceFactory([]); + List<engine.AnalysisError> errors = analyzeAnalysisOptions( + optionsFile.createSource(), initialContent, sourceFactory); + expect(errors, hasLength(1)); + engine.AnalysisError error = errors[0]; + YamlMap options = _getOptions(sourceFactory, initialContent); + AnalysisOptionsFixGenerator generator = + new AnalysisOptionsFixGenerator(error, initialContent, options); + List<Fix> fixes = await generator.computeFixes(); + expect(fixes, hasLength(1)); + List<SourceFileEdit> fileEdits = fixes[0].change.edits; + expect(fileEdits, hasLength(1)); + + String actualContent = + SourceEdit.applySequence(initialContent, fileEdits[0].edits); + expect(actualContent, expectedContent); + } + + YamlMap _getOptions(SourceFactory sourceFactory, String content) { + AnalysisOptionsProvider optionsProvider = + new AnalysisOptionsProvider(sourceFactory); + try { + return optionsProvider.getOptionsFromString(content); + } on OptionsFormatException { + return null; + } + } +} + +@reflectiveTest +class RemoveSettingTest extends NonDartFixTest { + test_enableSuperMixins() async { + await assertHasFix( + ''' +analyzer: + enable-experiment: + - non-nullable + language: + enableSuperMixins: true +''', + 'enable', + ''' +analyzer: + enable-experiment: + - non-nullable +'''); + } + + test_invalidExperiment_first() async { + await assertHasFix( + ''' +analyzer: + enable-experiment: + - not-an-experiment + - non-nullable +''', + 'not-', + ''' +analyzer: + enable-experiment: + - non-nullable +'''); + } + + test_invalidExperiment_last() async { + await assertHasFix( + ''' +analyzer: + enable-experiment: + - non-nullable + - not-an-experiment +''', + 'not-', + ''' +analyzer: + enable-experiment: + - non-nullable +'''); + } + + test_invalidExperiment_only() async { + await assertHasFix( + ''' +analyzer: + enable-experiment: + - not-an-experiment +''', + 'not-', + ''' +'''); + } +}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_all.dart new file mode 100644 index 0000000..c202ee9 --- /dev/null +++ b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_all.dart
@@ -0,0 +1,13 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import 'remove_setting_test.dart' as remove_setting; + +main() { + defineReflectiveSuite(() { + remove_setting.main(); + }); +}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_argument_name_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_argument_name_test.dart index b24488f..2707a41 100644 --- a/pkg/analysis_server/test/src/services/correction/fix/change_argument_name_test.dart +++ b/pkg/analysis_server/test/src/services/correction/fix/change_argument_name_test.dart
@@ -117,6 +117,23 @@ '''); } + test_default_annotation() async { + await resolveTestUnit(''' +@A(boot: 2) +f() => null; +class A { + const A({int boat}); +} +'''); + await assertHasFix(''' +@A(boat: 2) +f() => null; +class A { + const A({int boat}); +} +'''); + } + test_default_constructor() async { await resolveTestUnit(''' f() => new A(boot: 2); @@ -166,6 +183,40 @@ '''); } + test_default_redirectingConstructor() async { + await resolveTestUnit(''' +class A { + A.one() : this.two(boot: 3); + A.two({int boat}); +} +'''); + await assertHasFix(''' +class A { + A.one() : this.two(boat: 3); + A.two({int boat}); +} +'''); + } + + test_default_superConstructor() async { + await resolveTestUnit(''' +class A { + A.a({int boat}); +} +class B extends A { + B.b() : super.a(boot: 3); +} +'''); + await assertHasFix(''' +class A { + A.a({int boat}); +} +class B extends A { + B.b() : super.a(boat: 3); +} +'''); + } + test_tooDistant_constructor() async { await resolveTestUnit(''' f() => new A(bbbbb: 2);
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart index e9b5fa2..beb7025 100644 --- a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart +++ b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
@@ -64,9 +64,13 @@ Future<void> assertHasFix(String expected, {bool Function(AnalysisError) errorFilter, int length, - String target}) async { + String target, + int expectedNumberOfFixesForKind, + String matchFixMessage}) async { AnalysisError error = await _findErrorToFix(errorFilter, length: length); - Fix fix = await _assertHasFix(error); + Fix fix = await _assertHasFix(error, + expectedNumberOfFixesForKind: expectedNumberOfFixesForKind, + matchFixMessage: matchFixMessage); change = fix.change; // apply to "file" @@ -148,12 +152,38 @@ verifyNoTestUnitErrors = false; } - /// Computes fixes and verifies that there is a fix for the given [error] of - /// the appropriate kind. - Future<Fix> _assertHasFix(AnalysisError error) async { + /// Computes fixes and verifies that there is a fix for the given [error] of the appropriate kind. + /// Optionally, if a [matchFixMessage] is passed, then the kind as well as the fix message must + /// match to be returned. + Future<Fix> _assertHasFix(AnalysisError error, + {int expectedNumberOfFixesForKind, String matchFixMessage}) async { // Compute the fixes for this AnalysisError final List<Fix> fixes = await _computeFixes(error); + if (expectedNumberOfFixesForKind != null) { + int actualNumberOfFixesForKind = 0; + for (Fix fix in fixes) { + if (fix.kind == kind) { + actualNumberOfFixesForKind++; + } + } + if (actualNumberOfFixesForKind != expectedNumberOfFixesForKind) { + fail( + "Expected $expectedNumberOfFixesForKind fixes of kind $kind, but found $actualNumberOfFixesForKind:\n${fixes.join('\n')}"); + } + } + + // If a matchFixMessage was provided, + if (matchFixMessage != null) { + for (Fix fix in fixes) { + if (matchFixMessage == fix?.change?.message) { + return fix; + } + } + fail( + 'Expected to find fix $kind with name $matchFixMessage in\n${fixes.join('\n')}'); + } + // Assert that none of the fixes are a fix-all fix. Fix foundFix = null; for (Fix fix in fixes) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart index 08bf63e..f1d1710 100644 --- a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart +++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
@@ -65,7 +65,7 @@ Test test = null; print(test); } -'''); +''', expectedNumberOfFixesForKind: 1); } test_preferDirectOverExport_src() async { @@ -83,7 +83,65 @@ Test test = null; print(test); } +''', expectedNumberOfFixesForKind: 1); + } + + test_relativeDirective() async { + addSource('/home/test/lib/a.dart', ''' +import "b.dart"; '''); + addSource('/home/test/lib/b.dart', ''' +class Foo {} +'''); + await resolveTestUnit(''' +main() { new Foo(); } +'''); + await assertHasFix(''' +import 'b.dart'; + +main() { new Foo(); } +''', + expectedNumberOfFixesForKind: 2, + matchFixMessage: "Import library 'b.dart'"); + } + + test_relativeDirective_upOneDirectory() async { + addSource('/home/test/lib/a.dart', ''' +import "b.dart"; +'''); + addSource('/home/test/lib/b.dart', ''' +class Foo {} +'''); + testFile = convertPath('/home/test/lib/dir/test.dart'); + await resolveTestUnit(''' +main() { new Foo(); } +'''); + await assertHasFix(''' +import '../b.dart'; + +main() { new Foo(); } +''', + expectedNumberOfFixesForKind: 2, + matchFixMessage: "Import library '../b.dart'"); + } + + test_relativeDirective_downOneDirectory() async { + addSource('/home/test/lib/dir/a.dart', ''' +import "b.dart"; +'''); + addSource('/home/test/lib/dir/b.dart', ''' +class Foo {} +'''); + await resolveTestUnit(''' +main() { new Foo(); } +'''); + await assertHasFix(''' +import 'dir/b.dart'; + +main() { new Foo(); } +''', + expectedNumberOfFixesForKind: 2, + matchFixMessage: "Import library 'dir/b.dart'"); } test_withClass_annotation() async {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_empty_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_empty_test.dart new file mode 100644 index 0000000..ef13aa9 --- /dev/null +++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_empty_test.dart
@@ -0,0 +1,103 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analysis_server/src/services/correction/fix.dart'; +import 'package:analysis_server/src/services/correction/fix_internal.dart'; +import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import 'fix_processor.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(ReplaceWithIsEmptyTest); + }); +} + +@reflectiveTest +class ReplaceWithIsEmptyTest extends FixProcessorLintTest { + @override + FixKind get kind => DartFixKind.REPLACE_WITH_IS_EMPTY; + + @override + String get lintCode => LintNames.prefer_is_empty; + + test_constantOnLeft_equal() async { + await resolveTestUnit(''' +f(List c) { + if (/*LINT*/0 == c.length) {} +} +'''); + await assertHasFix(''' +f(List c) { + if (/*LINT*/c.isEmpty) {} +} +'''); + } + + test_constantOnLeft_greaterThan() async { + await resolveTestUnit(''' +f(List c) { + if (/*LINT*/1 > c.length) {} +} +'''); + await assertHasFix(''' +f(List c) { + if (/*LINT*/c.isEmpty) {} +} +'''); + } + + test_constantOnLeft_greaterThanOrEqual() async { + await resolveTestUnit(''' +f(List c) { + if (/*LINT*/0 >= c.length) {} +} +'''); + await assertHasFix(''' +f(List c) { + if (/*LINT*/c.isEmpty) {} +} +'''); + } + + test_constantOnRight_equal() async { + await resolveTestUnit(''' +f(List c) { + if (/*LINT*/c.length == 0) {} +} +'''); + await assertHasFix(''' +f(List c) { + if (/*LINT*/c.isEmpty) {} +} +'''); + } + + test_constantOnRight_lessThan() async { + await resolveTestUnit(''' +f(List c) { + if (/*LINT*/c.length < 1) {} +} +'''); + await assertHasFix(''' +f(List c) { + if (/*LINT*/c.isEmpty) {} +} +'''); + } + + test_constantOnRight_lessThanOrEqual() async { + await resolveTestUnit(''' +f(List c) { + if (/*LINT*/c.length <= 0) {} +} +'''); + await assertHasFix(''' +f(List c) { + if (/*LINT*/c.isEmpty) {} +} +'''); + } +}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_not_empty_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_not_empty_test.dart new file mode 100644 index 0000000..9b621d9 --- /dev/null +++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_not_empty_test.dart
@@ -0,0 +1,77 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analysis_server/src/services/correction/fix.dart'; +import 'package:analysis_server/src/services/correction/fix_internal.dart'; +import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import 'fix_processor.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(ReplaceWithIsNotEmptyTest); + }); +} + +@reflectiveTest +class ReplaceWithIsNotEmptyTest extends FixProcessorLintTest { + @override + FixKind get kind => DartFixKind.REPLACE_WITH_IS_NOT_EMPTY; + + @override + String get lintCode => LintNames.prefer_is_empty; + + test_constantOnLeft_lessThanOrEqual() async { + await resolveTestUnit(''' +f(List c) { + if (/*LINT*/1 <= c.length) {} +} +'''); + await assertHasFix(''' +f(List c) { + if (/*LINT*/c.isNotEmpty) {} +} +'''); + } + + test_constantOnLeft_notEqual() async { + await resolveTestUnit(''' +f(List c) { + if (/*LINT*/0 != c.length) {} +} +'''); + await assertHasFix(''' +f(List c) { + if (/*LINT*/c.isNotEmpty) {} +} +'''); + } + + test_constantOnRight_greaterThanOrEqual() async { + await resolveTestUnit(''' +f(List c) { + if (/*LINT*/c.length >= 1) {} +} +'''); + await assertHasFix(''' +f(List c) { + if (/*LINT*/c.isNotEmpty) {} +} +'''); + } + + test_constantOnRight_notEqual() async { + await resolveTestUnit(''' +f(List c) { + if (/*LINT*/c.length != 0) {} +} +'''); + await assertHasFix(''' +f(List c) { + if (/*LINT*/c.isNotEmpty) {} +} +'''); + } +}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart index e9ea84e..de8cd2a 100644 --- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart +++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -23,6 +23,7 @@ import 'add_static_test.dart' as add_static; import 'add_super_constructor_invocation_test.dart' as add_super_constructor_invocation; +import 'analysis_options/test_all.dart' as analysis_options; import 'change_argument_name_test.dart' as change_argument_name; import 'change_to_nearest_precise_value_test.dart' as change_to_nearest_precise_value; @@ -95,6 +96,8 @@ import 'replace_with_conditional_assignment_test.dart' as replace_with_conditional_assignment; import 'replace_with_identifier_test.dart' as replace_with_identifier; +import 'replace_with_is_empty_test.dart' as replace_with_is_empty; +import 'replace_with_is_not_empty_test.dart' as replace_with_is_not_empty; import 'replace_with_null_aware_test.dart' as replace_with_null_aware; import 'replace_with_tear_off_test.dart' as replace_with_tear_off; import 'update_sdk_constraints_test.dart' as update_sdk_constraints; @@ -122,6 +125,7 @@ add_required.main(); add_static.main(); add_super_constructor_invocation.main(); + analysis_options.main(); change_argument_name.main(); change_to.main(); change_to_nearest_precise_value.main(); @@ -188,6 +192,8 @@ replace_with_brackets.main(); replace_with_conditional_assignment.main(); replace_with_identifier.main(); + replace_with_is_empty.main(); + replace_with_is_not_empty.main(); replace_with_null_aware.main(); replace_with_tear_off.main(); update_sdk_constraints.main();
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java index 1ad467a..da73811 100644 --- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java +++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -624,8 +624,12 @@ * * @param file The file in which the specified elements are to be made accessible. * @param elements The elements to be made accessible in the specified file. + * @param offset The offset at which the specified elements need to be made accessible. If + * provided, this is used to guard against adding imports for text that would be inserted + * into a comment, string literal, or other location where the imports would not be + * necessary. */ - public void edit_importElements(String file, List<ImportedElements> elements, ImportElementsConsumer consumer); + public void edit_importElements(String file, List<ImportedElements> elements, int offset, ImportElementsConsumer consumer); /** * {@code edit.isPostfixCompletionApplicable}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java b/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java index 183ba52..071328a 100644 --- a/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java +++ b/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java
@@ -36,17 +36,20 @@ public static final List<TokenDetails> EMPTY_LIST = Lists.newArrayList(); /** - * The raw token text. + * The token's lexeme. */ private final String lexeme; /** - * The type of this token. + * A unique id for the type of the identifier. Omitted if the token is not an identifier in a + * reference position. */ private final String type; /** - * The kinds of elements which could validly replace this token. + * An indication of whether this token is in a declaration or reference position. (If no other + * purpose is found for this field then it should be renamed and converted to a boolean value.) + * Omitted if the token is not an identifier. */ private final List<String> validElementKinds; @@ -73,7 +76,7 @@ public static TokenDetails fromJson(JsonObject jsonObject) { String lexeme = jsonObject.get("lexeme").getAsString(); - String type = jsonObject.get("type").getAsString(); + String type = jsonObject.get("type") == null ? null : jsonObject.get("type").getAsString(); List<String> validElementKinds = jsonObject.get("validElementKinds") == null ? null : JsonUtilities.decodeStringList(jsonObject.get("validElementKinds").getAsJsonArray()); return new TokenDetails(lexeme, type, validElementKinds); } @@ -91,21 +94,24 @@ } /** - * The raw token text. + * The token's lexeme. */ public String getLexeme() { return lexeme; } /** - * The type of this token. + * A unique id for the type of the identifier. Omitted if the token is not an identifier in a + * reference position. */ public String getType() { return type; } /** - * The kinds of elements which could validly replace this token. + * An indication of whether this token is in a declaration or reference position. (If no other + * purpose is found for this field then it should be renamed and converted to a boolean value.) + * Omitted if the token is not an identifier. */ public List<String> getValidElementKinds() { return validElementKinds; @@ -123,7 +129,9 @@ public JsonObject toJson() { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("lexeme", lexeme); - jsonObject.addProperty("type", type); + if (type != null) { + jsonObject.addProperty("type", type); + } if (validElementKinds != null) { JsonArray jsonArrayValidElementKinds = new JsonArray(); for (String elt : validElementKinds) {
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html index edbcba3..56f1243 100644 --- a/pkg/analysis_server/tool/spec/spec_input.html +++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -7,7 +7,7 @@ <body> <h1>Analysis Server API Specification</h1> <h1 style="color:#999999">Version - <version>1.25.0</version> + <version>1.26.0</version> </h1> <p> This document contains a specification of the API provided by the @@ -2534,15 +2534,26 @@ The elements to be made accessible in the specified file. </p> </field> + <field name="offset" optional="true"> + <ref>int</ref> + <p> + The offset at which the specified elements need to be made accessible. + If provided, this is used to guard against adding imports for text + that would be inserted into a comment, string literal, or other + location where the imports would not be necessary. + </p> + </field> </params> <result> <field name="edit" optional="true"> <ref>SourceFileEdit</ref> <p> - The edits to be applied in order to make the specified elements accessible. The file to be edited will be the - defining compilation unit of the library containing the file specified in the request, which can be different - than the file specified in the request if the specified file is a part file. This field will be omitted if - there are no edits that need to be applied. + The edits to be applied in order to make the specified elements + accessible. The file to be edited will be the defining compilation + unit of the library containing the file specified in the request, + which can be different than the file specified in the request if the + specified file is a part file. This field will be omitted if there are + no edits that need to be applied. </p> </field> </result> @@ -3892,13 +3903,14 @@ <field name="lexeme"> <ref>String</ref> <p> - The raw token text. + The token's lexeme. </p> </field> - <field name="type"> + <field name="type" optional="true"> <ref>String</ref> <p> - The type of this token. + A unique id for the type of the identifier. + Omitted if the token is not an identifier in a reference position. </p> </field> <field name="validElementKinds" optional="true"> @@ -3906,7 +3918,10 @@ <ref>String</ref> </list> <p> - The kinds of elements which could validly replace this token. + An indication of whether this token is in a declaration or reference + position. (If no other purpose is found for this field then it should + be renamed and converted to a boolean value.) + Omitted if the token is not an identifier. </p> </field> </object>
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart index 0125a30..35174b9 100644 --- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart +++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
@@ -6,7 +6,7 @@ // To regenerate the file, use the script // "pkg/analysis_server/tool/spec/generate_files". -const String PROTOCOL_VERSION = '1.25.0'; +const String PROTOCOL_VERSION = '1.26.0'; const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles'; const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories'; @@ -201,6 +201,7 @@ const String EDIT_REQUEST_IMPORT_ELEMENTS = 'edit.importElements'; const String EDIT_REQUEST_IMPORT_ELEMENTS_ELEMENTS = 'elements'; const String EDIT_REQUEST_IMPORT_ELEMENTS_FILE = 'file'; +const String EDIT_REQUEST_IMPORT_ELEMENTS_OFFSET = 'offset'; const String EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE = 'edit.isPostfixCompletionApplicable'; const String EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE_FILE = 'file';
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart index b9d94ce..5d1b076 100644 --- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart +++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
@@ -10303,6 +10303,7 @@ * { * "file": FilePath * "elements": List<ImportedElements> + * "offset": optional int * } * * Clients may not extend, implement or mix-in this class. @@ -10312,6 +10313,8 @@ List<ImportedElements> _elements; + int _offset; + /** * The file in which the specified elements are to be made accessible. */ @@ -10338,9 +10341,29 @@ this._elements = value; } - EditImportElementsParams(String file, List<ImportedElements> elements) { + /** + * The offset at which the specified elements need to be made accessible. If + * provided, this is used to guard against adding imports for text that would + * be inserted into a comment, string literal, or other location where the + * imports would not be necessary. + */ + int get offset => _offset; + + /** + * The offset at which the specified elements need to be made accessible. If + * provided, this is used to guard against adding imports for text that would + * be inserted into a comment, string literal, or other location where the + * imports would not be necessary. + */ + void set offset(int value) { + this._offset = value; + } + + EditImportElementsParams(String file, List<ImportedElements> elements, + {int offset}) { this.file = file; this.elements = elements; + this.offset = offset; } factory EditImportElementsParams.fromJson( @@ -10365,7 +10388,11 @@ } else { throw jsonDecoder.mismatch(jsonPath, "elements"); } - return new EditImportElementsParams(file, elements); + int offset; + if (json.containsKey("offset")) { + offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); + } + return new EditImportElementsParams(file, elements, offset: offset); } else { throw jsonDecoder.mismatch(jsonPath, "edit.importElements params", json); } @@ -10382,6 +10409,9 @@ result["file"] = file; result["elements"] = elements.map((ImportedElements value) => value.toJson()).toList(); + if (offset != null) { + result["offset"] = offset; + } return result; } @@ -10398,7 +10428,8 @@ if (other is EditImportElementsParams) { return file == other.file && listEqual(elements, other.elements, - (ImportedElements a, ImportedElements b) => a == b); + (ImportedElements a, ImportedElements b) => a == b) && + offset == other.offset; } return false; } @@ -10408,6 +10439,7 @@ int hash = 0; hash = JenkinsSmiHash.combine(hash, file.hashCode); hash = JenkinsSmiHash.combine(hash, elements.hashCode); + hash = JenkinsSmiHash.combine(hash, offset.hashCode); return JenkinsSmiHash.finish(hash); } } @@ -21541,7 +21573,7 @@ * * { * "lexeme": String - * "type": String + * "type": optional String * "validElementKinds": optional List<String> * } * @@ -21555,12 +21587,12 @@ List<String> _validElementKinds; /** - * The raw token text. + * The token's lexeme. */ String get lexeme => _lexeme; /** - * The raw token text. + * The token's lexeme. */ void set lexeme(String value) { assert(value != null); @@ -21568,31 +21600,38 @@ } /** - * The type of this token. + * A unique id for the type of the identifier. Omitted if the token is not an + * identifier in a reference position. */ String get type => _type; /** - * The type of this token. + * A unique id for the type of the identifier. Omitted if the token is not an + * identifier in a reference position. */ void set type(String value) { - assert(value != null); this._type = value; } /** - * The kinds of elements which could validly replace this token. + * An indication of whether this token is in a declaration or reference + * position. (If no other purpose is found for this field then it should be + * renamed and converted to a boolean value.) Omitted if the token is not an + * identifier. */ List<String> get validElementKinds => _validElementKinds; /** - * The kinds of elements which could validly replace this token. + * An indication of whether this token is in a declaration or reference + * position. (If no other purpose is found for this field then it should be + * renamed and converted to a boolean value.) Omitted if the token is not an + * identifier. */ void set validElementKinds(List<String> value) { this._validElementKinds = value; } - TokenDetails(String lexeme, String type, {List<String> validElementKinds}) { + TokenDetails(String lexeme, {String type, List<String> validElementKinds}) { this.lexeme = lexeme; this.type = type; this.validElementKinds = validElementKinds; @@ -21613,8 +21652,6 @@ String type; if (json.containsKey("type")) { type = jsonDecoder.decodeString(jsonPath + ".type", json["type"]); - } else { - throw jsonDecoder.mismatch(jsonPath, "type"); } List<String> validElementKinds; if (json.containsKey("validElementKinds")) { @@ -21623,8 +21660,8 @@ json["validElementKinds"], jsonDecoder.decodeString); } - return new TokenDetails(lexeme, type, - validElementKinds: validElementKinds); + return new TokenDetails(lexeme, + type: type, validElementKinds: validElementKinds); } else { throw jsonDecoder.mismatch(jsonPath, "TokenDetails", json); } @@ -21634,7 +21671,9 @@ Map<String, dynamic> toJson() { Map<String, dynamic> result = {}; result["lexeme"] = lexeme; - result["type"] = type; + if (type != null) { + result["type"] = type; + } if (validElementKinds != null) { result["validElementKinds"] = validElementKinds; }
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart index 156688d..f79078a 100644 --- a/pkg/analyzer/lib/dart/element/element.dart +++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -523,6 +523,10 @@ /// Return `true` if this element has an annotation of the form '@literal'. bool get hasLiteral; + /// Return `true` if this element has an annotation of the form + /// `@optionalTypeArgs`. + bool get hasOptionalTypeArgs; + /// Return `true` if this element has an annotation of the form `@override`. bool get hasOverride; @@ -747,6 +751,10 @@ /// overriding methods to call super. bool get isMustCallSuper; + /// Return `true` if this annotation marks the associated type as + /// having "optional" type arguments. + bool get isOptionalTypeArgs; + /// Return `true` if this annotation marks the associated method as being /// expected to override an inherited method. bool get isOverride;
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart index c5b2489..266e0f2 100644 --- a/pkg/analyzer/lib/error/error.dart +++ b/pkg/analyzer/lib/error/error.dart
@@ -11,6 +11,7 @@ import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode; import 'package:analyzer/src/generated/resolver.dart' show ResolverErrorCode; import 'package:analyzer/src/generated/source.dart'; +import 'package:analyzer/src/manifest/manifest_warning_code.dart'; import 'package:front_end/src/base/errors.dart'; import 'package:front_end/src/scanner/errors.dart'; @@ -230,6 +231,7 @@ CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS, CompileTimeErrorCode.NOT_ITERABLE_SPREAD, CompileTimeErrorCode.NOT_MAP_SPREAD, + CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD, CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS, CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, @@ -355,6 +357,9 @@ HintCode.UNUSED_LABEL, HintCode.UNUSED_LOCAL_VARIABLE, HintCode.UNUSED_SHOWN_NAME, + ManifestWarningCode.UNSUPPORTED_CHROME_OS_HARDWARE, + ManifestWarningCode.PERMISSION_IMPLIES_UNSUPPORTED_HARDWARE, + ManifestWarningCode.CAMERA_PERMISSIONS_INCOMPATIBLE, ParserErrorCode.ABSTRACT_CLASS_MEMBER, ParserErrorCode.ABSTRACT_ENUM, ParserErrorCode.ABSTRACT_STATIC_METHOD, @@ -528,6 +533,7 @@ ParserErrorCode.TOP_LEVEL_OPERATOR, ParserErrorCode.TYPEDEF_IN_CLASS, ParserErrorCode.TYPE_ARGUMENTS_ON_TYPE_VARIABLE, + ParserErrorCode.TYPE_BEFORE_FACTORY, ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP, ParserErrorCode.UNEXPECTED_TOKEN, ParserErrorCode.VAR_AND_TYPE,
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart index f9db9f8..b5fde2b 100644 --- a/pkg/analyzer/lib/src/dart/ast/utilities.dart +++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -7993,7 +7993,12 @@ if (i > 0) { sink.write(separator); } - nodes[i].accept(this); + var node = nodes[i]; + if (node != null) { + node.accept(this); + } else { + sink.write('<null>'); + } } } }
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart index 789609e..112dce6 100644 --- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart +++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -1160,6 +1160,10 @@ return _dartObjectComputer.eagerXor( node, leftResult, rightResult, experimentStatus.constant_update_2018); } else if (operatorType == TokenType.EQ_EQ) { + if (experimentStatus.constant_update_2018) { + return _dartObjectComputer.lazyEqualEqual( + node, leftResult, rightResult); + } return _dartObjectComputer.equalEqual(node, leftResult, rightResult); } else if (operatorType == TokenType.GT) { return _dartObjectComputer.greaterThan(node, leftResult, rightResult); @@ -2012,6 +2016,18 @@ return null; } + DartObjectImpl lazyEqualEqual(Expression node, DartObjectImpl leftOperand, + DartObjectImpl rightOperand) { + if (leftOperand != null && rightOperand != null) { + try { + return leftOperand.lazyEqualEqual(_typeProvider, rightOperand); + } on EvaluationException catch (exception) { + _errorReporter.reportErrorForNode(exception.errorCode, node); + } + } + return null; + } + DartObjectImpl lazyOr(BinaryExpression node, DartObjectImpl leftOperand, DartObjectImpl rightOperandComputer()) { if (leftOperand != null) {
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart index bb01428..1b93859 100644 --- a/pkg/analyzer/lib/src/dart/constant/value.dart +++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -109,6 +109,11 @@ } @override + BoolState lazyEqualEqual(InstanceState rightOperand) { + return isIdentical(rightOperand); + } + + @override BoolState lazyOr(InstanceState rightOperandComputer()) { if (value == true) { return TRUE_STATE; @@ -563,6 +568,31 @@ _state.lazyAnd(() => rightOperandComputer()?._state)); /** + * Return the result of invoking the '==' operator on this object with the + * [rightOperand]. The [typeProvider] is the type provider used to find known + * types. + * + * Throws an [EvaluationException] if the operator is not appropriate for an + * object of this kind. + */ + DartObjectImpl lazyEqualEqual( + TypeProvider typeProvider, DartObjectImpl rightOperand) { + if (isNull || rightOperand.isNull) { + return new DartObjectImpl( + typeProvider.boolType, + isNull && rightOperand.isNull + ? BoolState.TRUE_STATE + : BoolState.FALSE_STATE); + } + if (isBoolNumStringOrNull) { + return new DartObjectImpl( + typeProvider.boolType, _state.lazyEqualEqual(rightOperand._state)); + } + throw new EvaluationException( + CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING); + } + + /** * Return the result of invoking the '||' operator on this object with the * [rightOperand]. The [typeProvider] is the type provider used to find known * types. @@ -1077,6 +1107,11 @@ } @override + BoolState lazyEqualEqual(InstanceState rightOperand) { + return isIdentical(rightOperand); + } + + @override BoolState lessThan(InstanceState rightOperand) { assertNumOrNull(rightOperand); if (value == null) { @@ -1313,6 +1348,11 @@ } @override + BoolState lazyEqualEqual(InstanceState rightOperand) { + return BoolState.UNKNOWN_VALUE; + } + + @override BoolState lazyOr(InstanceState rightOperandComputer()) { InstanceState rightOperand = rightOperandComputer(); assertBool(rightOperand); @@ -1452,6 +1492,11 @@ } @override + BoolState lazyEqualEqual(InstanceState rightOperand) { + return isIdentical(rightOperand); + } + + @override String toString() => _element == null ? "-unknown-" : _element.name; } @@ -1544,6 +1589,11 @@ } @override + BoolState lazyEqualEqual(InstanceState rightOperand) { + return isIdentical(rightOperand); + } + + @override String toString() { StringBuffer buffer = new StringBuffer(); List<String> fieldNames = _fieldMap.keys.toList(); @@ -1855,6 +1905,15 @@ } /** + * Return the result of invoking the '==' operator on this object with the + * [rightOperand]. + * + * Throws an [EvaluationException] if the operator is not appropriate for an + * object of this kind. + */ + BoolState lazyEqualEqual(InstanceState rightOperand); + + /** * Return the result of invoking the '||' operator on this object with the * [rightOperand]. * @@ -2348,6 +2407,11 @@ } @override + BoolState lazyEqualEqual(InstanceState rightOperand) { + return isIdentical(rightOperand); + } + + @override BoolState lessThan(InstanceState rightOperand) { assertNumOrNull(rightOperand); if (value == null) { @@ -2640,6 +2704,11 @@ } @override + BoolState lazyEqualEqual(InstanceState rightOperand) { + return isIdentical(rightOperand); + } + + @override String toString() { StringBuffer buffer = new StringBuffer(); buffer.write('['); @@ -2724,6 +2793,11 @@ } @override + BoolState lazyEqualEqual(InstanceState rightOperand) { + return isIdentical(rightOperand); + } + + @override String toString() { StringBuffer buffer = new StringBuffer(); buffer.write('{'); @@ -2791,6 +2865,11 @@ } @override + BoolState lazyEqualEqual(InstanceState rightOperand) { + return isIdentical(rightOperand); + } + + @override BoolState logicalNot() { throw new EvaluationException( CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION); @@ -2880,6 +2959,11 @@ } @override + BoolState lazyEqualEqual(InstanceState rightOperand) { + return BoolState.UNKNOWN_VALUE; + } + + @override BoolState lessThan(InstanceState rightOperand) { assertNumOrNull(rightOperand); return BoolState.UNKNOWN_VALUE; @@ -2982,6 +3066,11 @@ } @override + BoolState lazyEqualEqual(InstanceState rightOperand) { + return isIdentical(rightOperand); + } + + @override String toString() { StringBuffer buffer = new StringBuffer(); buffer.write('{'); @@ -3078,6 +3167,11 @@ } @override + BoolState lazyEqualEqual(InstanceState rightOperand) { + return isIdentical(rightOperand); + } + + @override IntState stringLength() { if (value == null) { return IntState.UNKNOWN_VALUE; @@ -3145,6 +3239,11 @@ } @override + BoolState lazyEqualEqual(InstanceState rightOperand) { + return isIdentical(rightOperand); + } + + @override String toString() => value == null ? "-unknown-" : "#$value"; } @@ -3204,5 +3303,10 @@ } @override + BoolState lazyEqualEqual(InstanceState rightOperand) { + return isIdentical(rightOperand); + } + + @override String toString() => _type?.toString() ?? "-unknown-"; }
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart index 8cbeb21..743595d 100644 --- a/pkg/analyzer/lib/src/dart/element/element.dart +++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -32,6 +32,7 @@ import 'package:analyzer/src/summary/idl.dart'; import 'package:analyzer/src/summary2/linked_unit_context.dart'; import 'package:analyzer/src/summary2/reference.dart'; +import 'package:analyzer/src/util/comment.dart'; /// Assert that the given [object] is null, which in the places where this /// function is called means that the element is not resynthesized. @@ -61,7 +62,7 @@ AbstractClassElementImpl(String name, int offset) : super(name, offset); AbstractClassElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + ElementImpl enclosing, Reference reference, AstNode linkedNode) : super.forLinkedNode(enclosing, reference, linkedNode); /// Initialize a newly created class element to have the given [name]. @@ -460,11 +461,9 @@ super(name, offset); ClassElementImpl.forLinkedNode(CompilationUnitElementImpl enclosing, - Reference reference, LinkedNode linkedNode) + Reference reference, AstNode linkedNode) : _unlinkedClass = null, - super.forLinkedNode(enclosing, reference, linkedNode) { - enclosing.linkedContext.loadClassMemberReferences(reference); - } + super.forLinkedNode(enclosing, reference, linkedNode); /// Initialize a newly created class element to have the given [name]. ClassElementImpl.forNode(Identifier name) @@ -484,11 +483,10 @@ @override List<PropertyAccessorElement> get accessors { - if (linkedNode != null) { - if (_accessors != null) return _accessors; + if (_accessors != null) return _accessors; - if (linkedNode.kind == LinkedNodeKind.classDeclaration || - linkedNode.kind == LinkedNodeKind.mixinDeclaration) { + if (linkedNode != null) { + if (linkedNode is ClassOrMixinDeclaration) { _createPropertiesAndAccessors(); assert(_accessors != null); return _accessors; @@ -496,12 +494,14 @@ return _accessors = const []; } } + if (_accessors == null) { if (_unlinkedClass != null) { _resynthesizeFieldsAndPropertyAccessors(); } } - return _accessors ?? const <PropertyAccessorElement>[]; + + return _accessors ??= const <PropertyAccessorElement>[]; } @override @@ -520,7 +520,7 @@ @override int get codeLength { if (linkedNode != null) { - return linkedNode.codeLength; + return linkedContext.getCodeLength(linkedNode); } if (_unlinkedClass != null) { return _unlinkedClass.codeRange?.length; @@ -531,7 +531,7 @@ @override int get codeOffset { if (linkedNode != null) { - return linkedNode.codeOffset; + return linkedContext.getCodeOffset(linkedNode); } if (_unlinkedClass != null) { return _unlinkedClass.codeRange?.offset; @@ -552,16 +552,15 @@ if (linkedNode != null) { var context = enclosingUnit.linkedContext; var containerRef = reference.getChild('@constructor'); - if (linkedNode.kind == LinkedNodeKind.classDeclaration || - linkedNode.kind == LinkedNodeKind.mixinDeclaration) { - _constructors = linkedNode.classOrMixinDeclaration_members - .where((node) => node.kind == LinkedNodeKind.constructorDeclaration) - .map((node) { - var name = context.getConstructorDeclarationName(node); - var reference = containerRef.getChild(name); - return ConstructorElementImpl.forLinkedNode(reference, node, this); - }).toList(); - } + _constructors = context.getConstructors(linkedNode).map((node) { + var name = node.name?.name ?? ''; + var reference = containerRef.getChild(name); + if (reference.element == null) { + reference.node2 = node; + ConstructorElementImpl.forLinkedNode(this, reference, node); + } + return reference.element as ConstructorElement; + }).toList(); } if (_unlinkedClass != null) { @@ -619,9 +618,9 @@ @override String get documentationComment { if (linkedNode != null) { - return enclosingUnit.linkedContext.getCommentText( - linkedNode.annotatedNode_comment, - ); + var context = enclosingUnit.linkedContext; + var comment = context.getDocumentationComment(linkedNode); + return getCommentNodeRawText(comment); } if (_unlinkedClass != null) { return _unlinkedClass.documentationComment?.text; @@ -634,11 +633,10 @@ @override List<FieldElement> get fields { - if (linkedNode != null) { - if (_fields != null) return _fields; + if (_fields != null) return _fields; - if (linkedNode.kind == LinkedNodeKind.classDeclaration || - linkedNode.kind == LinkedNodeKind.mixinDeclaration) { + if (linkedNode != null) { + if (linkedNode is ClassOrMixinDeclaration) { _createPropertiesAndAccessors(); assert(_fields != null); return _fields; @@ -646,11 +644,13 @@ _fields = const []; } } + if (_fields == null) { if (_unlinkedClass != null) { _resynthesizeFieldsAndPropertyAccessors(); } } + return _fields ?? const <FieldElement>[]; } @@ -748,10 +748,13 @@ var context = enclosingUnit.linkedContext; var implementsClause = context.getImplementsClause(linkedNode); if (implementsClause != null) { - return _interfaces = implementsClause.implementsClause_interfaces - .map((node) => context.getInterfaceType(node.typeName_type)) - .where((type) => type != null) + return _interfaces = implementsClause.interfaces + .map((node) => node.type) + .whereType<InterfaceType>() + .where(_isInterfaceTypeInterface) .toList(); + } else { + return _interfaces = const []; } } else if (_unlinkedClass != null) { var unlinkedInterfaces = _unlinkedClass.interfaces; @@ -792,11 +795,7 @@ @override bool get isAbstract { if (linkedNode != null) { - if (linkedNode.kind == LinkedNodeKind.classDeclaration) { - return linkedNode.classDeclaration_abstractKeyword != 0; - } else { - return linkedNode.classTypeAlias_abstractKeyword != 0; - } + return enclosingUnit.linkedContext.isAbstract(linkedNode); } if (_unlinkedClass != null) { return _unlinkedClass.isAbstract; @@ -807,7 +806,7 @@ @override bool get isMixinApplication { if (linkedNode != null) { - return linkedNode.kind == LinkedNodeKind.classTypeAlias; + return linkedNode is ClassTypeAlias; } if (_unlinkedClass != null) { return _unlinkedClass.isMixinApplication; @@ -830,6 +829,14 @@ } @override + bool get isSimplyBounded { +// if (linkedNode != null) { +// return linkedNode.simplyBoundable_isSimplyBounded; +// } + return super.isSimplyBounded; + } + + @override bool get isValidMixin { if (hasReferenceToSuper) { return false; @@ -863,19 +870,18 @@ if (linkedNode != null) { var context = enclosingUnit.linkedContext; var containerRef = reference.getChild('@method'); - if (linkedNode.kind == LinkedNodeKind.classDeclaration || - linkedNode.kind == LinkedNodeKind.mixinDeclaration) { - return _methods = linkedNode.classOrMixinDeclaration_members - .where((node) => node.kind == LinkedNodeKind.methodDeclaration) - .where((node) => node.methodDeclaration_propertyKeyword == 0) - .map((node) { - var name = context.getSimpleName(node.methodDeclaration_name); - var reference = containerRef.getChild(name); - return MethodElementImpl.forLinkedNode(reference, node, this); - }).toList(); - } else { - return _methods = const <MethodElement>[]; - } + return _methods = context + .getMethods(linkedNode) + .where((node) => node.propertyKeyword == null) + .map((node) { + var name = node.name.name; + var reference = containerRef.getChild(name); + if (reference.element == null) { + reference.node2 = node; + MethodElementImpl.forLinkedNode(this, reference, node); + } + return reference.element as MethodElement; + }).toList(); } if (_unlinkedClass != null) { @@ -933,17 +939,15 @@ if (linkedNode != null) { var context = enclosingUnit.linkedContext; - LinkedNode withClause; - if (linkedNode.kind == LinkedNodeKind.classDeclaration) { - withClause = linkedNode.classDeclaration_withClause; - } else { - withClause = linkedNode.classTypeAlias_withClause; - } + var withClause = context.getWithClause(linkedNode); if (withClause != null) { - return _mixins = withClause.withClause_mixinTypes - .map((node) => context.getInterfaceType(node.typeName_type)) - .where((type) => type != null) + return _mixins = withClause.mixinTypes + .map((node) => node.type) + .whereType<InterfaceType>() + .where(_isInterfaceTypeInterface) .toList(); + } else { + return _mixins = const []; } } else if (_unlinkedClass != null) { var unlinkedMixins = _unlinkedClass.mixins; @@ -1013,37 +1017,31 @@ @override InterfaceType get supertype { - if (_supertype == null) { - if (linkedNode != null) { - LinkedNode superclass; - if (linkedNode.kind == LinkedNodeKind.classDeclaration) { - superclass = linkedNode - .classDeclaration_extendsClause?.extendsClause_superclass; - } else { - superclass = linkedNode.classTypeAlias_superclass; - } - if (superclass != null) { - var context = enclosingUnit.linkedContext; - _supertype = context.getInterfaceType(superclass.typeName_type); - } else if (!linkedNode.classDeclaration_isDartObject) { - _supertype = context.typeProvider.objectType; - } - } else if (_unlinkedClass != null) { - if (_unlinkedClass.supertype != null) { - DartType type = enclosingUnit.resynthesizerContext - .resolveTypeRef(this, _unlinkedClass.supertype); - if (_isInterfaceTypeClass(type)) { - _supertype = type; - } else { - _supertype = context.typeProvider.objectType; - } - } else if (_unlinkedClass.hasNoSupertype) { - return null; + if (_supertype != null) return _supertype; + + if (linkedNode != null) { + var context = enclosingUnit.linkedContext; + var type = context.getSuperclass(linkedNode)?.type; + if (_isInterfaceTypeClass(type)) { + return _supertype = type; + } + return _supertype = this.context.typeProvider.objectType; + } else if (_unlinkedClass != null) { + if (_unlinkedClass.supertype != null) { + DartType type = enclosingUnit.resynthesizerContext + .resolveTypeRef(this, _unlinkedClass.supertype); + if (_isInterfaceTypeClass(type)) { + _supertype = type; } else { _supertype = context.typeProvider.objectType; } + } else if (_unlinkedClass.hasNoSupertype) { + return null; + } else { + _supertype = context.typeProvider.objectType; } } + return _supertype; } @@ -1069,17 +1067,21 @@ if (linkedNode != null) { var context = enclosingUnit.linkedContext; var containerRef = reference.getChild('@typeParameter'); - var typeParameters = LinkedUnitContext.getTypeParameters(linkedNode); + var typeParameters = context.getTypeParameters2(linkedNode); if (typeParameters == null) { return _typeParameterElements = const []; } - return _typeParameterElements = typeParameters.map((node) { - var name = context.getSimpleName(node.typeParameter_name); + return _typeParameterElements = typeParameters.typeParameters.map((node) { + var name = node.name.name; var reference = containerRef.getChild(name); - reference.node = node; - return TypeParameterElementImpl.forLinkedNode(this, reference, node); + if (reference.element == null) { + reference.node2 = node; + TypeParameterElementImpl.forLinkedNode(this, reference, node); + } + return reference.element as TypeParameterElementImpl; }).toList(); } + return super.typeParameters; } @@ -1308,9 +1310,9 @@ var accessorList = <PropertyAccessorElementImpl>[]; var fieldList = <FieldElementImpl>[]; - var fields = context.classFields(linkedNode); + var fields = context.getFields(linkedNode); for (var field in fields) { - var name = context.getVariableName(field); + var name = field.name.name; var fieldElement = FieldElementImpl.forLinkedNodeFactory( this, reference.getChild('@field').getChild(name), @@ -1324,44 +1326,43 @@ } } - for (var node in linkedNode.classOrMixinDeclaration_members) { - if (node.kind == LinkedNodeKind.methodDeclaration) { - var isGetter = context.isGetterMethod(node); - var isSetter = context.isSetterMethod(node); - if (!isGetter && !isSetter) continue; + var methods = context.getMethods(linkedNode); + for (var method in methods) { + var isGetter = method.isGetter; + var isSetter = method.isSetter; + if (!isGetter && !isSetter) continue; - var name = context.getMethodName(node); - var containerRef = isGetter - ? reference.getChild('@getter') - : reference.getChild('@setter'); + var name = method.name.name; + var containerRef = isGetter + ? reference.getChild('@getter') + : reference.getChild('@setter'); - var accessorElement = PropertyAccessorElementImpl.forLinkedNode( - this, - containerRef.getChild(name), - node, - ); - accessorList.add(accessorElement); + var accessorElement = PropertyAccessorElementImpl.forLinkedNode( + this, + containerRef.getChild(name), + method, + ); + accessorList.add(accessorElement); - var fieldRef = reference.getChild('@field').getChild(name); - FieldElementImpl field = fieldRef.element; - if (field == null) { - field = new FieldElementImpl(name, -1); - fieldRef.element = field; - field.enclosingElement = this; - field.isSynthetic = true; - field.isFinal = isGetter; - field.isStatic = accessorElement.isStatic; - fieldList.add(field); - } else { - field.isFinal = false; - } + var fieldRef = reference.getChild('@field').getChild(name); + FieldElementImpl field = fieldRef.element; + if (field == null) { + field = new FieldElementImpl(name, -1); + fieldRef.element = field; + field.enclosingElement = this; + field.isSynthetic = true; + field.isFinal = isGetter; + field.isStatic = accessorElement.isStatic; + fieldList.add(field); + } else { + field.isFinal = false; + } - accessorElement.variable = field; - if (isGetter) { - field.getter = accessorElement; - } else { - field.setter = accessorElement; - } + accessorElement.variable = field; + if (isGetter) { + field.getter = accessorElement; + } else { + field.setter = accessorElement; } } @@ -1640,7 +1641,7 @@ super(null, -1); CompilationUnitElementImpl.forLinkedNode(LibraryElementImpl enclosingLibrary, - this.linkedContext, Reference reference, LinkedNode linkedNode) + this.linkedContext, Reference reference, CompilationUnit linkedNode) : resynthesizerContext = null, _unlinkedUnit = null, _unlinkedPart = null, @@ -1657,25 +1658,26 @@ @override List<PropertyAccessorElement> get accessors { + if (_accessors != null) return _accessors; + if (linkedNode != null) { - if (_accessors != null) return _accessors; _createPropertiesAndAccessors(this); assert(_accessors != null); return _accessors; } - if (_accessors == null) { - if (_unlinkedUnit != null) { - _explicitTopLevelAccessors ??= - resynthesizerContext.buildTopLevelAccessors(); - _explicitTopLevelVariables ??= - resynthesizerContext.buildTopLevelVariables(); - } - if (_explicitTopLevelAccessors != null) { - _accessors = <PropertyAccessorElementImpl>[] - ..addAll(_explicitTopLevelAccessors.accessors) - ..addAll(_explicitTopLevelVariables.implicitAccessors); - } + + if (_unlinkedUnit != null) { + _explicitTopLevelAccessors ??= + resynthesizerContext.buildTopLevelAccessors(); + _explicitTopLevelVariables ??= + resynthesizerContext.buildTopLevelVariables(); } + if (_explicitTopLevelAccessors != null) { + _accessors = <PropertyAccessorElementImpl>[] + ..addAll(_explicitTopLevelAccessors.accessors) + ..addAll(_explicitTopLevelVariables.implicitAccessors); + } + return _accessors ?? const <PropertyAccessorElement>[]; } @@ -1715,25 +1717,28 @@ @override List<ClassElement> get enums { + if (_enums != null) return _enums; + if (linkedNode != null) { - if (_enums != null) return _enums; - var context = enclosingUnit.linkedContext; var containerRef = reference.getChild('@enum'); - _enums = linkedNode.compilationUnit_declarations - .where((node) => node.kind == LinkedNodeKind.enumDeclaration) - .map((node) { - var name = context.getUnitMemberName(node); + CompilationUnit linkedNode = this.linkedNode; + _enums = linkedNode.declarations.whereType<EnumDeclaration>().map((node) { + var name = node.name.name; var reference = containerRef.getChild(name); - reference.node = node; - return EnumElementImpl.forLinkedNode(this, reference, node); + if (reference.element == null) { + reference.node2 = node; + EnumElementImpl.forLinkedNode(this, reference, node); + } + return reference.element as EnumElementImpl; }).toList(); } + if (_unlinkedUnit != null) { - _enums ??= _unlinkedUnit.enums + return _enums = _unlinkedUnit.enums .map((e) => new EnumElementImpl.forSerialized(e, this)) .toList(growable: false); } - return _enums ?? const <ClassElement>[]; + return _enums ??= const <ClassElement>[]; } /// Set the enums contained in this compilation unit to the given [enums]. @@ -1750,17 +1755,19 @@ if (_functions != null) return _functions; if (linkedNode != null) { - var context = enclosingUnit.linkedContext; + CompilationUnit linkedNode = this.linkedNode; var containerRef = reference.getChild('@function'); - _functions = linkedNode.compilationUnit_declarations - .where((node) => - node.kind == LinkedNodeKind.functionDeclaration && - !context.isGetterFunction(node) && - !context.isSetterFunction(node)) + return _functions = linkedNode.declarations + .whereType<FunctionDeclaration>() + .where((node) => !node.isGetter && !node.isSetter) .map((node) { - var name = context.getUnitMemberName(node); + var name = node.name.name; var reference = containerRef.getChild(name); - return FunctionElementImpl.forLinkedNode(this, reference, node); + if (reference.element == null) { + reference.node2 = node; + FunctionElementImpl.forLinkedNode(this, reference, node); + } + return reference.element as FunctionElementImpl; }).toList(); } else if (_unlinkedUnit != null) { _functions = _unlinkedUnit.executables @@ -1785,16 +1792,24 @@ if (_typeAliases != null) return _typeAliases; if (linkedNode != null) { - var context = enclosingUnit.linkedContext; + CompilationUnit linkedNode = this.linkedNode; var containerRef = reference.getChild('@typeAlias'); - _typeAliases = linkedNode.compilationUnit_declarations - .where((node) => - node.kind == LinkedNodeKind.functionTypeAlias || - node.kind == LinkedNodeKind.genericTypeAlias) - .map((node) { - var name = context.getUnitMemberName(node); + return _typeAliases = linkedNode.declarations.where((node) { + return node is FunctionTypeAlias || node is GenericTypeAlias; + }).map((node) { + String name; + if (node is FunctionTypeAlias) { + name = node.name.name; + } else { + name = (node as GenericTypeAlias).name.name; + } + var reference = containerRef.getChild(name); - return GenericTypeAliasElementImpl.forLinkedNode(this, reference, node); + if (reference.element == null) { + reference.node2 = node; + GenericTypeAliasElementImpl.forLinkedNode(this, reference, node); + } + return reference.element as GenericTypeAliasElement; }).toList(); } @@ -1843,15 +1858,17 @@ if (_mixins != null) return _mixins; if (linkedNode != null) { - var context = enclosingUnit.linkedContext; + CompilationUnit linkedNode = this.linkedNode; var containerRef = reference.getChild('@class'); - return _mixins = linkedNode.compilationUnit_declarations - .where((node) => node.kind == LinkedNodeKind.mixinDeclaration) - .map((node) { - var name = context.getUnitMemberName(node); + var declarations = linkedNode.declarations; + return _mixins = declarations.whereType<MixinDeclaration>().map((node) { + var name = node.name.name; var reference = containerRef.getChild(name); - reference.node = node; - return MixinElementImpl.forLinkedNode(this, reference, node); + if (reference.element == null) { + reference.node2 = node; + MixinElementImpl.forLinkedNode(this, reference, node); + } + return reference.element as MixinElementImpl; }).toList(); } @@ -1937,18 +1954,26 @@ if (_types != null) return _types; if (linkedNode != null) { - var context = enclosingUnit.linkedContext; + CompilationUnit linkedNode = this.linkedNode; var containerRef = reference.getChild('@class'); - return _types = linkedNode.compilationUnit_declarations - .where((node) => - node.kind == LinkedNodeKind.classDeclaration || - node.kind == LinkedNodeKind.classTypeAlias) - .map((node) { - var name = context.getUnitMemberName(node); + _types = <ClassElement>[]; + for (var node in linkedNode.declarations) { + String name; + if (node is ClassDeclaration) { + name = node.name.name; + } else if (node is ClassTypeAlias) { + name = node.name.name; + } else { + continue; + } var reference = containerRef.getChild(name); - reference.node = node; - return ClassElementImpl.forLinkedNode(this, reference, node); - }).toList(); + if (reference.element == null) { + reference.node2 = node; + ClassElementImpl.forLinkedNode(this, reference, node); + } + _types.add(reference.element); + } + return _types; } if (_unlinkedUnit != null) { @@ -2131,9 +2156,12 @@ var variableList = <TopLevelVariableElementImpl>[]; variableMap[unit] = variableList; - var variables = context.topLevelVariables(unit.linkedNode); + var unitNode = unit.linkedContext.unit_withDeclarations; + var unitDeclarations = unitNode.declarations; + + var variables = context.topLevelVariables(unitNode); for (var variable in variables) { - var name = context.getVariableName(variable); + var name = variable.name.name; var reference = unit.reference.getChild('@variable').getChild(name); var variableElement = TopLevelVariableElementImpl.forLinkedNodeFactory( unit, @@ -2148,13 +2176,13 @@ } } - for (var node in unit.linkedNode.compilationUnit_declarations) { - if (node.kind == LinkedNodeKind.functionDeclaration) { - var isGetter = context.isGetterFunction(node); - var isSetter = context.isSetterFunction(node); + for (var node in unitDeclarations) { + if (node is FunctionDeclaration) { + var isGetter = node.isGetter; + var isSetter = node.isSetter; if (!isGetter && !isSetter) continue; - var name = context.getUnitMemberName(node); + var name = node.name.name; var containerRef = isGetter ? unit.reference.getChild('@getter') : unit.reference.getChild('@setter'); @@ -2210,7 +2238,7 @@ ConstFieldElementImpl(String name, int offset) : super(name, offset); ConstFieldElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + ElementImpl enclosing, Reference reference, AstNode linkedNode) : super.forLinkedNode(enclosing, reference, linkedNode); /// Initialize a newly created field element to have the given [name]. @@ -2232,7 +2260,7 @@ : super(enumElement); ConstFieldElementImpl_EnumValue.forLinkedNode(EnumElementImpl enumElement, - Reference reference, LinkedNode linkedNode, this._index) + Reference reference, AstNode linkedNode, this._index) : _unlinkedEnumValue = null, super.forLinkedNode(enumElement, reference, linkedNode); @@ -2242,9 +2270,9 @@ @override String get documentationComment { if (linkedNode != null) { - return enclosingUnit.linkedContext.getCommentText( - linkedNode.annotatedNode_comment, - ); + var context = enclosingUnit.linkedContext; + var comment = context.getDocumentationComment(linkedNode); + return getCommentNodeRawText(comment); } if (_unlinkedEnumValue != null) { return _unlinkedEnumValue.documentationComment?.text; @@ -2289,9 +2317,7 @@ @override int get nameOffset { if (linkedNode != null) { - return enclosingUnit.linkedContext.getSimpleOffset( - linkedNode.enumConstantDeclaration_name, - ); + return enclosingUnit.linkedContext.getNameOffset(linkedNode); } int offset = super.nameOffset; if (offset == -1) { @@ -2350,7 +2376,7 @@ } ConstFieldElementImpl_ofEnum.forLinkedNode( - this._enum, Reference reference, LinkedNode linkedNode) + this._enum, Reference reference, AstNode linkedNode) : super.forLinkedNode(_enum, reference, linkedNode); @override @@ -2429,8 +2455,8 @@ /// and [offset]. ConstructorElementImpl(String name, int offset) : super(name, offset); - ConstructorElementImpl.forLinkedNode(Reference reference, - LinkedNode linkedNode, ClassElementImpl enclosingClass) + ConstructorElementImpl.forLinkedNode(ClassElementImpl enclosingClass, + Reference reference, ConstructorDeclaration linkedNode) : super.forLinkedNode(enclosingClass, reference, linkedNode); /// Initialize a newly created constructor element to have the given [name]. @@ -2445,13 +2471,13 @@ /// there are no initializers, or `null` if there was an error in the source. List<ConstructorInitializer> get constantInitializers { if (_constantInitializers == null) { - if (linkedNode != null) { - var context = enclosingUnit.linkedContext; - return _constantInitializers ??= - linkedNode.constructorDeclaration_initializers.map((node) { - return context.readNode(node) as ConstructorInitializer; - }).toList(); - } +// if (linkedNode != null) { +// var context = enclosingUnit.linkedContext; +// return _constantInitializers ??= +// linkedNode.constructorDeclaration_initializers.map((node) { +// return context.readNode(node) as ConstructorInitializer; +// }).toList(); +// } if (serializedExecutable != null) { _constantInitializers = serializedExecutable.constantInitializers @@ -2493,7 +2519,8 @@ @override bool get isConst { if (linkedNode != null) { - return linkedNode.constructorDeclaration_constKeyword != 0; + ConstructorDeclaration linkedNode = this.linkedNode; + return linkedNode.constKeyword != null; } if (serializedExecutable != null) { return serializedExecutable.isConst; @@ -2542,7 +2569,8 @@ @override bool get isFactory { if (linkedNode != null) { - return linkedNode.constructorDeclaration_factoryKeyword != 0; + ConstructorDeclaration linkedNode = this.linkedNode; + return linkedNode.factoryKeyword != null; } if (serializedExecutable != null) { return serializedExecutable.isFactory; @@ -2599,24 +2627,24 @@ @override ConstructorElement get redirectedConstructor { if (_redirectedConstructor == null) { - if (linkedNode != null) { - var context = enclosingUnit.linkedContext; - if (isFactory) { - var node = linkedNode.constructorDeclaration_redirectedConstructor; - if (node != null) { - ConstructorName ast = context.readNode(node); - return ast.staticElement; - } - } else { - for (var node in linkedNode.constructorDeclaration_initializers) { - if (node.kind == LinkedNodeKind.redirectingConstructorInvocation) { - RedirectingConstructorInvocation ast = context.readNode(node); - return ast.staticElement; - } - } - } - return null; - } +// if (linkedNode != null) { +// var context = enclosingUnit.linkedContext; +// if (isFactory) { +// var node = linkedNode.constructorDeclaration_redirectedConstructor; +// if (node != null) { +// ConstructorName ast = context.readNode(node); +// return ast.staticElement; +// } +// } else { +// for (var node in linkedNode.constructorDeclaration_initializers) { +// if (node.kind == LinkedNodeKind.redirectingConstructorInvocation) { +// RedirectingConstructorInvocation ast = context.readNode(node); +// return ast.staticElement; +// } +// } +// } +// return null; +// } if (serializedExecutable != null) { if (serializedExecutable.isRedirectedConstructor) { @@ -2759,7 +2787,7 @@ : super(name, offset); ConstTopLevelVariableElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + ElementImpl enclosing, Reference reference, AstNode linkedNode) : super.forLinkedNode(enclosing, reference, linkedNode); /// Initialize a newly created top-level variable element to have the given @@ -2850,7 +2878,7 @@ : super(name, nameOffset); DefaultFieldFormalParameterElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + ElementImpl enclosing, Reference reference, AstNode linkedNode) : super.forLinkedNode(enclosing, reference, linkedNode); /// Initialize a newly created parameter element to have the given [name]. @@ -2872,7 +2900,7 @@ : super(name, nameOffset); DefaultParameterElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + ElementImpl enclosing, Reference reference, AstNode linkedNode) : super.forLinkedNode(enclosing, reference, linkedNode); /// Initialize a newly created parameter element to have the given [name]. @@ -2938,6 +2966,10 @@ /// literal. static String _LITERAL_VARIABLE_NAME = "literal"; + /// The name of the top-level variable used to mark a type as having + /// "optional" type arguments. + static String _OPTIONAL_TYPE_ARGS_VARIABLE_NAME = "optionalTypeArgs"; + /// The name of the top-level variable used to mark a function as running /// a single test. static String _IS_TEST_VARIABLE_NAME = "isTest"; @@ -3087,6 +3119,12 @@ element.library?.name == _META_LIB_NAME; @override + bool get isOptionalTypeArgs => + element is PropertyAccessorElement && + element.name == _OPTIONAL_TYPE_ARGS_VARIABLE_NAME && + element.library?.name == _META_LIB_NAME; + + @override bool get isOverride => element is PropertyAccessorElement && element.name == _OVERRIDE_VARIABLE_NAME && @@ -3168,7 +3206,7 @@ ElementImpl _enclosingElement; Reference reference; - final LinkedNode linkedNode; + final AstNode linkedNode; /// The name of this element. String _name; @@ -3358,6 +3396,18 @@ } @override + bool get hasOptionalTypeArgs { + var metadata = this.metadata; + for (var i = 0; i < metadata.length; i++) { + var annotation = metadata[i]; + if (annotation.isOptionalTypeArgs) { + return true; + } + } + return false; + } + + @override bool get hasOverride { var metadata = this.metadata; for (var i = 0; i < metadata.length; i++) { @@ -3492,6 +3542,10 @@ @override Source get librarySource => library?.source; + LinkedUnitContext get linkedContext { + return _enclosingElement.linkedContext; + } + @override ElementLocation get location { if (_cachedLocation == null) { @@ -3506,7 +3560,7 @@ List<ElementAnnotation> get metadata { if (linkedNode != null) { if (_metadata != null) return _metadata; - var metadata = enclosingUnit.linkedContext.getMetadataOrEmpty(linkedNode); + var metadata = linkedContext.getMetadata(linkedNode); return _metadata = _buildAnnotations2(enclosingUnit, metadata); } return _metadata ?? const <ElementAnnotation>[]; @@ -3720,7 +3774,7 @@ /// Return annotations for the given [nodeList] in the [unit]. List<ElementAnnotation> _buildAnnotations2( - CompilationUnitElementImpl unit, List<LinkedNode> nodeList) { + CompilationUnitElementImpl unit, List<Annotation> nodeList) { var length = nodeList.length; if (length == 0) { return const <ElementAnnotation>[]; @@ -3728,7 +3782,7 @@ var annotations = new List<ElementAnnotation>(length); for (int i = 0; i < length; i++) { - var ast = unit.linkedContext.readNode(nodeList[i]); + var ast = nodeList[i]; annotations[i] = ElementAnnotationImpl(enclosingUnit) ..annotationAst = ast; } @@ -3922,7 +3976,7 @@ super(name, offset); EnumElementImpl.forLinkedNode(CompilationUnitElementImpl enclosing, - Reference reference, LinkedNode linkedNode) + Reference reference, EnumDeclaration linkedNode) : _unlinkedEnum = null, super.forLinkedNode(enclosing, reference, linkedNode); @@ -3966,7 +4020,7 @@ @override int get codeLength { if (linkedNode != null) { - return linkedNode.codeLength; + return linkedContext.getCodeLength(linkedNode); } if (_unlinkedEnum != null) { return _unlinkedEnum.codeRange?.length; @@ -3977,7 +4031,7 @@ @override int get codeOffset { if (linkedNode != null) { - return linkedNode.codeOffset; + return linkedContext.getCodeOffset(linkedNode); } if (_unlinkedEnum != null) { return _unlinkedEnum.codeRange?.offset; @@ -3997,9 +4051,9 @@ @override String get documentationComment { if (linkedNode != null) { - return enclosingUnit.linkedContext.getCommentText( - linkedNode.annotatedNode_comment, - ); + var context = enclosingUnit.linkedContext; + var comment = context.getDocumentationComment(linkedNode); + return getCommentNodeRawText(comment); } if (_unlinkedEnum != null) { return _unlinkedEnum.documentationComment?.text; @@ -4209,13 +4263,12 @@ } // Build fields for all enum constants. - var constants = linkedNode.enumDeclaration_constants; + var containerRef = this.reference.getChild('@constant'); + var constants = linkedContext.getEnumConstants(linkedNode); for (var i = 0; i < constants.length; ++i) { var constant = constants[i]; - var name = enclosingUnit.linkedContext.getSimpleName( - constant.enumConstantDeclaration_name, - ); - var reference = this.reference.getChild('@constant').getChild(name); + var name = constant.name.name; + var reference = containerRef.getChild(name); var field = new ConstFieldElementImpl_EnumValue.forLinkedNode( this, reference, constant, i); fields.add(field); @@ -4256,7 +4309,7 @@ /// Initialize using the given linked node. ExecutableElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + ElementImpl enclosing, Reference reference, AstNode linkedNode) : serializedExecutable = null, super.forLinkedNode(enclosing, reference, linkedNode) { reference.element = this; @@ -4281,7 +4334,7 @@ @override int get codeLength { if (linkedNode != null) { - return linkedNode.codeLength; + return linkedContext.getCodeLength(linkedNode); } if (serializedExecutable != null) { return serializedExecutable.codeRange?.length; @@ -4292,7 +4345,7 @@ @override int get codeOffset { if (linkedNode != null) { - return linkedNode.codeOffset; + return linkedContext.getCodeOffset(linkedNode); } if (serializedExecutable != null) { return serializedExecutable.codeRange?.offset; @@ -4319,9 +4372,9 @@ @override String get documentationComment { if (linkedNode != null) { - return enclosingUnit.linkedContext.getCommentText( - linkedNode.annotatedNode_comment, - ); + var context = enclosingUnit.linkedContext; + var comment = context.getDocumentationComment(linkedNode); + return getCommentNodeRawText(comment); } if (serializedExecutable != null) { return serializedExecutable.documentationComment?.text; @@ -4358,6 +4411,9 @@ @override bool get isAbstract { + if (linkedNode != null) { + return !isExternal && enclosingUnit.linkedContext.isAbstract(linkedNode); + } if (serializedExecutable != null) { return serializedExecutable.isAbstract; } @@ -4426,9 +4482,7 @@ @override int get nameOffset { if (linkedNode != null) { - return enclosingUnit.linkedContext.getSimpleOffset( - linkedNode.namedCompilationUnitMember_name, - ); + return enclosingUnit.linkedContext.getNameOffset(linkedNode); } int offset = super.nameOffset; @@ -4440,24 +4494,26 @@ @override List<ParameterElement> get parameters { - if (_parameters == null) { - if (linkedNode != null) { - var context = enclosingUnit.linkedContext; - var containerRef = reference.getChild('@parameter'); - var formalParameters = context.getFormalParameters(linkedNode); - _parameters = ParameterElementImpl.forLinkedNodeList( - this, - context, - containerRef, - formalParameters, - ); - } - if (serializedExecutable != null) { - _parameters = ParameterElementImpl.resynthesizeList( - serializedExecutable.parameters, this); - } + if (_parameters != null) return _parameters; + + if (linkedNode != null) { + var context = enclosingUnit.linkedContext; + var containerRef = reference.getChild('@parameter'); + var formalParameters = context.getFormalParameters(linkedNode); + _parameters = ParameterElementImpl.forLinkedNodeList( + this, + context, + containerRef, + formalParameters, + ); } - return _parameters ?? const <ParameterElement>[]; + + if (serializedExecutable != null) { + _parameters = ParameterElementImpl.resynthesizeList( + serializedExecutable.parameters, this); + } + + return _parameters ??= const <ParameterElement>[]; } /// Set the parameters defined by this executable element to the given @@ -4473,8 +4529,10 @@ @override DartType get returnType { if (linkedNode != null) { - return _returnType ??= - enclosingUnit.linkedContext.getReturnType(linkedNode); + if (_returnType != null) return _returnType; + return _returnType = enclosingUnit.linkedContext.getReturnType( + linkedNode, + ); } if (serializedExecutable != null && _declaredReturnType == null && @@ -4624,7 +4682,7 @@ super(null, offset); ExportElementImpl.forLinkedNode( - LibraryElementImpl enclosing, LinkedNode linkedNode) + LibraryElementImpl enclosing, ExportDirective linkedNode) : _unlinkedExportPublic = null, _unlinkedExportNonPublic = null, super.forLinkedNode(enclosing, null, linkedNode); @@ -4639,9 +4697,10 @@ if (_combinators != null) return _combinators; if (linkedNode != null) { + ExportDirective node = linkedNode; return _combinators = ImportElementImpl._buildCombinators2( enclosingUnit.linkedContext, - linkedNode, + node.combinators, ); } @@ -4670,11 +4729,7 @@ if (linkedNode != null) { var context = enclosingUnit.linkedContext; - var relativeUriStr = context.getStringContent( - linkedNode.uriBasedDirective_uri, - ); - var relativeUri = Uri.parse(relativeUriStr); - var uri = resolveRelativeUri(librarySource.uri, relativeUri); + var uri = context.directiveUri(librarySource.uri, linkedNode); var elementFactory = context.bundleContext.elementFactory; return _exportedLibrary = elementFactory.libraryOfUri('$uri'); } @@ -4700,11 +4755,6 @@ @override List<ElementAnnotation> get metadata { - if (linkedNode != null) { - if (_metadata != null) return _metadata; - var metadata = enclosingUnit.linkedContext.getMetadataOrEmpty(linkedNode); - return _metadata = _buildAnnotations2(enclosingUnit, metadata); - } if (_metadata == null) { if (_unlinkedExportNonPublic != null) { return _metadata = _buildAnnotations(library.definingCompilationUnit, @@ -4789,7 +4839,7 @@ FieldElementImpl(String name, int offset) : super(name, offset); FieldElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + ElementImpl enclosing, Reference reference, AstNode linkedNode) : super.forLinkedNode(enclosing, reference, linkedNode) { if (!linkedNode.isSynthetic) { var enclosingRef = enclosing.reference; @@ -4809,7 +4859,7 @@ } factory FieldElementImpl.forLinkedNodeFactory( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) { + ElementImpl enclosing, Reference reference, AstNode linkedNode) { if (enclosing.enclosingUnit.linkedContext.isConst(linkedNode)) { return ConstFieldElementImpl.forLinkedNode( enclosing, @@ -4850,14 +4900,13 @@ @override bool get isCovariant { if (linkedNode != null) { - if (linkedNode.kind == LinkedNodeKind.variableDeclaration) { - return linkedNode.variableDeclaration_declaration.isCovariant; - } - return false; + return linkedContext.isCovariantField(linkedNode); } + if (_unlinkedVariable != null) { return _unlinkedVariable.isCovariant; } + return hasModifier(Modifier.COVARIANT); } @@ -4922,7 +4971,7 @@ : super(name, nameOffset); FieldFormalParameterElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + ElementImpl enclosing, Reference reference, AstNode linkedNode) : super.forLinkedNode(enclosing, reference, linkedNode); /// Initialize a newly created parameter element to have the given [name]. @@ -5001,8 +5050,8 @@ /// [offset]. FunctionElementImpl(String name, int offset) : super(name, offset); - FunctionElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + FunctionElementImpl.forLinkedNode(ElementImpl enclosing, Reference reference, + FunctionDeclaration linkedNode) : super.forLinkedNode(enclosing, reference, linkedNode); /// Initialize a newly created function element to have the given [name]. @@ -5030,6 +5079,14 @@ } @override + String get displayName { + if (linkedNode != null) { + return reference.name; + } + return super.displayName; + } + + @override TypeParameterizedElementMixin get enclosingTypeParameterContext { return (enclosingElement as ElementImpl).typeParameterContext; } @@ -5056,20 +5113,18 @@ ElementKind get kind => ElementKind.FUNCTION; @override - DartType get returnType { + String get name { if (linkedNode != null) { - return enclosingUnit.linkedContext.getType( - linkedNode.functionDeclaration_returnType2, - ); + return reference.name; } - return super.returnType; + return super.name; } @override void set returnType(DartType returnType) { - if (linkedNode != null) { - enclosingUnit.linkedContext.setReturnType(linkedNode, returnType); - } +// if (linkedNode != null) { +// enclosingUnit.linkedContext.setReturnType(linkedNode, returnType); +// } super.returnType = returnType; } @@ -5242,7 +5297,7 @@ FunctionType _type; GenericFunctionTypeElementImpl.forLinkedNode( - ElementImpl enclosingElement, Reference reference, LinkedNode linkedNode) + ElementImpl enclosingElement, Reference reference, AstNode linkedNode) : super.forLinkedNode(enclosingElement, reference, linkedNode); /// Initialize a newly created function element to have no name and the given @@ -5335,7 +5390,7 @@ @override List<TypeParameterElement> get typeParameters { if (linkedNode != null) { - if (linkedNode.kind == LinkedNodeKind.functionTypeAlias) { + if (linkedNode is FunctionTypeAlias) { return const <TypeParameterElement>[]; } } @@ -5425,7 +5480,7 @@ GenericTypeAliasElementImpl.forLinkedNode( CompilationUnitElementImpl enclosingUnit, Reference reference, - LinkedNode linkedNode) + AstNode linkedNode) : _unlinkedTypedef = null, super.forLinkedNode(enclosingUnit, reference, linkedNode); @@ -5442,7 +5497,7 @@ @override int get codeLength { if (linkedNode != null) { - return linkedNode.codeLength; + return linkedContext.getCodeLength(linkedNode); } if (_unlinkedTypedef != null) { return _unlinkedTypedef.codeRange?.length; @@ -5453,7 +5508,7 @@ @override int get codeOffset { if (linkedNode != null) { - return linkedNode.codeOffset; + return linkedContext.getCodeOffset(linkedNode); } if (_unlinkedTypedef != null) { return _unlinkedTypedef.codeRange?.offset; @@ -5467,9 +5522,9 @@ @override String get documentationComment { if (linkedNode != null) { - return enclosingUnit.linkedContext.getCommentText( - linkedNode.annotatedNode_comment, - ); + var context = enclosingUnit.linkedContext; + var comment = context.getDocumentationComment(linkedNode); + return getCommentNodeRawText(comment); } if (_unlinkedTypedef != null) { return _unlinkedTypedef.documentationComment?.text; @@ -5493,11 +5548,12 @@ if (_function != null) return _function; if (linkedNode != null) { - if (linkedNode.kind == LinkedNodeKind.genericTypeAlias) { - _function = GenericFunctionTypeElementImpl.forLinkedNode( + if (linkedNode is GenericTypeAlias) { + var context = enclosingUnit.linkedContext; + return _function = GenericFunctionTypeElementImpl.forLinkedNode( this, reference.getChild('@function'), - linkedNode.genericTypeAlias_functionType, + context.getGeneticTypeAliasFunction(linkedNode), ); } else { return _function = GenericFunctionTypeElementImpl.forLinkedNode( @@ -5506,7 +5562,6 @@ linkedNode, ); } - return _function; } if (_unlinkedTypedef != null) { @@ -5546,6 +5601,14 @@ } @override + bool get isSimplyBounded { +// if (linkedNode != null) { +// return linkedNode.simplyBoundable_isSimplyBounded; +// } + return super.isSimplyBounded; + } + + @override ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS; @override @@ -5706,7 +5769,7 @@ final UnlinkedCombinator _unlinkedCombinator; final LinkedUnitContext linkedContext; - final LinkedNode linkedNode; + final HideCombinator linkedNode; /// The names that are not to be made visible in the importing library even if /// they are defined in the imported library. @@ -5730,9 +5793,7 @@ if (_hiddenNames != null) return _hiddenNames; if (linkedNode != null) { - return _hiddenNames = linkedNode.hideCombinator_hiddenNames - .map((node) => linkedContext.getSimpleName(node)) - .toList(); + return _hiddenNames = linkedNode.hiddenNames.map((i) => i.name).toList(); } if (_unlinkedCombinator != null) { @@ -5800,7 +5861,7 @@ super(null, offset); ImportElementImpl.forLinkedNode( - LibraryElementImpl enclosing, LinkedNode linkedNode) + LibraryElementImpl enclosing, ImportDirective linkedNode) : _unlinkedImport = null, _linkedDependency = null, super.forLinkedNode(enclosing, null, linkedNode); @@ -5815,9 +5876,10 @@ if (_combinators != null) return _combinators; if (linkedNode != null) { - return _combinators = _buildCombinators2( + ImportDirective node = linkedNode; + return _combinators = ImportElementImpl._buildCombinators2( enclosingUnit.linkedContext, - linkedNode, + node.combinators, ); } @@ -5854,14 +5916,11 @@ if (linkedNode != null) { var context = enclosingUnit.linkedContext; - var relativeUriStr = context.getStringContent( - linkedNode.uriBasedDirective_uri, - ); - var relativeUri = Uri.parse(relativeUriStr); - var uri = resolveRelativeUri(librarySource.uri, relativeUri); + var uri = context.directiveUri(librarySource.uri, linkedNode); var elementFactory = context.bundleContext.elementFactory; return _importedLibrary = elementFactory.libraryOfUri('$uri'); } + if (_linkedDependency != null) { if (_importedLibrary == null) { LibraryElementImpl library = enclosingElement as LibraryElementImpl; @@ -5873,6 +5932,7 @@ } } } + return _importedLibrary; } @@ -5884,7 +5944,8 @@ @override bool get isDeferred { if (linkedNode != null) { - return linkedNode.importDirective_deferredKeyword != 0; + ImportDirective linkedNode = this.linkedNode; + return linkedNode.deferredKeyword != null; } if (_unlinkedImport != null) { return _unlinkedImport.isDeferred; @@ -5905,11 +5966,6 @@ @override List<ElementAnnotation> get metadata { - if (linkedNode != null) { - if (_metadata != null) return _metadata; - var metadata = enclosingUnit.linkedContext.getMetadataOrEmpty(linkedNode); - return _metadata = _buildAnnotations2(enclosingUnit, metadata); - } if (_metadata == null) { if (_unlinkedImport != null) { return _metadata = _buildAnnotations( @@ -5943,25 +5999,27 @@ } PrefixElement get prefix { - if (_prefix == null) { - if (linkedNode != null) { - var prefix = linkedNode.importDirective_prefix; - if (prefix != null) { - var context = enclosingUnit.linkedContext; - var name = context.getSimpleName(prefix); - LibraryElementImpl library = enclosingElement as LibraryElementImpl; - _prefix = new PrefixElementImpl.forLinkedNode( - library, - library.reference.getChild('@prefix').getChild(name), - prefix, - ); - } - } - if (_unlinkedImport != null && _unlinkedImport.prefixReference != 0) { - LibraryElementImpl library = enclosingElement as LibraryElementImpl; - _prefix = new PrefixElementImpl.forSerialized(_unlinkedImport, library); + if (_prefix != null) return _prefix; + + if (linkedNode != null) { + ImportDirective linkedNode = this.linkedNode; + var prefix = linkedNode.prefix; + if (prefix != null) { + var name = prefix.name; + var library = enclosingElement as LibraryElementImpl; + _prefix = new PrefixElementImpl.forLinkedNode( + library, + library.reference.getChild('@prefix').getChild(name), + prefix, + ); } } + + if (_unlinkedImport != null && _unlinkedImport.prefixReference != 0) { + LibraryElementImpl library = enclosingElement as LibraryElementImpl; + _prefix = new PrefixElementImpl.forSerialized(_unlinkedImport, library); + } + return _prefix; } @@ -6069,16 +6127,15 @@ } static List<NamespaceCombinator> _buildCombinators2( - LinkedUnitContext context, LinkedNode linkedNode) { - return linkedNode.namespaceDirective_combinators.map((node) { - var kind = node.kind; - if (kind == LinkedNodeKind.hideCombinator) { + LinkedUnitContext context, List<Combinator> combinators) { + return combinators.map((node) { + if (node is HideCombinator) { return HideElementCombinatorImpl.forLinkedNode(context, node); } - if (kind == LinkedNodeKind.showCombinator) { + if (node is ShowCombinator) { return ShowElementCombinatorImpl.forLinkedNode(context, node); } - throw UnimplementedError('$kind'); + throw UnimplementedError('${node.runtimeType}'); }).toList(); } } @@ -6212,7 +6269,7 @@ this.nameLength, this.linkedContext, Reference reference, - LinkedNode linkedNode) + CompilationUnit linkedNode) : resynthesizerContext = null, unlinkedDefiningUnit = null, super.forLinkedNode(null, reference, linkedNode) { @@ -6311,14 +6368,17 @@ @override Namespace get exportNamespace { + if (_exportNamespace != null) return _exportNamespace; + if (linkedNode != null) { - if (_exportNamespace != null) return _exportNamespace; var elements = linkedContext.bundleContext.elementFactory; return _exportNamespace = elements.buildExportNamespace(source.uri); } + if (resynthesizerContext != null) { _exportNamespace ??= resynthesizerContext.buildExportNamespace(); } + return _exportNamespace; } @@ -6328,41 +6388,42 @@ @override List<ExportElement> get exports { - if (_exports == null) { - if (linkedNode != null) { - return _exports = linkedNode.compilationUnit_directives - .where((node) => node.kind == LinkedNodeKind.exportDirective) - .map((node) { - return ExportElementImpl.forLinkedNode(this, node); - }).toList(); - } - if (unlinkedDefiningUnit != null) { - List<UnlinkedExportNonPublic> unlinkedNonPublicExports = - unlinkedDefiningUnit.exports; - List<UnlinkedExportPublic> unlinkedPublicExports = - unlinkedDefiningUnit.publicNamespace.exports; - assert(unlinkedDefiningUnit.exports.length == - unlinkedPublicExports.length); - int length = unlinkedNonPublicExports.length; - if (length != 0) { - List<ExportElement> exports = new List<ExportElement>(); - for (int i = 0; i < length; i++) { - UnlinkedExportPublic serializedExportPublic = - unlinkedPublicExports[i]; - UnlinkedExportNonPublic serializedExportNonPublic = - unlinkedNonPublicExports[i]; - ExportElementImpl exportElement = - new ExportElementImpl.forSerialized( - serializedExportPublic, serializedExportNonPublic, library); - exports.add(exportElement); - } - _exports = exports; - } else { - _exports = const <ExportElement>[]; + if (_exports != null) return _exports; + + if (linkedNode != null) { + var unit = linkedContext.unit_withDirectives; + return _exports = unit.directives + .whereType<ExportDirective>() + .map((node) => ExportElementImpl.forLinkedNode(this, node)) + .toList(); + } + + if (unlinkedDefiningUnit != null) { + List<UnlinkedExportNonPublic> unlinkedNonPublicExports = + unlinkedDefiningUnit.exports; + List<UnlinkedExportPublic> unlinkedPublicExports = + unlinkedDefiningUnit.publicNamespace.exports; + assert( + unlinkedDefiningUnit.exports.length == unlinkedPublicExports.length); + int length = unlinkedNonPublicExports.length; + if (length != 0) { + List<ExportElement> exports = new List<ExportElement>(); + for (int i = 0; i < length; i++) { + UnlinkedExportPublic serializedExportPublic = + unlinkedPublicExports[i]; + UnlinkedExportNonPublic serializedExportNonPublic = + unlinkedNonPublicExports[i]; + ExportElementImpl exportElement = new ExportElementImpl.forSerialized( + serializedExportPublic, serializedExportNonPublic, library); + exports.add(exportElement); } + _exports = exports; + } else { + _exports = const <ExportElement>[]; } } - return _exports ?? const <ExportElement>[]; + + return _exports ??= const <ExportElement>[]; } /// Set the specifications of all of the exports defined in this library to @@ -6424,20 +6485,30 @@ @override List<ImportElement> get imports { - if (_imports == null) { - if (linkedNode != null) { - return _imports = linkedNode.compilationUnit_directives - .where((node) => node.kind == LinkedNodeKind.importDirective) - .map((node) { - return ImportElementImpl.forLinkedNode(this, node); - }).toList(); + if (_imports != null) return _imports; + + if (linkedNode != null) { + var unit = linkedContext.unit_withDirectives; + _imports = unit.directives + .whereType<ImportDirective>() + .map((node) => ImportElementImpl.forLinkedNode(this, node)) + .toList(); + var hasCore = _imports.any((import) => import.importedLibrary.isDartCore); + if (!hasCore) { + var elements = linkedContext.bundleContext.elementFactory; + _imports.add(ImportElementImpl(-1) + ..importedLibrary = elements.libraryOfUri('dart:core') + ..isSynthetic = true); } - if (unlinkedDefiningUnit != null) { - _imports = buildImportsFromSummary(this, unlinkedDefiningUnit.imports, - resynthesizerContext.linkedLibrary.importDependencies); - } + return _imports; } - return _imports ?? const <ImportElement>[]; + + if (unlinkedDefiningUnit != null) { + _imports = buildImportsFromSummary(this, unlinkedDefiningUnit.imports, + resynthesizerContext.linkedLibrary.importDependencies); + } + + return _imports ??= const <ImportElement>[]; } /// Set the specifications of all of the imports defined in this library to @@ -6599,21 +6670,19 @@ @override List<ElementAnnotation> get metadata { + if (_metadata != null) return _metadata; + if (linkedNode != null) { - if (_metadata != null) return _metadata; - CompilationUnitElementImpl enclosingUnit = _definingCompilationUnit; - var context = enclosingUnit.linkedContext; - var metadata = context.getLibraryMetadataOrEmpty(linkedNode); + var metadata = linkedContext.getLibraryMetadata(linkedNode); return _metadata = _buildAnnotations2(enclosingUnit, metadata); } - if (_metadata == null) { - if (unlinkedDefiningUnit != null) { - _metadata = _buildAnnotations( - _definingCompilationUnit as CompilationUnitElementImpl, - unlinkedDefiningUnit.libraryAnnotations); - return _metadata; - } + + if (unlinkedDefiningUnit != null) { + return _metadata = _buildAnnotations( + _definingCompilationUnit as CompilationUnitElementImpl, + unlinkedDefiningUnit.libraryAnnotations); } + return super.metadata; } @@ -6990,8 +7059,8 @@ /// given [offset]. MethodElementImpl(String name, int offset) : super(name, offset); - MethodElementImpl.forLinkedNode(Reference reference, LinkedNode linkedNode, - ClassElementImpl enclosingClass) + MethodElementImpl.forLinkedNode(ClassElementImpl enclosingClass, + Reference reference, MethodDeclaration linkedNode) : super.forLinkedNode(enclosingClass, reference, linkedNode); /// Initialize a newly created method element to have the given [name]. @@ -7025,14 +7094,6 @@ super.enclosingElement as ClassElementImpl; @override - bool get isAbstract { - if (linkedNode != null) { - return !isExternal && enclosingUnit.linkedContext.isAbstract(linkedNode); - } - return super.isAbstract; - } - - @override bool get isOperator { String name = displayName; if (name.isEmpty) { @@ -7048,7 +7109,7 @@ @override bool get isStatic { if (linkedNode != null) { - return linkedNode.methodDeclaration_modifierKeyword != 0; + return enclosingUnit.linkedContext.isStatic(linkedNode); } if (serializedExecutable != null) { return serializedExecutable.isStatic; @@ -7076,11 +7137,11 @@ @override DartType get returnType { - if (linkedNode != null) { - return enclosingUnit.linkedContext.getType( - linkedNode.methodDeclaration_returnType2, - ); - } +// if (linkedNode != null) { +// return enclosingUnit.linkedContext.getType( +// linkedNode.methodDeclaration_returnType2, +// ); +// } return super.returnType; } @@ -7151,10 +7212,8 @@ MixinElementImpl(String name, int offset) : super(name, offset); MixinElementImpl.forLinkedNode(CompilationUnitElementImpl enclosing, - Reference reference, LinkedNode linkedNode) - : super.forLinkedNode(enclosing, reference, linkedNode) { - enclosing.linkedContext.loadClassMemberReferences(reference); - } + Reference reference, MixinDeclaration linkedNode) + : super.forLinkedNode(enclosing, reference, linkedNode); /// Initialize a newly created class element to have the given [name]. MixinElementImpl.forNode(Identifier name) : super.forNode(name); @@ -7179,12 +7238,11 @@ if (linkedNode != null) { List<InterfaceType> constraints; - var onClause = linkedNode.mixinDeclaration_onClause; + var onClause = enclosingUnit.linkedContext.getOnClause(linkedNode); if (onClause != null) { - var context = enclosingUnit.linkedContext; - constraints = onClause.onClause_superclassConstraints - .map((node) => context.getInterfaceType(node.typeName_type)) - .where((type) => type != null) + constraints = onClause.superclassConstraints + .map((node) => node.type) + .whereType<InterfaceType>() .toList(); } if (constraints == null || constraints.isEmpty) { @@ -7443,6 +7501,9 @@ bool get hasLiteral => false; @override + bool get hasOptionalTypeArgs => false; + + @override bool get hasOverride => false; @override @@ -7651,7 +7712,7 @@ super(name, offset); NonParameterVariableElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + ElementImpl enclosing, Reference reference, AstNode linkedNode) : _unlinkedVariable = null, super.forLinkedNode(enclosing, reference, linkedNode); @@ -7668,7 +7729,7 @@ @override int get codeLength { if (linkedNode != null) { - return linkedNode.codeLength; + return linkedContext.getCodeLength(linkedNode); } if (_unlinkedVariable != null) { return _unlinkedVariable.codeRange?.length; @@ -7679,7 +7740,7 @@ @override int get codeOffset { if (linkedNode != null) { - return linkedNode.codeOffset; + return linkedContext.getCodeOffset(linkedNode); } if (_unlinkedVariable != null) { return _unlinkedVariable.codeRange?.offset; @@ -7690,9 +7751,9 @@ @override String get documentationComment { if (linkedNode != null) { - return enclosingUnit.linkedContext.getCommentText( - linkedNode.variableDeclaration_declaration.comment, - ); + var context = enclosingUnit.linkedContext; + var comment = context.getDocumentationComment(linkedNode); + return getCommentNodeRawText(comment); } if (_unlinkedVariable != null) { return _unlinkedVariable.documentationComment?.text; @@ -7778,9 +7839,7 @@ @override String get name { if (linkedNode != null) { - return enclosingUnit.linkedContext.getSimpleName( - linkedNode.variableDeclaration_name, - ); + return reference.name; } if (_unlinkedVariable != null) { return _unlinkedVariable.name; @@ -7791,10 +7850,9 @@ @override int get nameOffset { if (linkedNode != null) { - return enclosingUnit.linkedContext.getSimpleOffset( - linkedNode.variableDeclaration_name, - ); + return enclosingUnit.linkedContext.getNameOffset(linkedNode); } + int offset = super.nameOffset; if (offset == 0) { if (_unlinkedVariable != null) { @@ -7864,28 +7922,23 @@ super(name, nameOffset); ParameterElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + ElementImpl enclosing, Reference reference, FormalParameter linkedNode) : unlinkedParam = null, super.forLinkedNode(enclosing, reference, linkedNode); factory ParameterElementImpl.forLinkedNodeFactory( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) { - var kind = linkedNode.kind; - if (kind == LinkedNodeKind.fieldFormalParameter) { + ElementImpl enclosing, Reference reference, FormalParameter node) { + if (node is FieldFormalParameter) { return FieldFormalParameterElementImpl.forLinkedNode( enclosing, reference, - linkedNode, + node, ); - } else if (kind == LinkedNodeKind.functionTypedFormalParameter || - kind == LinkedNodeKind.simpleFormalParameter) { - return ParameterElementImpl.forLinkedNode( - enclosing, - reference, - linkedNode, - ); + } else if (node is FunctionTypedFormalParameter || + node is SimpleFormalParameter) { + return ParameterElementImpl.forLinkedNode(enclosing, reference, node); } else { - throw UnimplementedError('$kind'); + throw UnimplementedError('${node.runtimeType}'); } } @@ -7938,7 +7991,7 @@ @override int get codeLength { if (linkedNode != null) { - return linkedNode.codeLength; + return linkedContext.getCodeLength(linkedNode); } if (unlinkedParam != null) { return unlinkedParam.codeRange?.length; @@ -7949,7 +8002,7 @@ @override int get codeOffset { if (linkedNode != null) { - return linkedNode.codeOffset; + return linkedContext.getCodeOffset(linkedNode); } if (unlinkedParam != null) { return unlinkedParam.codeRange?.offset; @@ -8046,13 +8099,13 @@ @override bool get isCovariant { - if (linkedNode != null) { - if (linkedNode.kind == LinkedNodeKind.defaultFormalParameter) { - var parameter = linkedNode.defaultFormalParameter_parameter; - return parameter.normalFormalParameter_isCovariant; - } - return linkedNode.normalFormalParameter_isCovariant; - } +// if (linkedNode != null) { +// if (linkedNode.kind == LinkedNodeKind.defaultFormalParameter) { +// var parameter = linkedNode.defaultFormalParameter_parameter; +// return parameter.normalFormalParameter_isCovariant; +// } +// return linkedNode.normalFormalParameter_isCovariant; +// } if (isExplicitlyCovariant || inheritsCovariant) { return true; } @@ -8077,7 +8130,8 @@ @override bool get isFinal { if (linkedNode != null) { - return enclosingUnit.linkedContext.isFinal(linkedNode); + FormalParameter linkedNode = this.linkedNode; + return linkedNode.isFinal; } if (unlinkedParam != null) { return unlinkedParam.isFinal; @@ -8126,9 +8180,7 @@ @override int get nameOffset { if (linkedNode != null) { - return enclosingUnit.linkedContext.getSimpleOffset( - linkedNode.normalFormalParameter_identifier, - ); + return enclosingUnit.linkedContext.getNameOffset(linkedNode); } int offset = super.nameOffset; @@ -8151,14 +8203,9 @@ if (_parameterKind != null) return _parameterKind; if (linkedNode != null) { - if (linkedNode.kind == LinkedNodeKind.defaultFormalParameter) { - if (linkedNode.defaultFormalParameter_isNamed) { - return _parameterKind = ParameterKind.NAMED; - } else { - return _parameterKind = ParameterKind.POSITIONAL; - } - } - return _parameterKind = ParameterKind.REQUIRED; + FormalParameter linkedNode = this.linkedNode; + // ignore: deprecated_member_use_from_same_package + return linkedNode.kind; } if (unlinkedParam != null) { switch (unlinkedParam.kind) { @@ -8191,7 +8238,7 @@ if (linkedNode != null) { if (_type != null) return _type; var context = enclosingUnit.linkedContext; - return _type = context.getFormalParameterType(linkedNode); + return _type = context.getType(linkedNode); } _resynthesizeTypeAndParameters(); return super.type; @@ -8305,18 +8352,18 @@ ElementImpl enclosing, LinkedUnitContext context, Reference containerRef, - List<LinkedNode> formalParameters) { + List<FormalParameter> formalParameters) { if (formalParameters == null) { return const []; } return formalParameters.map((node) { - if (node.kind == LinkedNodeKind.defaultFormalParameter) { - var parameterNode = node.defaultFormalParameter_parameter; - var name = context.getFormalParameterName(parameterNode); + if (node is DefaultFormalParameter) { + NormalFormalParameter parameterNode = node.parameter; + var name = parameterNode.identifier.name; var reference = containerRef.getChild(name); - reference.node = node; - if (parameterNode.kind == LinkedNodeKind.fieldFormalParameter) { + reference.node2 = node; + if (parameterNode is FieldFormalParameter) { return DefaultFieldFormalParameterElementImpl.forLinkedNode( enclosing, reference, @@ -8330,14 +8377,17 @@ ); } } else { - var name = context.getFormalParameterName(node); + var name = node.identifier.name; var reference = containerRef.getChild(name); - reference.node = node; - return ParameterElementImpl.forLinkedNodeFactory( - enclosing, - reference, - node, - ); + if (reference.element == null) { + reference.node2 = node; + ParameterElementImpl.forLinkedNodeFactory( + enclosing, + reference, + node, + ); + } + return reference.element as ParameterElement; } }).toList(); } @@ -8465,7 +8515,7 @@ super(name, nameOffset); PrefixElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + ElementImpl enclosing, Reference reference, SimpleIdentifier linkedNode) : _unlinkedImport = null, super.forLinkedNode(enclosing, reference, linkedNode); @@ -8510,8 +8560,7 @@ @override int get nameOffset { if (linkedNode != null) { - LibraryElementImpl library = enclosingElement; - return library.linkedContext.getSimpleOffset(linkedNode); + return (linkedNode as SimpleIdentifier).offset; } int offset = super.nameOffset; if (offset == 0 && _unlinkedImport != null) { @@ -8541,7 +8590,7 @@ PropertyAccessorElementImpl(String name, int offset) : super(name, offset); PropertyAccessorElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + ElementImpl enclosing, Reference reference, AstNode linkedNode) : super.forLinkedNode(enclosing, reference, linkedNode); /// Initialize a newly created property accessor element to have the given @@ -8614,14 +8663,6 @@ } @override - bool get isAbstract { - if (linkedNode != null) { - return enclosingUnit.linkedContext.isAbstract(linkedNode); - } - return super.isAbstract; - } - - @override bool get isGetter { if (linkedNode != null) { return enclosingUnit.linkedContext.isGetter(linkedNode); @@ -8813,7 +8854,7 @@ PropertyInducingElementImpl(String name, int offset) : super(name, offset); PropertyInducingElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + ElementImpl enclosing, Reference reference, AstNode linkedNode) : super.forLinkedNode(enclosing, reference, linkedNode); /// Initialize a newly created element to have the given [name]. @@ -8838,9 +8879,7 @@ DartType get type { if (linkedNode != null) { if (_type != null) return _type; - return _type = enclosingUnit.linkedContext.getType( - linkedNode.variableDeclaration_type2, - ); + return _type = enclosingUnit.linkedContext.getType(linkedNode); } if (isSynthetic && _type == null) { if (getter != null) { @@ -8914,7 +8953,7 @@ final UnlinkedCombinator _unlinkedCombinator; final LinkedUnitContext linkedContext; - final LinkedNode linkedNode; + final ShowCombinator linkedNode; /// The names that are to be made visible in the importing library if they are /// defined in the imported library. @@ -8956,7 +8995,7 @@ @override int get offset { if (linkedNode != null) { - return linkedContext.getTokenOffset(linkedNode.combinator_keyword); + return linkedNode.keyword.offset; } if (_unlinkedCombinator != null) { return _unlinkedCombinator.offset; @@ -8974,9 +9013,7 @@ if (_shownNames != null) return _shownNames; if (linkedNode != null) { - return _shownNames = linkedNode.showCombinator_shownNames - .map((node) => linkedContext.getSimpleName(node)) - .toList(); + return _shownNames = linkedNode.shownNames.map((i) => i.name).toList(); } if (_unlinkedCombinator != null) { @@ -9037,7 +9074,7 @@ TopLevelVariableElementImpl(String name, int offset) : super(name, offset); TopLevelVariableElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + ElementImpl enclosing, Reference reference, AstNode linkedNode) : super.forLinkedNode(enclosing, reference, linkedNode) { if (!linkedNode.isSynthetic) { var enclosingRef = enclosing.reference; @@ -9057,7 +9094,7 @@ } factory TopLevelVariableElementImpl.forLinkedNodeFactory( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) { + ElementImpl enclosing, Reference reference, AstNode linkedNode) { if (enclosing.enclosingUnit.linkedContext.isConst(linkedNode)) { return ConstTopLevelVariableElementImpl.forLinkedNode( enclosing, @@ -9121,7 +9158,7 @@ TypeParameterElementImpl.forLinkedNode( TypeParameterizedElementMixin enclosing, Reference reference, - LinkedNode linkedNode) + TypeParameter linkedNode) : _unlinkedTypeParam = null, super.forLinkedNode(enclosing, reference, linkedNode); @@ -9148,13 +9185,8 @@ if (_bound != null) return _bound; if (linkedNode != null) { - var bound = linkedNode.typeParameter_bound; - if (bound != null) { - var context = enclosingUnit.linkedContext; - return _bound = context.getTypeAnnotationType(bound); - } else { - return null; - } + var context = enclosingUnit.linkedContext; + return _bound = context.getTypeParameterBound(linkedNode)?.type; } if (_unlinkedTypeParam != null) { @@ -9177,7 +9209,7 @@ @override int get codeLength { if (linkedNode != null) { - return linkedNode.codeLength; + return linkedContext.getCodeLength(linkedNode); } if (_unlinkedTypeParam != null) { return _unlinkedTypeParam.codeRange?.length; @@ -9188,7 +9220,7 @@ @override int get codeOffset { if (linkedNode != null) { - return linkedNode.codeOffset; + return linkedContext.getCodeOffset(linkedNode); } if (_unlinkedTypeParam != null) { return _unlinkedTypeParam.codeRange?.offset; @@ -9290,15 +9322,18 @@ if (linkedNode != null) { var context = enclosingUnit.linkedContext; var containerRef = reference.getChild('@typeParameter'); - var typeParameters = LinkedUnitContext.getTypeParameters(linkedNode); + var typeParameters = context.getTypeParameters2(linkedNode); if (typeParameters == null) { return _typeParameterElements = const []; } - return _typeParameterElements = typeParameters.map((node) { - var name = context.getSimpleName(node.typeParameter_name); + return _typeParameterElements = typeParameters.typeParameters.map((node) { + var name = node.name.name; var reference = containerRef.getChild(name); - reference.node = node; - return TypeParameterElementImpl.forLinkedNode(this, reference, node); + if (reference.element == null) { + reference.node2 = node; + TypeParameterElementImpl.forLinkedNode(this, reference, node); + } + return reference.element as TypeParameterElementImpl; }).toList(); } @@ -9411,7 +9446,7 @@ UriReferencedElementImpl(String name, int offset) : super(name, offset); UriReferencedElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + ElementImpl enclosing, Reference reference, AstNode linkedNode) : super.forLinkedNode(enclosing, reference, linkedNode); /// Initialize using the given serialized information. @@ -9475,7 +9510,7 @@ VariableElementImpl(String name, int offset) : super(name, offset); VariableElementImpl.forLinkedNode( - ElementImpl enclosing, Reference reference, LinkedNode linkedNode) + ElementImpl enclosing, Reference reference, AstNode linkedNode) : super.forLinkedNode(enclosing, reference, linkedNode); /// Initialize a newly created variable element to have the given [name]. @@ -9498,9 +9533,9 @@ DartObject get constantValue => evaluationResult?.value; void set declaredType(DartType type) { - if (linkedNode != null) { - enclosingUnit.linkedContext.setVariableType(linkedNode, type); - } +// if (linkedNode != null) { +// enclosingUnit.linkedContext.setVariableType(linkedNode, type); +// } _declaredType = _checkElementOfType(type); }
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart index 67f47f7..7384095d 100644 --- a/pkg/analyzer/lib/src/dart/element/handle.dart +++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -395,6 +395,9 @@ bool get hasLiteral => actualElement.hasLiteral; @override + bool get hasOptionalTypeArgs => actualElement.hasOptionalTypeArgs; + + @override bool get hasOverride => actualElement.hasOverride; @override
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart index 845d59d..7472796 100644 --- a/pkg/analyzer/lib/src/dart/element/member.dart +++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -425,6 +425,9 @@ bool get hasLiteral => _baseElement.hasLiteral; @override + bool get hasOptionalTypeArgs => _baseElement.hasOptionalTypeArgs; + + @override bool get hasOverride => _baseElement.hasOverride; @override
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart new file mode 100644 index 0000000..b3fd95f --- /dev/null +++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -0,0 +1,292 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/type.dart'; +import 'package:analyzer/src/dart/element/element.dart'; +import 'package:analyzer/src/dart/element/type.dart'; +import 'package:analyzer/src/dart/element/type_visitor.dart'; + +/// Returns a type where all occurrences of the given type parameters have been +/// replaced with the corresponding types. +/// +/// This will copy only the sub-terms of [type] that contain substituted +/// variables; all other [DartType] objects will be reused. +/// +/// In particular, if no type parameters were substituted, this is guaranteed +/// to return the [type] instance (not a copy), so the caller may use +/// [identical] to efficiently check if a distinct type was created. +DartType substitute( + DartType type, + Map<TypeParameterElement, DartType> substitution, +) { + if (substitution.isEmpty) { + return type; + } + return Substitution.fromMap(substitution).substituteType(type); +} + +abstract class Substitution { + static const Substitution empty = _NullSubstitution.instance; + + const Substitution(); + + DartType getSubstitute(TypeParameterElement parameter, bool upperBound); + + DartType substituteType(DartType type, {bool contravariant: false}) { + return new _TopSubstitutor(this, contravariant).visit(type); + } + + /// Substitutes the type parameters on the class of [type] with the + /// type arguments provided in [type]. + static Substitution fromInterfaceType(InterfaceType type) { + if (type.typeArguments.isEmpty) { + return _NullSubstitution.instance; + } + return fromPairs(type.element.typeParameters, type.typeArguments); + } + + /// Substitutes each parameter to the type it maps to in [map]. + static Substitution fromMap(Map<TypeParameterElement, DartType> map) { + if (map.isEmpty) { + return _NullSubstitution.instance; + } + return new _MapSubstitution(map, map); + } + + /// Substitutes the Nth parameter in [parameters] with the Nth type in + /// [types]. + static Substitution fromPairs( + List<TypeParameterElement> parameters, + List<DartType> types, + ) { + assert(parameters.length == types.length); + if (parameters.isEmpty) { + return _NullSubstitution.instance; + } + return fromMap( + new Map<TypeParameterElement, DartType>.fromIterables( + parameters, + types, + ), + ); + } + + /// Substitutes all occurrences of the given type parameters with the + /// corresponding upper or lower bound, depending on the variance of the + /// context where it occurs. + /// + /// For example the type `(T) => T` with the bounds `bottom <: T <: num` + /// becomes `(bottom) => num` (in this example, `num` is the upper bound, + /// and `bottom` is the lower bound). + /// + /// This is a way to obtain an upper bound for a type while eliminating all + /// references to certain type variables. + static Substitution fromUpperAndLowerBounds( + Map<TypeParameterElement, DartType> upper, + Map<TypeParameterElement, DartType> lower, + ) { + if (upper.isEmpty && lower.isEmpty) { + return _NullSubstitution.instance; + } + return new _MapSubstitution(upper, lower); + } +} + +class _FreshTypeParametersSubstitutor extends _TypeSubstitutor { + final Map<TypeParameterElement, DartType> substitution = {}; + + _FreshTypeParametersSubstitutor(_TypeSubstitutor outer) : super(outer); + + TypeParameterElement freshTypeParameter(TypeParameterElement element) { + var freshElement = new TypeParameterElementImpl(element.name, -1); + var freshType = new TypeParameterTypeImpl(freshElement); + freshElement.type = freshType; + substitution[element] = freshType; + if (element.bound != null) { + freshElement.bound = visit(element.bound); + } + return freshElement; + } + + DartType lookup(TypeParameterElement parameter, bool upperBound) { + return substitution[parameter]; + } +} + +class _MapSubstitution extends Substitution { + final Map<TypeParameterElement, DartType> upper; + final Map<TypeParameterElement, DartType> lower; + + _MapSubstitution(this.upper, this.lower); + + DartType getSubstitute(TypeParameterElement parameter, bool upperBound) { + return upperBound ? upper[parameter] : lower[parameter]; + } +} + +class _NullSubstitution extends Substitution { + static const _NullSubstitution instance = const _NullSubstitution(); + + const _NullSubstitution(); + + DartType getSubstitute(TypeParameterElement parameter, bool upperBound) { + return new TypeParameterTypeImpl(parameter); + } + + @override + DartType substituteType(DartType type, {bool contravariant: false}) => type; +} + +class _TopSubstitutor extends _TypeSubstitutor { + final Substitution substitution; + + _TopSubstitutor(this.substitution, bool contravariant) : super(null) { + if (contravariant) { + invertVariance(); + } + } + + @override + TypeParameterElement freshTypeParameter(TypeParameterElement element) { + throw 'Create a fresh environment first'; + } + + @override + DartType lookup(TypeParameterElement parameter, bool upperBound) { + return substitution.getSubstitute(parameter, upperBound); + } +} + +abstract class _TypeSubstitutor extends DartTypeVisitor<DartType> { + final _TypeSubstitutor outer; + bool covariantContext = true; + + /// The number of times a variable from this environment has been used in + /// a substitution. + /// + /// There is a strict requirement that we must return the same instance for + /// types that were not altered by the substitution. This counter lets us + /// check quickly if anything happened in a substitution. + int useCounter = 0; + + _TypeSubstitutor(this.outer) { + covariantContext = outer == null ? true : outer.covariantContext; + } + + void bumpCountersUntil(_TypeSubstitutor target) { + var substitutor = this; + while (substitutor != target) { + substitutor.useCounter++; + substitutor = substitutor.outer; + } + target.useCounter++; + } + + TypeParameterElement freshTypeParameter(TypeParameterElement element); + + List<TypeParameterElement> freshTypeParameters( + List<TypeParameterElement> parameters) { + if (parameters.isEmpty) { + return const <TypeParameterElement>[]; + } + return parameters.map(freshTypeParameter).toList(); + } + + DartType getSubstitute(TypeParameterElement parameter) { + var environment = this; + while (environment != null) { + var replacement = environment.lookup(parameter, covariantContext); + if (replacement != null) { + bumpCountersUntil(environment); + return replacement; + } + environment = environment.outer; + } + return null; + } + + void invertVariance() { + covariantContext = !covariantContext; + } + + DartType lookup(TypeParameterElement parameter, bool upperBound); + + _FreshTypeParametersSubstitutor newInnerEnvironment() { + return new _FreshTypeParametersSubstitutor(this); + } + + DartType visit(DartType type) { + return DartTypeVisitor.visit(type, this); + } + + @override + DartType visitBottomType(BottomTypeImpl type) => type; + + @override + DartType visitDynamicType(DynamicTypeImpl type) => type; + + @override + DartType visitFunctionType(FunctionType type) { + // This is a bit tricky because we have to generate fresh type parameters + // in order to change the bounds. At the same time, if the function type + // was unaltered, we have to return the [type] object (not a copy!). + // Substituting a type for a fresh type variable should not be confused + // with a "real" substitution. + // + // Create an inner environment to generate fresh type parameters. The use + // counter on the inner environment tells if the fresh type parameters have + // any uses, but does not tell if the resulting function type is distinct. + // Our own use counter will get incremented if something from our + // environment has been used inside the function. + var inner = type.typeFormals.isEmpty ? this : newInnerEnvironment(); + int before = this.useCounter; + + // Invert the variance when translating parameters. + inner.invertVariance(); + + var typeFormals = inner.freshTypeParameters(type.typeFormals); + + var parameters = type.parameters.map((parameter) { + var type = inner.visit(parameter.type); + return ParameterElementImpl.synthetic( + parameter.name, + type, + // ignore: deprecated_member_use_from_same_package + parameter.parameterKind, + ); + }).toList(); + + inner.invertVariance(); + + var returnType = inner.visit(type.returnType); + + if (this.useCounter == before) return type; + + return FunctionTypeImpl.synthetic(returnType, typeFormals, parameters); + } + + @override + DartType visitInterfaceType(InterfaceType type) { + if (type.typeArguments.isEmpty) { + return type; + } + + int before = useCounter; + var typeArguments = type.typeArguments.map(visit).toList(); + if (useCounter == before) { + return type; + } + + return new InterfaceTypeImpl.explicit(type.element, typeArguments); + } + + @override + DartType visitTypeParameterType(TypeParameterType type) { + return getSubstitute(type.element) ?? type; + } + + @override + DartType visitVoidType(VoidType type) => type; +}
diff --git a/pkg/analyzer/lib/src/dart/element/type_visitor.dart b/pkg/analyzer/lib/src/dart/element/type_visitor.dart new file mode 100644 index 0000000..6b0ffbe --- /dev/null +++ b/pkg/analyzer/lib/src/dart/element/type_visitor.dart
@@ -0,0 +1,46 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/dart/element/type.dart'; +import 'package:analyzer/src/dart/element/type.dart'; + +class DartTypeVisitor<R> { + const DartTypeVisitor(); + + R defaultDartType(DartType type) => null; + + R visitBottomType(BottomTypeImpl type) => defaultDartType(type); + + R visitDynamicType(DynamicTypeImpl type) => defaultDartType(type); + + R visitFunctionType(FunctionType type) => defaultDartType(type); + + R visitInterfaceType(InterfaceType type) => defaultDartType(type); + + R visitTypeParameterType(TypeParameterType type) => defaultDartType(type); + + R visitVoidType(VoidType type) => defaultDartType(type); + + static R visit<R>(DartType type, DartTypeVisitor<R> visitor) { + if (type is BottomTypeImpl) { + return visitor.visitBottomType(type); + } + if (type is DynamicTypeImpl) { + return visitor.visitDynamicType(type); + } + if (type is FunctionType) { + return visitor.visitFunctionType(type); + } + if (type is InterfaceType) { + return visitor.visitInterfaceType(type); + } + if (type is TypeParameterType) { + return visitor.visitTypeParameterType(type); + } + if (type is VoidType) { + return visitor.visitVoidType(type); + } + throw UnimplementedError('(${type.runtimeType}) $type'); + } +}
diff --git a/pkg/analyzer/lib/src/dart/element/wrapped.dart b/pkg/analyzer/lib/src/dart/element/wrapped.dart index 984a7b1..5aebd1d 100644 --- a/pkg/analyzer/lib/src/dart/element/wrapped.dart +++ b/pkg/analyzer/lib/src/dart/element/wrapped.dart
@@ -71,6 +71,9 @@ bool get hasLoadLibraryFunction => wrappedUnit.hasLoadLibraryFunction; @override + bool get hasOptionalTypeArgs => wrappedUnit.hasOptionalTypeArgs; + + @override bool get hasOverride => wrappedUnit.hasOverride; @override @@ -261,6 +264,9 @@ bool get hasLiteral => wrappedImport.hasLiteral; @override + bool get hasOptionalTypeArgs => wrappedImport.hasOptionalTypeArgs; + + @override bool get hasOverride => wrappedImport.hasOverride; @override @@ -466,6 +472,9 @@ bool get hasLoadLibraryFunction => wrappedLib.hasLoadLibraryFunction; @override + bool get hasOptionalTypeArgs => wrappedLib.hasOptionalTypeArgs; + + @override bool get hasOverride => wrappedLib.hasOverride; @override
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart index 67fbccc..6e31a4b 100644 --- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart +++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -693,6 +693,8 @@ static const ParserErrorCode TYPE_ARGUMENTS_ON_TYPE_VARIABLE = _TYPE_ARGUMENTS_ON_TYPE_VARIABLE; + static const ParserErrorCode TYPE_BEFORE_FACTORY = _TYPE_BEFORE_FACTORY; + static const ParserErrorCode TYPEDEF_IN_CLASS = _TYPEDEF_IN_CLASS; /** @@ -716,7 +718,7 @@ static const ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER = const ParserErrorCode('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER', - "The default value of a positional parameter should be preceeded by '='.", + "The default value of a positional parameter should be preceded by '='.", correction: "Try replacing the ':' with '='."); /**
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart index 598d093..b12e351 100644 --- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart +++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -104,6 +104,7 @@ _EXPECTED_ELSE_OR_COMMA, _INVALID_SUPER_IN_INITIALIZER, _INVALID_THIS_IN_INITIALIZER, + _TYPE_BEFORE_FACTORY, ]; const ParserErrorCode _ABSTRACT_CLASS_MEMBER = const ParserErrorCode( @@ -216,7 +217,7 @@ const ParserErrorCode _DUPLICATED_MODIFIER = const ParserErrorCode( 'DUPLICATED_MODIFIER', r"The modifier '#lexeme' was already specified.", - correction: "Try removing all but one occurance of the modifier."); + correction: "Try removing all but one occurence of the modifier."); const ParserErrorCode _DUPLICATE_DEFERRED = const ParserErrorCode( 'DUPLICATE_DEFERRED', @@ -256,7 +257,7 @@ const ParserErrorCode _EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE = const ParserErrorCode('EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE', - r"Export directives must preceed part directives.", + r"Export directives must precede part directives.", correction: "Try moving the export directives before the part directives."); @@ -360,7 +361,7 @@ const ParserErrorCode _IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE = const ParserErrorCode('IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE', - r"Import directives must preceed part directives.", + r"Import directives must precede part directives.", correction: "Try moving the import directives before the part directives."); @@ -438,7 +439,7 @@ const ParserErrorCode _MISSING_KEYWORD_OPERATOR = const ParserErrorCode( 'MISSING_KEYWORD_OPERATOR', - r"Operator declarations must be preceeded by the keyword 'operator'.", + r"Operator declarations must be preceded by the keyword 'operator'.", correction: "Try adding the keyword 'operator'."); const ParserErrorCode _MISSING_PREFIX_IN_DEFERRED_IMPORT = @@ -550,6 +551,10 @@ r"Can't use type arguments with type variable '#name'.", correction: "Try removing the type arguments."); +const ParserErrorCode _TYPE_BEFORE_FACTORY = const ParserErrorCode( + 'TYPE_BEFORE_FACTORY', r"Factory constructors cannot have a return type.", + correction: "Try removing the type appearing before 'factory'."); + const ParserErrorCode _VAR_AND_TYPE = const ParserErrorCode('VAR_AND_TYPE', r"Variables can't be declared using both 'var' and a type name.", correction: "Try removing 'var.'");
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart index 41a977e..570fc8f 100644 --- a/pkg/analyzer/lib/src/error/codes.dart +++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -331,7 +331,7 @@ "Class '{0}' can't define field '{1}' and have method '{2}.{1}' " "with the same name.", correction: "Try converting the getter to a method, or " - "renaming the field to a name that doesn't conflit."); + "renaming the field to a name that doesn't conflict."); /** * 10.10 Superinterfaces: It is a compile-time error if a class `C` has two @@ -366,7 +366,7 @@ "Class '{0}' can't define method '{1}' and have field '{2}.{1}' " "with the same name.", correction: "Try converting the method to a getter, or " - "renaming the method to a name that doesn't conflit."); + "renaming the method to a name that doesn't conflict."); /** * 10.11 Class Member Conflicts: Let `C` be a class. It is a compile-time @@ -384,7 +384,7 @@ "Class '{0}' can't define static member '{1}' and have instance " "member '{2}.{1}' with the same name.", correction: - "Try renaming the member to a name that doesn't conflit."); + "Try renaming the member to a name that doesn't conflict."); /** * 7. Classes: It is a compile time error if a generic class declares a type @@ -761,7 +761,7 @@ static const CompileTimeErrorCode CONST_WITH_UNDEFINED_CONSTRUCTOR = const CompileTimeErrorCode('CONST_WITH_UNDEFINED_CONSTRUCTOR', "The class '{0}' doesn't have a constant constructor '{1}'.", - correction: "Try calling a different contructor."); + correction: "Try calling a different constructor."); /** * 16.12.2 Const: It is a compile-time error if <i>T.id</i> is not the name of @@ -773,7 +773,7 @@ static const CompileTimeErrorCode CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT = const CompileTimeErrorCode('CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT', "The class '{0}' doesn't have a default constant constructor.", - correction: "Try calling a different contructor."); + correction: "Try calling a different constructor."); /** * 15.3.1 Typedef: It is a compile-time error if any default values are @@ -1173,7 +1173,7 @@ static const CompileTimeErrorCode IMPLEMENTS_REPEATED = const CompileTimeErrorCode( 'IMPLEMENTS_REPEATED', "'{0}' can only be implemented once.", - correction: "Try removing all but one occurance of the class name."); + correction: "Try removing all but one occurrence of the class name."); /** * 7.10 Superinterfaces: It is a compile-time error if the superclass of a @@ -1186,7 +1186,7 @@ static const CompileTimeErrorCode IMPLEMENTS_SUPER_CLASS = const CompileTimeErrorCode('IMPLEMENTS_SUPER_CLASS', "'{0}' can't be used in both 'extends' and 'implements' clauses.", - correction: "Try removing one of the occurances."); + correction: "Try removing one of the occurrences."); /** * 7.6.1 Generative Constructors: Note that <b>this</b> is not in scope on the @@ -2184,6 +2184,10 @@ 'NOT_MAP_SPREAD', "Spread elements in map literals must implement 'Map'."); + static const CompileTimeErrorCode NOT_NULL_AWARE_NULL_SPREAD = + const CompileTimeErrorCode('NOT_NULL_AWARE_NULL_SPREAD', + "The Null typed expression can't be used with a non-null-aware spread."); + /** * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the * superinitializer appears and let <i>S</i> be the superclass of <i>C</i>. @@ -2217,7 +2221,7 @@ static const CompileTimeErrorCode ON_REPEATED = const CompileTimeErrorCode( 'ON_REPEATED', "'{0}' can only be used in super-class constraints only once.", - correction: "Try removing all but one occurance of the class name."); + correction: "Try removing all but one occurrence of the class name."); /** * 7.1.1 Operators: It is a compile-time error to declare an optional
diff --git a/pkg/analyzer/lib/src/error/literal_element_verifier.dart b/pkg/analyzer/lib/src/error/literal_element_verifier.dart index 29b65b9..89dcdce 100644 --- a/pkg/analyzer/lib/src/error/literal_element_verifier.dart +++ b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
@@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer/dart/ast/token.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/error/listener.dart'; import 'package:analyzer/src/dart/element/type.dart'; @@ -82,11 +83,13 @@ CompileTimeErrorCode.MAP_ENTRY_NOT_IN_MAP, element); } } else if (element is SpreadElement) { + var isNullAware = element.spreadOperator.type == + TokenType.PERIOD_PERIOD_PERIOD_QUESTION; Expression expression = element.expression; if (forList || forSet) { - _verifySpreadForListOrSet(expression); + _verifySpreadForListOrSet(isNullAware, expression); } else if (forMap) { - _verifySpreadForMap(expression); + _verifySpreadForMap(isNullAware, expression); } } } @@ -123,12 +126,19 @@ /// Verify that the type of the elements of the given [expression] can be /// assigned to the [elementType] of the enclosing collection. - void _verifySpreadForListOrSet(Expression expression) { + void _verifySpreadForListOrSet(bool isNullAware, Expression expression) { var expressionType = expression.staticType; if (expressionType.isDynamic) return; - // TODO(scheglov) Check for non-null-aware spread? - if (expressionType.isDartCoreNull) return; + if (expressionType.isDartCoreNull) { + if (!isNullAware) { + errorReporter.reportErrorForNode( + CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD, + expression, + ); + } + return; + } InterfaceType iterableType; var iterableObjectType = typeProvider.iterableObjectType; @@ -161,12 +171,19 @@ /// Verify that the [expression] is a subtype of `Map<Object, Object>`, and /// its key and values are assignable to [mapKeyType] and [mapValueType]. - void _verifySpreadForMap(Expression expression) { + void _verifySpreadForMap(bool isNullAware, Expression expression) { var expressionType = expression.staticType; if (expressionType.isDynamic) return; - // TODO(scheglov) Check for non-null-aware spread? - if (expressionType.isDartCoreNull) return; + if (expressionType.isDartCoreNull) { + if (!isNullAware) { + errorReporter.reportErrorForNode( + CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD, + expression, + ); + } + return; + } InterfaceType mapType; var mapObjectObjectType = typeProvider.mapObjectObjectType;
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart index b4a0bda..ea8336f 100644 --- a/pkg/analyzer/lib/src/generated/constant.dart +++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -4,6 +4,7 @@ import 'package:analyzer/dart/analysis/declared_variables.dart'; import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer/error/error.dart'; import 'package:analyzer/error/listener.dart'; import 'package:analyzer/src/dart/constant/evaluation.dart'; import 'package:analyzer/src/dart/constant/value.dart'; @@ -128,9 +129,15 @@ new ConstantEvaluationEngine(_typeProvider, new DeclaredVariables(), typeSystem: _typeSystem), errorReporter)); + List<AnalysisError> errors = errorListener.errors; + if (errors.isNotEmpty) { + return EvaluationResult.forErrors(errors); + } if (result != null) { return EvaluationResult.forValue(result); } - return EvaluationResult.forErrors(errorListener.errors); + // We should not get here. Either there should be a valid value or there + // should be an error explaining why a value could not be generated. + return EvaluationResult.forErrors(errors); } }
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart index cdffbef..0c23f5c 100644 --- a/pkg/analyzer/lib/src/generated/engine.dart +++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -733,6 +733,11 @@ static const String PUBSPEC_YAML_FILE = 'pubspec.yaml'; /** + * The file name used for Android manifest files. + */ + static const String ANDROID_MANIFEST_FILE = 'AndroidManifest.xml'; + + /** * The unique instance of this class. */ static final AnalysisEngine instance = new AnalysisEngine._(); @@ -1023,6 +1028,12 @@ @deprecated int get cacheSize; + /* + * A flag indicating whether to run checks on AndroidManifest.xml file to + * see if it is complaint with Chrome OS. + */ + bool get chromeOsManifestChecks; + /** * Return `true` if analysis is to generate dart2js related hint results. */ @@ -1391,6 +1402,9 @@ */ bool strictRawTypes = false; + @override + bool chromeOsManifestChecks = false; + /** * Initialize a newly created set of analysis options to have their default * values.
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart index c372f0d..236bfe4 100644 --- a/pkg/analyzer/lib/src/generated/error_verifier.dart +++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -4739,17 +4739,8 @@ return; } } - if (element.metadata.isNotEmpty) { - for (var annotation in element.metadata) { - var e = annotation.element; - // TODO(jmesserly): similar "package:meta" annotations are added to - // the element as boolean getters, that may be worth considering. - if (e?.name == 'optionalTypeArgs' && - e.librarySource.uri.toString() == 'package:meta/meta.dart') { - // Type is marked with `@optionalTypeArgs`: not an error. - return; - } - } + if (element.hasOptionalTypeArgs) { + return; } _errorReporter.reportErrorForNode(HintCode.STRICT_RAW_TYPE, node, [type]); }
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart index a6fdb03..fa863d1 100644 --- a/pkg/analyzer/lib/src/generated/resolver.dart +++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -5164,7 +5164,7 @@ FunctionType _inferArgumentTypesForGeneric(AstNode inferenceNode, DartType uninstantiatedType, TypeArgumentList typeArguments, - {AstNode errorNode}) { + {AstNode errorNode, bool isConst: false}) { errorNode ??= inferenceNode; TypeSystem ts = typeSystem; if (typeArguments == null && @@ -5177,6 +5177,7 @@ const <DartType>[], InferenceContext.getContext(inferenceNode), downwards: true, + isConst: isConst, errorReporter: errorReporter, errorNode: errorNode); } @@ -5218,7 +5219,7 @@ inferred = _inferArgumentTypesForGeneric( node, constructorType, constructor.type.typeArguments, - errorNode: node.constructorName); + isConst: node.isConst, errorNode: node.constructorName); if (inferred != null) { ArgumentList arguments = node.argumentList;
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart index f3b066e..682b4f3 100644 --- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart +++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -175,6 +175,7 @@ InterfaceType inferred = ts.inferGenericFunctionOrType<InterfaceType>( _typeProvider.listType, parameters, elementTypes, contextType, downwards: downwards, + isConst: node.isConst, errorReporter: _resolver.errorReporter, errorNode: node); return inferred; @@ -190,6 +191,7 @@ ParameterizedType inferred = ts.inferGenericFunctionOrType( _typeProvider.mapType, [], [], contextType, downwards: true, + isConst: node.isConst, errorReporter: _resolver.errorReporter, errorNode: node); return inferred; @@ -204,6 +206,7 @@ DartType inferred = ts.inferGenericFunctionOrType<InterfaceType>( _typeProvider.setType, [], [], contextType, downwards: true, + isConst: node.isConst, errorReporter: _resolver.errorReporter, errorNode: node); return inferred; @@ -1546,7 +1549,8 @@ DartType fnType, TypeArgumentList typeArguments, ArgumentList argumentList, - AstNode errorNode) { + AstNode errorNode, + {bool isConst: false}) { TypeSystem ts = _typeSystem; if (typeArguments == null && fnType is FunctionType && @@ -1568,7 +1572,9 @@ } return ts.inferGenericFunctionOrType( fnType, params, argTypes, InferenceContext.getContext(node), - errorReporter: _resolver.errorReporter, errorNode: errorNode); + isConst: isConst, + errorReporter: _resolver.errorReporter, + errorNode: errorNode); } return null; } @@ -1606,7 +1612,8 @@ ArgumentList arguments = node.argumentList; FunctionType inferred = _inferGenericInvoke(node, constructorType, - constructor.type.typeArguments, arguments, node.constructorName); + constructor.type.typeArguments, arguments, node.constructorName, + isConst: node.isConst); if (inferred != null && inferred != originalElement.type) { // Fix up the parameter elements based on inferred method. @@ -1888,7 +1895,9 @@ ..addAll(valueTypes); return (_typeSystem as Dart2TypeSystem).inferGenericFunctionOrType( _typeProvider.mapType, typeParameters, elementTypes, contextType, - errorReporter: _resolver.errorReporter, errorNode: node); + isConst: node.isConst, + errorReporter: _resolver.errorReporter, + errorNode: node); } DartType _toSetType(SetOrMapLiteral node, DartType contextType, @@ -1908,7 +1917,9 @@ growable: true); return (_typeSystem as Dart2TypeSystem).inferGenericFunctionOrType( _typeProvider.setType, parameters, elementTypes, contextType, - errorReporter: _resolver.errorReporter, errorNode: node); + isConst: node.isConst, + errorReporter: _resolver.errorReporter, + errorNode: node); } /**
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart index 969cac5..ec1a06f 100644 --- a/pkg/analyzer/lib/src/generated/type_system.dart +++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -225,7 +225,8 @@ DartType returnContextType, {ErrorReporter errorReporter, AstNode errorNode, - bool downwards: false}) { + bool downwards: false, + bool isConst: false}) { // TODO(jmesserly): expose typeFormals on ParameterizedType. List<TypeParameterElement> typeFormals = typeFormalsAsElements(genericType); if (typeFormals.isEmpty) { @@ -242,6 +243,9 @@ genericType is FunctionType ? genericType.returnType : genericType; if (returnContextType != null) { + if (isConst) { + returnContextType = _eliminateTypeVariables(returnContextType); + } inferrer.constrainReturnType(declaredReturnType, returnContextType); } @@ -652,6 +656,30 @@ } /** + * Eliminates type variables from the context [type], replacing them with + * `Null` or `Object` as appropriate. + * + * For example in `List<T> list = const []`, the context type for inferring + * the list should be changed from `List<T>` to `List<Null>` so the constant + * doesn't depend on the type variables `T` (because it can't be canonicalized + * at compile time, as `T` is unknown). + * + * Conceptually this is similar to the "least closure", except instead of + * eliminating `?` ([UnknownInferredType]) it eliminates all type variables + * ([TypeParameterType]). + * + * The equivalent CFE code can be found in the `TypeVariableEliminator` class. + */ + DartType _eliminateTypeVariables(DartType type) { + return _substituteType(type, true, (type, lowerBound) { + if (type is TypeParameterType) { + return lowerBound ? typeProvider.nullType : typeProvider.objectType; + } + return type; + }); + } + + /** * Compute the greatest lower bound of function types [f] and [g]. * * The spec rules for GLB on function types, informally, are pretty simple: @@ -891,19 +919,43 @@ return false; } + /** + * Returns the greatest or least closure of [type], which replaces `?` + * ([UnknownInferredType]) with `dynamic` or `Null` as appropriate. + * + * If [lowerBound] is true, this will return the "least closure", otherwise + * it returns the "greatest closure". + */ DartType _substituteForUnknownType(DartType type, {bool lowerBound: false}) { - if (identical(type, UnknownInferredType.instance)) { - if (lowerBound) { - // TODO(jmesserly): this should be the bottom type, once it can be - // reified. - return typeProvider.nullType; + return _substituteType(type, lowerBound, (type, lowerBound) { + if (identical(type, UnknownInferredType.instance)) { + return lowerBound ? typeProvider.nullType : typeProvider.dynamicType; } - return typeProvider.dynamicType; + return type; + }); + } + + /** + * Apply the [visitType] substitution to [type], using the result value if + * different, otherwise recursively apply the substitution. + * + * This method is used for substituting `?` ([UnknownInferredType]) with its + * greatest/least closure, and for eliminating type parameters for inference + * of `const` objects. + * + * See also [_eliminateTypeVariables] and [_substituteForUnknownType]. + */ + DartType _substituteType(DartType type, bool lowerBound, + DartType Function(DartType, bool) visitType) { + // Apply the substitution to this type, and return the result if different. + var newType = visitType(type, lowerBound); + if (!identical(newType, type)) { + return newType; } if (type is InterfaceTypeImpl) { // Generic types are covariant, so keep the constraint direction. - var newTypeArgs = _transformList(type.typeArguments, - (t) => _substituteForUnknownType(t, lowerBound: lowerBound)); + var newTypeArgs = _transformList( + type.typeArguments, (t) => _substituteType(t, lowerBound, visitType)); if (identical(type.typeArguments, newTypeArgs)) return type; return new InterfaceTypeImpl( type.element, type.prunedTypedefs, type.nullability) @@ -914,8 +966,7 @@ var returnType = type.returnType; var newParameters = _transformList(parameters, (ParameterElement p) { // Parameters are contravariant, so flip the constraint direction. - var newType = - _substituteForUnknownType(p.type, lowerBound: !lowerBound); + var newType = _substituteType(p.type, !lowerBound, visitType); return new ParameterElementImpl.synthetic( p.name, newType, @@ -923,8 +974,7 @@ p.parameterKind); }); // Return type is covariant. - var newReturnType = - _substituteForUnknownType(returnType, lowerBound: lowerBound); + var newReturnType = _substituteType(returnType, lowerBound, visitType); if (identical(parameters, newParameters) && identical(returnType, newReturnType)) { return type; @@ -1179,8 +1229,8 @@ ?.reportErrorForNode(StrongModeCode.COULD_NOT_INFER, errorNode, [ typeParam, ' Inferred candidate type $inferred has type parameters' - ' ${(inferred as FunctionType).typeFormals}, but a function with' - ' type parameters cannot be used as a type argument.' + ' ${(inferred as FunctionType).typeFormals}, but a function with' + ' type parameters cannot be used as a type argument.' ]); // Heuristic: Using a generic function type as a bound makes subtyping @@ -1211,8 +1261,8 @@ ?.reportErrorForNode(StrongModeCode.COULD_NOT_INFER, errorNode, [ typeParam, "\nRecursive bound cannot be instantiated: '$typeParamBound'." - "\nConsider passing explicit type argument(s) " - "to the generic.\n\n'" + "\nConsider passing explicit type argument(s) " + "to the generic.\n\n'" ]); } }
diff --git a/pkg/analyzer/lib/src/manifest/manifest_validator.dart b/pkg/analyzer/lib/src/manifest/manifest_validator.dart new file mode 100644 index 0000000..f18f9bd --- /dev/null +++ b/pkg/analyzer/lib/src/manifest/manifest_validator.dart
@@ -0,0 +1,112 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/error/error.dart'; +import 'package:analyzer/error/listener.dart'; +import 'package:analyzer/src/generated/source.dart'; +import 'package:html/dom.dart'; +import 'package:html/parser.dart' show parseFragment; +import 'package:source_span/source_span.dart'; + +import 'manifest_values.dart'; +import 'manifest_warning_code.dart'; + +class ManifestValidator { + /** + * The source representing the file being validated. + */ + final Source source; + + /** + * Initialize a newly create validator to validate the content of the given + * [source]. + */ + ManifestValidator(this.source); + + /* + * Validate the [contents] of the Android Manifest file. + */ + List<AnalysisError> validate(String contents, bool checkManifest) { + RecordingErrorListener recorder = new RecordingErrorListener(); + ErrorReporter reporter = new ErrorReporter(recorder, source); + + if (checkManifest) { + var document = + parseFragment(contents, container: MANIFEST_TAG, generateSpans: true); + var manifest = document.children.firstWhere( + (element) => element.localName == MANIFEST_TAG, + orElse: () => null); + var features = manifest?.getElementsByTagName(USES_FEATURE_TAG) ?? []; + var permissions = + manifest?.getElementsByTagName(USES_PERMISSION_TAG) ?? []; + + _validateFeatures(features, reporter); + _validatePermissions(permissions, features, reporter); + } + return recorder.errors; + } + + /* + * Validate the `uses-feature` tags. + */ + _validateFeatures(List<Element> features, ErrorReporter reporter) { + var unsupported = features + .where((element) => UNSUPPORTED_HARDWARE_FEATURES + .contains(element.attributes[ANDROID_NAME])) + .toList(); + unsupported.forEach((element) { + if (!element.attributes.containsKey(ANDROID_REQUIRED)) { + _reportErrorForNode(reporter, element, ANDROID_NAME, + ManifestWarningCode.UNSUPPORTED_CHROME_OS_HARDWARE); + } else if (element.attributes[ANDROID_REQUIRED] == true) { + _reportErrorForNode(reporter, element, ANDROID_NAME, + ManifestWarningCode.UNSUPPORTED_CHROME_OS_HARDWARE); + } + }); + } + + /* + * Validate the `uses-permission` tags. + */ + _validatePermissions(List<Element> permissions, List<Element> features, + ErrorReporter reporter) { + permissions.forEach((permission) { + if (permission.attributes[ANDROID_NAME] == ANDROID_PERMISSION_CAMERA) { + if (!_hasFeatureCamera(features) || + !_hasFeatureCameraAutoFocus(features)) { + _reportErrorForNode(reporter, permission, ANDROID_NAME, + ManifestWarningCode.CAMERA_PERMISSIONS_INCOMPATIBLE); + } + } else { + var featureName = + getImpliedUnsupportedHardware(permission.attributes[ANDROID_NAME]); + if (featureName != null) { + _reportErrorForNode( + reporter, + permission, + ANDROID_NAME, + ManifestWarningCode.PERMISSION_IMPLIES_UNSUPPORTED_HARDWARE, + [featureName]); + } + } + }); + } + + bool _hasFeatureCamera(List<Element> features) => + features.any((f) => f.localName == HARDWARE_FEATURE_CAMERA); + + bool _hasFeatureCameraAutoFocus(List<Element> features) => + features.any((f) => f.localName == HARDWARE_FEATURE_CAMERA_AUTOFOCUS); + + /** + * Report an error for the given node. + */ + void _reportErrorForNode( + ErrorReporter reporter, Node node, dynamic key, ErrorCode errorCode, + [List<Object> arguments]) { + FileSpan span = node.attributeValueSpans[key]; + reporter.reportErrorForOffset( + errorCode, span.start.offset, span.length, arguments); + } +}
diff --git a/pkg/analyzer/lib/src/manifest/manifest_values.dart b/pkg/analyzer/lib/src/manifest/manifest_values.dart new file mode 100644 index 0000000..ea1b59d --- /dev/null +++ b/pkg/analyzer/lib/src/manifest/manifest_values.dart
@@ -0,0 +1,101 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/* +* The arritbute values to check for compatibiltiy with Chrome OS. +* + */ + +const String MANIFEST_TAG = 'manifest'; + +const String USES_PERMISSION_TAG = 'uses-permission'; + +const String USES_FEATURE_TAG = 'uses-feature'; + +const String ANDROID_NAME = 'android:name'; + +const String ANDROID_REQUIRED = 'android:required'; + +const String HARDWARE_FEATURE_CAMERA = 'android.hardware.camera'; + +const String HARDWARE_FEATURE_CAMERA_AUTOFOCUS = + 'android.hardware.camera.autofocus'; + +const String HARDWARE_FEATURE_TELEPHONY = 'android.hardware.telephony'; + +const String ANDROID_PERMISSION_CAMERA = 'android.permission.CAMERA'; + +const UNSUPPORTED_HARDWARE_FEATURES = <String>[ + HARDWARE_FEATURE_CAMERA, + HARDWARE_FEATURE_CAMERA_AUTOFOCUS, + 'android.hardware.camera.capability.manual_post_processing', + 'android.hardware.camera.capability.manual_sensor', + 'android.hardware.camera.capability.raw', + 'android.hardware.camera.flash', + 'android.hardware.camera.level.full', + 'android.hardware.consumerir', + 'android.hardware.location.gps', + 'android.hardware.nfc', + 'android.hardware.nfc.hce', + 'android.hardware.sensor.barometer', + HARDWARE_FEATURE_TELEPHONY, + 'android.hardware.telephony.cdma', + 'android.hardware.telephony.gsm', + 'android.hardware.touchscreen', + 'android.hardware.type.automotive', + 'android.hardware.type.television', + 'android.hardware.usb.accessory', + 'android.hardware.usb.host', + // Partially-supported, only on some Chrome OS devices. + 'android.hardware.sensor.accelerometer', + 'android.hardware.sensor.compass', + 'android.hardware.sensor.gyroscope', + 'android.hardware.sensor.light', + 'android.hardware.sensor.proximity', + 'android.hardware.sensor.stepcounter', + 'android.hardware.sensor.stepdetector', + // Software features that are not supported + 'android.software.app_widgets', + 'android.software.device_admin', + 'android.software.home_screen', + 'android.software.input_methods', + 'android.software.leanback', + 'android.software.live_wallpaper', + 'android.software.live_tv', + 'android.software.managed_users', + 'android.software.midi', + 'android.software.sip', + 'android.software.sip.voip', +]; + +String getImpliedUnsupportedHardware(String permission) { + switch (permission) { + case ANDROID_PERMISSION_CAMERA: + return HARDWARE_FEATURE_CAMERA; + case 'android.permission.CALL_PHONE': + return HARDWARE_FEATURE_TELEPHONY; + case 'android.permission.CALL_PRIVILEGED': + return HARDWARE_FEATURE_TELEPHONY; + case 'android.permission.MODIFY_PHONE_STATE': + return HARDWARE_FEATURE_TELEPHONY; + case 'android.permission.PROCESS_OUTGOING_CALLS': + return HARDWARE_FEATURE_TELEPHONY; + case 'android.permission.READ_SMS': + return HARDWARE_FEATURE_TELEPHONY; + case 'android.permission.RECEIVE_SMS': + return HARDWARE_FEATURE_TELEPHONY; + case 'android.permission.RECEIVE_MMS': + return HARDWARE_FEATURE_TELEPHONY; + case 'android.permission.RECEIVE_WAP_PUSH': + return HARDWARE_FEATURE_TELEPHONY; + case 'android.permission.SEND_SMS': + return HARDWARE_FEATURE_TELEPHONY; + case 'android.permission.WRITE_APN_SETTINGS': + return HARDWARE_FEATURE_TELEPHONY; + case 'android.permission.WRITE_SMS': + return HARDWARE_FEATURE_TELEPHONY; + default: + return null; + } +}
diff --git a/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart b/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart new file mode 100644 index 0000000..0e0928c --- /dev/null +++ b/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
@@ -0,0 +1,60 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/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 ManifestWarningCode extends ErrorCode { + /** + * A code indicating that a specified hardware feature is not supported on Chrome OS. + */ + static const ManifestWarningCode UNSUPPORTED_CHROME_OS_HARDWARE = + const ManifestWarningCode('UNSUPPORTED_CHROME_OS_HARDWARE', + "This hardware feature is not supported on Chrome OS.", + correction: + "Try adding `android:required=\"false\"` for this hardware " + + "feature."); + + /** + * A code indicating that a specified permission is not supported on Chrome OS. + */ + static const ManifestWarningCode PERMISSION_IMPLIES_UNSUPPORTED_HARDWARE = + const ManifestWarningCode( + 'PERMISSION_IMPLIES_UNSUPPORTED_HARDWARE', + "Permission exists without corresponding hardware tag `<uses-feature " + + "android:name=\"{0}\" android:required=\"false\">`.", + correction: + "Try adding the uses-feature with required=\"false\" attribute value."); + + /** + * A code indicating that the camera permissions is not supported on Chrome OS. + */ + static const ManifestWarningCode CAMERA_PERMISSIONS_INCOMPATIBLE = + const ManifestWarningCode( + 'CAMERA_PERMISSIONS_INCOMPATIBLE', + "Permission exists without corresponding hardware `<uses-feature " + + "android:name=\"android.hardware.camera\" android:required=\"false\">` " + + "`<uses-feature " + + "android:name=\"android.hardware.camera.autofocus\" android:required=\"false\">`.", + correction: + "Try adding the uses-feature with required=\"false\" attribute value."); + + /** + * Initialize a newly created warning code to have the given [name], [message] + * and [correction]. + */ + const ManifestWarningCode(String name, String message, {String correction}) + : super.temporary(name, message, correction: correction); + + @override + ErrorSeverity get errorSeverity => ErrorSeverity.WARNING; + + @override + ErrorType get type => ErrorType.STATIC_WARNING; +}
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart index 539b719..8337641 100644 --- a/pkg/analyzer/lib/src/services/available_declarations.dart +++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -32,6 +32,7 @@ /// A top-level public declaration. class Declaration { + final List<Declaration> children; final String defaultArgumentListString; final List<int> defaultArgumentListTextRanges; final String docComplete; @@ -45,18 +46,11 @@ final String locationPath; final int locationStartColumn; final int locationStartLine; - - /// The name of the declaration. - /// For enum constants, the name of the constant. final String name; - - /// Usually `null`. - /// For enum constants, the name of the enum. - final String name2; - final String parameters; final List<String> parameterNames; final List<String> parameterTypes; + final Declaration parent; final int requiredParameterCount; final String returnType; final String typeParameters; @@ -64,6 +58,7 @@ List<String> _relevanceTags; Declaration({ + @required this.children, @required this.defaultArgumentListString, @required this.defaultArgumentListTextRanges, @required this.docComplete, @@ -78,10 +73,10 @@ @required this.locationStartColumn, @required this.locationStartLine, @required this.name, - @required this.name2, @required this.parameters, @required this.parameterNames, @required this.parameterTypes, + @required this.parent, @required List<String> relevanceTags, @required this.requiredParameterCount, @required this.returnType, @@ -92,11 +87,7 @@ @override String toString() { - if (name2 == null) { - return '($kind, $name)'; - } else { - return '($kind, $name, $name2)'; - } + return '($kind, $name)'; } } @@ -735,8 +726,8 @@ var name = declaration.name; return <String>['$uriStr::$name']; case DeclarationKind.ENUM_CONSTANT: - var name2 = declaration.name2; - return <String>['$uriStr::$name2']; + var enumName = declaration.parent.name; + return <String>['$uriStr::$enumName']; default: return null; } @@ -767,15 +758,14 @@ class _DeclarationStorage { static const fieldDocMask = 1 << 0; - static const fieldName2Mask = 1 << 1; - static const fieldParametersMask = 1 << 2; - static const fieldReturnTypeMask = 1 << 3; - static const fieldTypeParametersMask = 1 << 4; + static const fieldParametersMask = 1 << 1; + static const fieldReturnTypeMask = 1 << 2; + static const fieldTypeParametersMask = 1 << 3; - static Declaration fromIdl(String path, idl.AvailableDeclaration d) { + static Declaration fromIdl( + String path, Declaration parent, idl.AvailableDeclaration d) { var fieldMask = d.fieldMask; var hasDoc = fieldMask & fieldDocMask != 0; - var hasName2 = fieldMask & fieldName2Mask != 0; var hasParameters = fieldMask & fieldParametersMask != 0; var hasReturnType = fieldMask & fieldReturnTypeMask != 0; var hasTypeParameters = fieldMask & fieldTypeParametersMask != 0; @@ -787,7 +777,9 @@ relevanceTags = null; } - return Declaration( + var children = <Declaration>[]; + var declaration = Declaration( + children: children, defaultArgumentListString: d.defaultArgumentListString.isNotEmpty ? d.defaultArgumentListString : null, @@ -806,15 +798,22 @@ locationStartColumn: d.locationStartColumn, locationStartLine: d.locationStartLine, name: d.name, - name2: hasName2 ? d.name2 : null, parameters: hasParameters ? d.parameters : null, parameterNames: hasParameters ? d.parameterNames : null, parameterTypes: hasParameters ? d.parameterTypes.toList() : null, + parent: parent, relevanceTags: relevanceTags, requiredParameterCount: hasParameters ? d.requiredParameterCount : null, returnType: hasReturnType ? d.returnType : null, typeParameters: hasTypeParameters ? d.typeParameters : null, ); + + for (var childIdl in d.children) { + var child = fromIdl(path, declaration, childIdl); + children.add(child); + } + + return declaration; } static DeclarationKind kindFromIdl(idl.AvailableDeclarationKind kind) { @@ -880,9 +879,6 @@ if (d.docComplete != null) { fieldMask |= fieldDocMask; } - if (d.name2 != null) { - fieldMask |= fieldName2Mask; - } if (d.parameters != null) { fieldMask |= fieldParametersMask; } @@ -895,6 +891,7 @@ var idlKind = kindToIdl(d.kind); return idl.AvailableDeclarationBuilder( + children: d.children.map(toIdl).toList(), defaultArgumentListString: d.defaultArgumentListString, defaultArgumentListTextRanges: d.defaultArgumentListTextRanges, docComplete: d.docComplete, @@ -909,7 +906,6 @@ locationStartColumn: d.locationStartColumn, locationStartLine: d.locationStartLine, name: d.name, - name2: d.name2, parameters: d.parameters, parameterNames: d.parameterNames, parameterTypes: d.parameterTypes, @@ -938,7 +934,7 @@ Iterable<Declaration> filter(List<Declaration> declarations) { return declarations.where((d) { - var name = d.name2 ?? d.name; + var name = d.name; for (var combinator in combinators) { if (combinator.shows.isNotEmpty) { if (!combinator.shows.contains(name)) return false; @@ -961,7 +957,7 @@ class _File { /// The version of data format, should be incremented on every format change. - static const int DATA_VERSION = 9; + static const int DATA_VERSION = 11; /// The next value for [id]. static int _nextId = 0; @@ -1083,7 +1079,7 @@ for (var part in parts) { libraryDeclarations.addAll(part.file.fileDeclarations); } - _computeRelevanceTagsForLibraryDeclarations(); + _computeRelevanceTags(libraryDeclarations); } } @@ -1093,6 +1089,8 @@ fileDeclarations = []; libraryDeclarations = null; exportedDeclarations = null; + templateNames = []; + templateValues = []; for (var astDirective in unit.directives) { if (astDirective is ExportDirective) { @@ -1143,7 +1141,7 @@ } } - void addDeclaration({ + Declaration addDeclaration({ String defaultArgumentListString, List<int> defaultArgumentListTextRanges, bool isAbstract = false, @@ -1152,23 +1150,23 @@ bool isFinal = false, @required DeclarationKind kind, @required Identifier name, - Identifier name2, String parameters, List<String> parameterNames, List<String> parameterTypes, + Declaration parent, List<String> relevanceTags, int requiredParameterCount, String returnType, String typeParameters, }) { - if (Identifier.isPrivateName(name.name) || - name2 != null && Identifier.isPrivateName(name2.name)) { - return; + if (Identifier.isPrivateName(name.name)) { + return null; } var locationOffset = name.offset; var lineLocation = lineInfo.getLocation(locationOffset); - fileDeclarations.add(Declaration( + var declaration = Declaration( + children: <Declaration>[], defaultArgumentListString: defaultArgumentListString, defaultArgumentListTextRanges: defaultArgumentListTextRanges, docComplete: docComplete, @@ -1181,17 +1179,24 @@ locationOffset: locationOffset, locationPath: path, name: name.name, - name2: name2?.name, locationStartColumn: lineLocation.columnNumber, locationStartLine: lineLocation.lineNumber, parameters: parameters, parameterNames: parameterNames, parameterTypes: parameterTypes, + parent: parent, relevanceTags: relevanceTags, requiredParameterCount: requiredParameterCount, returnType: returnType, typeParameters: typeParameters, - )); + ); + + if (parent != null) { + parent.children.add(declaration); + } else { + fileDeclarations.add(declaration); + } + return declaration; } for (var node in unit.declarations) { @@ -1199,12 +1204,15 @@ var isDeprecated = _hasDeprecatedAnnotation(node); if (node is ClassDeclaration) { - addDeclaration( + var classDeclaration = addDeclaration( isAbstract: node.isAbstract, isDeprecated: isDeprecated, kind: DeclarationKind.CLASS, name: node.name, ); + if (classDeclaration == null) continue; + + var hasConstructor = false; for (var classMember in node.members) { if (classMember is ConstructorDeclaration) { setDartDoc(classMember); @@ -1228,15 +1236,44 @@ isDeprecated: isDeprecated, kind: DeclarationKind.CONSTRUCTOR, name: constructorName, - name2: node.name, parameters: parameters.toSource(), parameterNames: _getFormalParameterNames(parameters), parameterTypes: _getFormalParameterTypes(parameters), + parent: classDeclaration, requiredParameterCount: _getFormalParameterRequiredCount(parameters), ); + hasConstructor = true; } } + + if (!hasConstructor) { + classDeclaration.children.add(Declaration( + children: [], + defaultArgumentListString: null, + defaultArgumentListTextRanges: null, + docComplete: null, + docSummary: null, + isAbstract: false, + isConst: false, + isDeprecated: false, + isFinal: false, + kind: DeclarationKind.CONSTRUCTOR, + locationOffset: -1, + locationPath: path, + name: '', + locationStartColumn: 0, + locationStartLine: 0, + parameters: '()', + parameterNames: [], + parameterTypes: [], + parent: classDeclaration, + relevanceTags: null, + requiredParameterCount: 0, + returnType: null, + typeParameters: null, + )); + } } else if (node is ClassTypeAlias) { addDeclaration( isDeprecated: isDeprecated, @@ -1244,11 +1281,13 @@ name: node.name, ); } else if (node is EnumDeclaration) { - addDeclaration( + var enumDeclaration = addDeclaration( isDeprecated: isDeprecated, kind: DeclarationKind.ENUM, name: node.name, ); + if (enumDeclaration == null) continue; + for (var constant in node.constants) { setDartDoc(constant); var isDeprecated = _hasDeprecatedAnnotation(constant); @@ -1256,7 +1295,7 @@ isDeprecated: isDeprecated, kind: DeclarationKind.ENUM_CONSTANT, name: constant.name, - name2: node.name, + parent: enumDeclaration, ); } } else if (node is FunctionDeclaration) { @@ -1299,6 +1338,8 @@ } } else if (node is GenericTypeAlias) { var functionType = node.functionType; + if (functionType == null) continue; + var parameters = functionType.parameters; addDeclaration( isDeprecated: isDeprecated, @@ -1335,10 +1376,11 @@ } } - void _computeRelevanceTagsForLibraryDeclarations() { - for (var declaration in libraryDeclarations) { + void _computeRelevanceTags(List<Declaration> declarations) { + for (var declaration in declarations) { declaration._relevanceTags ??= RelevanceTags._forDeclaration(uriStr, declaration); + _computeRelevanceTags(declaration.children); } } @@ -1429,11 +1471,11 @@ }).toList(); fileDeclarations = idlFile.declarations.map((e) { - return _DeclarationStorage.fromIdl(path, e); + return _DeclarationStorage.fromIdl(path, null, e); }).toList(); - templateNames = idlFile.directiveInfo.templateNames; - templateValues = idlFile.directiveInfo.templateValues; + templateNames = idlFile.directiveInfo.templateNames.toList(); + templateValues = idlFile.directiveInfo.templateValues.toList(); } static _DefaultArguments _computeDefaultArguments( @@ -1649,7 +1691,7 @@ static Set<Declaration> _newDeclarationSet() { return HashSet<Declaration>( hashCode: (e) => e.name.hashCode, - equals: (a, b) => a.name == b.name && a.name2 == b.name2, + equals: (a, b) => a.name == b.name, ); } }
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart index 004943b..fd78d94 100644 --- a/pkg/analyzer/lib/src/summary/format.dart +++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -322,7 +322,7 @@ String get exception => _exception ??= ''; /// The exception string. - void set exception(String value) { + set exception(String value) { this._exception = value; } @@ -331,7 +331,7 @@ _files ??= <AnalysisDriverExceptionFileBuilder>[]; /// The state of files when the exception happened. - void set files(List<AnalysisDriverExceptionFileBuilder> value) { + set files(List<AnalysisDriverExceptionFileBuilder> value) { this._files = value; } @@ -339,7 +339,7 @@ String get path => _path ??= ''; /// The path of the file being analyzed when the exception happened. - void set path(String value) { + set path(String value) { this._path = value; } @@ -347,7 +347,7 @@ String get stackTrace => _stackTrace ??= ''; /// The exception stack trace string. - void set stackTrace(String value) { + set stackTrace(String value) { this._stackTrace = value; } @@ -361,16 +361,12 @@ _path = path, _stackTrace = stackTrace; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _files?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._path ?? ''); signature.addString(this._exception ?? ''); @@ -517,7 +513,7 @@ String get content => _content ??= ''; /// The content of the file. - void set content(String value) { + set content(String value) { this._content = value; } @@ -525,7 +521,7 @@ String get path => _path ??= ''; /// The path of the file. - void set path(String value) { + set path(String value) { this._path = value; } @@ -533,14 +529,10 @@ : _content = content, _path = path; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() {} - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._path ?? ''); signature.addString(this._content ?? ''); @@ -631,7 +623,7 @@ _errors ??= <AnalysisDriverUnitErrorBuilder>[]; /// The full list of analysis errors, both syntactic and semantic. - void set errors(List<AnalysisDriverUnitErrorBuilder> value) { + set errors(List<AnalysisDriverUnitErrorBuilder> value) { this._errors = value; } @@ -639,7 +631,7 @@ AnalysisDriverUnitIndexBuilder get index => _index; /// The index of the unit. - void set index(AnalysisDriverUnitIndexBuilder value) { + set index(AnalysisDriverUnitIndexBuilder value) { this._index = value; } @@ -649,17 +641,13 @@ : _errors = errors, _index = index; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _errors?.forEach((b) => b.flushInformative()); _index?.flushInformative(); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._errors == null) { signature.addInt(0); @@ -775,7 +763,7 @@ /// The names of defined instance members. /// They are indexes into [AnalysisDriverUnitError.strings] list. /// The list is sorted in ascending order. - void set members(List<int> value) { + set members(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._members = value; } @@ -785,7 +773,7 @@ /// The name of the class. /// It is an index into [AnalysisDriverUnitError.strings] list. - void set name(int value) { + set name(int value) { assert(value == null || value >= 0); this._name = value; } @@ -794,14 +782,10 @@ : _members = members, _name = name; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() {} - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addInt(this._name ?? 0); if (this._members == null) { @@ -897,7 +881,7 @@ String get correction => _correction ??= ''; /// The optional correction hint for the error. - void set correction(String value) { + set correction(String value) { this._correction = value; } @@ -905,7 +889,7 @@ int get length => _length ??= 0; /// The length of the error in the file. - void set length(int value) { + set length(int value) { assert(value == null || value >= 0); this._length = value; } @@ -914,7 +898,7 @@ String get message => _message ??= ''; /// The message of the error. - void set message(String value) { + set message(String value) { this._message = value; } @@ -922,7 +906,7 @@ int get offset => _offset ??= 0; /// The offset from the beginning of the file. - void set offset(int value) { + set offset(int value) { assert(value == null || value >= 0); this._offset = value; } @@ -931,7 +915,7 @@ String get uniqueName => _uniqueName ??= ''; /// The unique name of the error code. - void set uniqueName(String value) { + set uniqueName(String value) { this._uniqueName = value; } @@ -947,14 +931,10 @@ _offset = offset, _uniqueName = uniqueName; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() {} - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addInt(this._offset ?? 0); signature.addInt(this._length ?? 0); @@ -1106,7 +1086,7 @@ /// Each item of this list corresponds to a unique referenced element. It is /// the kind of the synthetic element. - void set elementKinds(List<idl.IndexSyntheticElementKind> value) { + set elementKinds(List<idl.IndexSyntheticElementKind> value) { this._elementKinds = value; } @@ -1119,7 +1099,7 @@ /// is a top-level element. The list is sorted in ascending order, so that /// the client can quickly check whether an element is referenced in this /// index. - void set elementNameClassMemberIds(List<int> value) { + set elementNameClassMemberIds(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._elementNameClassMemberIds = value; } @@ -1131,7 +1111,7 @@ /// the identifier of the named parameter name, or `null` if the element is /// not a named parameter. The list is sorted in ascending order, so that the /// client can quickly check whether an element is referenced in this index. - void set elementNameParameterIds(List<int> value) { + set elementNameParameterIds(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._elementNameParameterIds = value; } @@ -1144,7 +1124,7 @@ /// the identifier of the top-level element name, or `null` if the element is /// the unit. The list is sorted in ascending order, so that the client can /// quickly check whether an element is referenced in this index. - void set elementNameUnitMemberIds(List<int> value) { + set elementNameUnitMemberIds(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._elementNameUnitMemberIds = value; } @@ -1155,7 +1135,7 @@ /// Each item of this list corresponds to a unique referenced element. It is /// the index into [unitLibraryUris] and [unitUnitUris] for the library /// specific unit where the element is declared. - void set elementUnits(List<int> value) { + set elementUnits(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._elementUnits = value; } @@ -1164,7 +1144,7 @@ int get nullStringId => _nullStringId ??= 0; /// Identifier of the null string in [strings]. - void set nullStringId(int value) { + set nullStringId(int value) { assert(value == null || value >= 0); this._nullStringId = value; } @@ -1175,7 +1155,7 @@ /// List of unique element strings used in this index. The list is sorted in /// ascending order, so that the client can quickly check the presence of a /// string in this index. - void set strings(List<String> value) { + set strings(List<String> value) { this._strings = value; } @@ -1184,7 +1164,7 @@ _subtypes ??= <AnalysisDriverSubtypeBuilder>[]; /// The list of classes declared in the unit. - void set subtypes(List<AnalysisDriverSubtypeBuilder> value) { + set subtypes(List<AnalysisDriverSubtypeBuilder> value) { this._subtypes = value; } @@ -1195,7 +1175,7 @@ /// in [subtypes]. They are indexes into [strings] list. The list is sorted /// in ascending order. There might be more than one element with the same /// value if there is more than one subtype of this supertype. - void set supertypes(List<int> value) { + set supertypes(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._supertypes = value; } @@ -1206,7 +1186,7 @@ /// Each item of this list corresponds to the library URI of a unique library /// specific unit referenced in the index. It is an index into [strings] /// list. - void set unitLibraryUris(List<int> value) { + set unitLibraryUris(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._unitLibraryUris = value; } @@ -1217,7 +1197,7 @@ /// Each item of this list corresponds to the unit URI of a unique library /// specific unit referenced in the index. It is an index into [strings] /// list. - void set unitUnitUris(List<int> value) { + set unitUnitUris(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._unitUnitUris = value; } @@ -1228,7 +1208,7 @@ /// Each item of this list is the `true` if the corresponding element usage /// is qualified with some prefix. - void set usedElementIsQualifiedFlags(List<bool> value) { + set usedElementIsQualifiedFlags(List<bool> value) { this._usedElementIsQualifiedFlags = value; } @@ -1237,7 +1217,7 @@ _usedElementKinds ??= <idl.IndexRelationKind>[]; /// Each item of this list is the kind of the element usage. - void set usedElementKinds(List<idl.IndexRelationKind> value) { + set usedElementKinds(List<idl.IndexRelationKind> value) { this._usedElementKinds = value; } @@ -1245,7 +1225,7 @@ List<int> get usedElementLengths => _usedElementLengths ??= <int>[]; /// Each item of this list is the length of the element usage. - void set usedElementLengths(List<int> value) { + set usedElementLengths(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._usedElementLengths = value; } @@ -1255,7 +1235,7 @@ /// Each item of this list is the offset of the element usage relative to the /// beginning of the file. - void set usedElementOffsets(List<int> value) { + set usedElementOffsets(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._usedElementOffsets = value; } @@ -1267,7 +1247,7 @@ /// [elementNameUnitMemberIds], [elementNameClassMemberIds] and /// [elementNameParameterIds]. The list is sorted in ascending order, so /// that the client can quickly find element references in this index. - void set usedElements(List<int> value) { + set usedElements(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._usedElements = value; } @@ -1278,7 +1258,7 @@ /// Each item of this list is the `true` if the corresponding name usage /// is qualified with some prefix. - void set usedNameIsQualifiedFlags(List<bool> value) { + set usedNameIsQualifiedFlags(List<bool> value) { this._usedNameIsQualifiedFlags = value; } @@ -1287,7 +1267,7 @@ _usedNameKinds ??= <idl.IndexRelationKind>[]; /// Each item of this list is the kind of the name usage. - void set usedNameKinds(List<idl.IndexRelationKind> value) { + set usedNameKinds(List<idl.IndexRelationKind> value) { this._usedNameKinds = value; } @@ -1296,7 +1276,7 @@ /// Each item of this list is the offset of the name usage relative to the /// beginning of the file. - void set usedNameOffsets(List<int> value) { + set usedNameOffsets(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._usedNameOffsets = value; } @@ -1307,7 +1287,7 @@ /// Each item of this list is the index into [strings] for a used name. The /// list is sorted in ascending order, so that the client can quickly find /// whether a name is used in this index. - void set usedNames(List<int> value) { + set usedNames(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._usedNames = value; } @@ -1354,16 +1334,12 @@ _usedNameOffsets = usedNameOffsets, _usedNames = usedNames; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _subtypes?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._strings == null) { signature.addInt(0); @@ -1960,7 +1936,7 @@ _definedClassMemberNames ??= <String>[]; /// List of class member names defined by the unit. - void set definedClassMemberNames(List<String> value) { + set definedClassMemberNames(List<String> value) { this._definedClassMemberNames = value; } @@ -1968,7 +1944,7 @@ List<String> get definedTopLevelNames => _definedTopLevelNames ??= <String>[]; /// List of top-level names defined by the unit. - void set definedTopLevelNames(List<String> value) { + set definedTopLevelNames(List<String> value) { this._definedTopLevelNames = value; } @@ -1976,7 +1952,7 @@ List<String> get referencedNames => _referencedNames ??= <String>[]; /// List of external names referenced by the unit. - void set referencedNames(List<String> value) { + set referencedNames(List<String> value) { this._referencedNames = value; } @@ -1985,7 +1961,7 @@ /// List of names which are used in `extends`, `with` or `implements` clauses /// in the file. Import prefixes and type arguments are not included. - void set subtypedNames(List<String> value) { + set subtypedNames(List<String> value) { this._subtypedNames = value; } @@ -1993,7 +1969,7 @@ UnlinkedUnitBuilder get unit => _unit; /// Unlinked information for the unit. - void set unit(UnlinkedUnitBuilder value) { + set unit(UnlinkedUnitBuilder value) { this._unit = value; } @@ -2009,16 +1985,12 @@ _subtypedNames = subtypedNames, _unit = unit; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _unit?.flushInformative(); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._referencedNames == null) { signature.addInt(0); @@ -2208,6 +2180,7 @@ class AvailableDeclarationBuilder extends Object with _AvailableDeclarationMixin implements idl.AvailableDeclaration { + List<AvailableDeclarationBuilder> _children; String _defaultArgumentListString; List<int> _defaultArgumentListTextRanges; String _docComplete; @@ -2222,7 +2195,6 @@ int _locationStartColumn; int _locationStartLine; String _name; - String _name2; List<String> _parameterNames; String _parameters; List<String> _parameterTypes; @@ -2232,9 +2204,17 @@ String _typeParameters; @override + List<AvailableDeclarationBuilder> get children => + _children ??= <AvailableDeclarationBuilder>[]; + + set children(List<AvailableDeclarationBuilder> value) { + this._children = value; + } + + @override String get defaultArgumentListString => _defaultArgumentListString ??= ''; - void set defaultArgumentListString(String value) { + set defaultArgumentListString(String value) { this._defaultArgumentListString = value; } @@ -2242,7 +2222,7 @@ List<int> get defaultArgumentListTextRanges => _defaultArgumentListTextRanges ??= <int>[]; - void set defaultArgumentListTextRanges(List<int> value) { + set defaultArgumentListTextRanges(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._defaultArgumentListTextRanges = value; } @@ -2250,21 +2230,21 @@ @override String get docComplete => _docComplete ??= ''; - void set docComplete(String value) { + set docComplete(String value) { this._docComplete = value; } @override String get docSummary => _docSummary ??= ''; - void set docSummary(String value) { + set docSummary(String value) { this._docSummary = value; } @override int get fieldMask => _fieldMask ??= 0; - void set fieldMask(int value) { + set fieldMask(int value) { assert(value == null || value >= 0); this._fieldMask = value; } @@ -2272,28 +2252,28 @@ @override bool get isAbstract => _isAbstract ??= false; - void set isAbstract(bool value) { + set isAbstract(bool value) { this._isAbstract = value; } @override bool get isConst => _isConst ??= false; - void set isConst(bool value) { + set isConst(bool value) { this._isConst = value; } @override bool get isDeprecated => _isDeprecated ??= false; - void set isDeprecated(bool value) { + set isDeprecated(bool value) { this._isDeprecated = value; } @override bool get isFinal => _isFinal ??= false; - void set isFinal(bool value) { + set isFinal(bool value) { this._isFinal = value; } @@ -2302,14 +2282,14 @@ _kind ??= idl.AvailableDeclarationKind.CLASS; /// The kind of the declaration. - void set kind(idl.AvailableDeclarationKind value) { + set kind(idl.AvailableDeclarationKind value) { this._kind = value; } @override int get locationOffset => _locationOffset ??= 0; - void set locationOffset(int value) { + set locationOffset(int value) { assert(value == null || value >= 0); this._locationOffset = value; } @@ -2317,7 +2297,7 @@ @override int get locationStartColumn => _locationStartColumn ??= 0; - void set locationStartColumn(int value) { + set locationStartColumn(int value) { assert(value == null || value >= 0); this._locationStartColumn = value; } @@ -2325,7 +2305,7 @@ @override int get locationStartLine => _locationStartLine ??= 0; - void set locationStartLine(int value) { + set locationStartLine(int value) { assert(value == null || value >= 0); this._locationStartLine = value; } @@ -2335,37 +2315,28 @@ /// The first part of the declaration name, usually the only one, for example /// the name of a class like `MyClass`, or a function like `myFunction`. - void set name(String value) { + set name(String value) { this._name = value; } @override - String get name2 => _name2 ??= ''; - - /// The second, optional, part of the declaration name. For example enum - /// constants all have the same [name], but their own [name2]. - void set name2(String value) { - this._name2 = value; - } - - @override List<String> get parameterNames => _parameterNames ??= <String>[]; - void set parameterNames(List<String> value) { + set parameterNames(List<String> value) { this._parameterNames = value; } @override String get parameters => _parameters ??= ''; - void set parameters(String value) { + set parameters(String value) { this._parameters = value; } @override List<String> get parameterTypes => _parameterTypes ??= <String>[]; - void set parameterTypes(List<String> value) { + set parameterTypes(List<String> value) { this._parameterTypes = value; } @@ -2376,14 +2347,14 @@ /// example, function do not currently), and not every declaration has to /// store one (for classes it can be computed when we know the library that /// includes this file). - void set relevanceTags(List<String> value) { + set relevanceTags(List<String> value) { this._relevanceTags = value; } @override int get requiredParameterCount => _requiredParameterCount ??= 0; - void set requiredParameterCount(int value) { + set requiredParameterCount(int value) { assert(value == null || value >= 0); this._requiredParameterCount = value; } @@ -2391,19 +2362,20 @@ @override String get returnType => _returnType ??= ''; - void set returnType(String value) { + set returnType(String value) { this._returnType = value; } @override String get typeParameters => _typeParameters ??= ''; - void set typeParameters(String value) { + set typeParameters(String value) { this._typeParameters = value; } AvailableDeclarationBuilder( - {String defaultArgumentListString, + {List<AvailableDeclarationBuilder> children, + String defaultArgumentListString, List<int> defaultArgumentListTextRanges, String docComplete, String docSummary, @@ -2417,7 +2389,6 @@ int locationStartColumn, int locationStartLine, String name, - String name2, List<String> parameterNames, String parameters, List<String> parameterTypes, @@ -2425,7 +2396,8 @@ int requiredParameterCount, String returnType, String typeParameters}) - : _defaultArgumentListString = defaultArgumentListString, + : _children = children, + _defaultArgumentListString = defaultArgumentListString, _defaultArgumentListTextRanges = defaultArgumentListTextRanges, _docComplete = docComplete, _docSummary = docSummary, @@ -2439,7 +2411,6 @@ _locationStartColumn = locationStartColumn, _locationStartLine = locationStartLine, _name = name, - _name2 = name2, _parameterNames = parameterNames, _parameters = parameters, _parameterTypes = parameterTypes, @@ -2448,15 +2419,21 @@ _returnType = returnType, _typeParameters = typeParameters; - /** - * Flush [informative] data recursively. - */ - void flushInformative() {} + /// Flush [informative] data recursively. + void flushInformative() { + _children?.forEach((b) => b.flushInformative()); + } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { + if (this._children == null) { + signature.addInt(0); + } else { + signature.addInt(this._children.length); + for (var x in this._children) { + x?.collectApiSignature(signature); + } + } signature.addString(this._defaultArgumentListString ?? ''); if (this._defaultArgumentListTextRanges == null) { signature.addInt(0); @@ -2478,7 +2455,6 @@ signature.addInt(this._locationStartColumn ?? 0); signature.addInt(this._locationStartLine ?? 0); signature.addString(this._name ?? ''); - signature.addString(this._name2 ?? ''); if (this._parameterNames == null) { signature.addInt(0); } else { @@ -2510,18 +2486,22 @@ } fb.Offset finish(fb.Builder fbBuilder) { + fb.Offset offset_children; fb.Offset offset_defaultArgumentListString; fb.Offset offset_defaultArgumentListTextRanges; fb.Offset offset_docComplete; fb.Offset offset_docSummary; fb.Offset offset_name; - fb.Offset offset_name2; fb.Offset offset_parameterNames; fb.Offset offset_parameters; fb.Offset offset_parameterTypes; fb.Offset offset_relevanceTags; fb.Offset offset_returnType; fb.Offset offset_typeParameters; + if (!(_children == null || _children.isEmpty)) { + offset_children = fbBuilder + .writeList(_children.map((b) => b.finish(fbBuilder)).toList()); + } if (_defaultArgumentListString != null) { offset_defaultArgumentListString = fbBuilder.writeString(_defaultArgumentListString); @@ -2540,9 +2520,6 @@ if (_name != null) { offset_name = fbBuilder.writeString(_name); } - if (_name2 != null) { - offset_name2 = fbBuilder.writeString(_name2); - } if (!(_parameterNames == null || _parameterNames.isEmpty)) { offset_parameterNames = fbBuilder.writeList( _parameterNames.map((b) => fbBuilder.writeString(b)).toList()); @@ -2565,50 +2542,50 @@ offset_typeParameters = fbBuilder.writeString(_typeParameters); } fbBuilder.startTable(); + if (offset_children != null) { + fbBuilder.addOffset(0, offset_children); + } if (offset_defaultArgumentListString != null) { - fbBuilder.addOffset(0, offset_defaultArgumentListString); + fbBuilder.addOffset(1, offset_defaultArgumentListString); } if (offset_defaultArgumentListTextRanges != null) { - fbBuilder.addOffset(1, offset_defaultArgumentListTextRanges); + fbBuilder.addOffset(2, offset_defaultArgumentListTextRanges); } if (offset_docComplete != null) { - fbBuilder.addOffset(2, offset_docComplete); + fbBuilder.addOffset(3, offset_docComplete); } if (offset_docSummary != null) { - fbBuilder.addOffset(3, offset_docSummary); + fbBuilder.addOffset(4, offset_docSummary); } if (_fieldMask != null && _fieldMask != 0) { - fbBuilder.addUint32(4, _fieldMask); + fbBuilder.addUint32(5, _fieldMask); } if (_isAbstract == true) { - fbBuilder.addBool(5, true); - } - if (_isConst == true) { fbBuilder.addBool(6, true); } - if (_isDeprecated == true) { + if (_isConst == true) { fbBuilder.addBool(7, true); } - if (_isFinal == true) { + if (_isDeprecated == true) { fbBuilder.addBool(8, true); } + if (_isFinal == true) { + fbBuilder.addBool(9, true); + } if (_kind != null && _kind != idl.AvailableDeclarationKind.CLASS) { - fbBuilder.addUint8(9, _kind.index); + fbBuilder.addUint8(10, _kind.index); } if (_locationOffset != null && _locationOffset != 0) { - fbBuilder.addUint32(10, _locationOffset); + fbBuilder.addUint32(11, _locationOffset); } if (_locationStartColumn != null && _locationStartColumn != 0) { - fbBuilder.addUint32(11, _locationStartColumn); + fbBuilder.addUint32(12, _locationStartColumn); } if (_locationStartLine != null && _locationStartLine != 0) { - fbBuilder.addUint32(12, _locationStartLine); + fbBuilder.addUint32(13, _locationStartLine); } if (offset_name != null) { - fbBuilder.addOffset(13, offset_name); - } - if (offset_name2 != null) { - fbBuilder.addOffset(14, offset_name2); + fbBuilder.addOffset(14, offset_name); } if (offset_parameterNames != null) { fbBuilder.addOffset(15, offset_parameterNames); @@ -2652,6 +2629,7 @@ _AvailableDeclarationImpl(this._bc, this._bcOffset); + List<idl.AvailableDeclaration> _children; String _defaultArgumentListString; List<int> _defaultArgumentListTextRanges; String _docComplete; @@ -2666,7 +2644,6 @@ int _locationStartColumn; int _locationStartLine; String _name; - String _name2; List<String> _parameterNames; String _parameters; List<String> _parameterTypes; @@ -2676,102 +2653,104 @@ String _typeParameters; @override + List<idl.AvailableDeclaration> get children { + _children ??= const fb.ListReader<idl.AvailableDeclaration>( + const _AvailableDeclarationReader()) + .vTableGet(_bc, _bcOffset, 0, const <idl.AvailableDeclaration>[]); + return _children; + } + + @override String get defaultArgumentListString { _defaultArgumentListString ??= - const fb.StringReader().vTableGet(_bc, _bcOffset, 0, ''); + const fb.StringReader().vTableGet(_bc, _bcOffset, 1, ''); return _defaultArgumentListString; } @override List<int> get defaultArgumentListTextRanges { _defaultArgumentListTextRanges ??= - const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 1, const <int>[]); + const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 2, const <int>[]); return _defaultArgumentListTextRanges; } @override String get docComplete { - _docComplete ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 2, ''); + _docComplete ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, ''); return _docComplete; } @override String get docSummary { - _docSummary ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, ''); + _docSummary ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 4, ''); return _docSummary; } @override int get fieldMask { - _fieldMask ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 4, 0); + _fieldMask ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 5, 0); return _fieldMask; } @override bool get isAbstract { - _isAbstract ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 5, false); + _isAbstract ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 6, false); return _isAbstract; } @override bool get isConst { - _isConst ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 6, false); + _isConst ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 7, false); return _isConst; } @override bool get isDeprecated { - _isDeprecated ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 7, false); + _isDeprecated ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 8, false); return _isDeprecated; } @override bool get isFinal { - _isFinal ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 8, false); + _isFinal ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 9, false); return _isFinal; } @override idl.AvailableDeclarationKind get kind { _kind ??= const _AvailableDeclarationKindReader() - .vTableGet(_bc, _bcOffset, 9, idl.AvailableDeclarationKind.CLASS); + .vTableGet(_bc, _bcOffset, 10, idl.AvailableDeclarationKind.CLASS); return _kind; } @override int get locationOffset { _locationOffset ??= - const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 10, 0); + const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 11, 0); return _locationOffset; } @override int get locationStartColumn { _locationStartColumn ??= - const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 11, 0); + const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 12, 0); return _locationStartColumn; } @override int get locationStartLine { _locationStartLine ??= - const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 12, 0); + const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 13, 0); return _locationStartLine; } @override String get name { - _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 13, ''); + _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 14, ''); return _name; } @override - String get name2 { - _name2 ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 14, ''); - return _name2; - } - - @override List<String> get parameterNames { _parameterNames ??= const fb.ListReader<String>(const fb.StringReader()) .vTableGet(_bc, _bcOffset, 15, const <String>[]); @@ -2823,6 +2802,8 @@ @override Map<String, Object> toJson() { Map<String, Object> _result = <String, Object>{}; + if (children.isNotEmpty) + _result["children"] = children.map((_value) => _value.toJson()).toList(); if (defaultArgumentListString != '') _result["defaultArgumentListString"] = defaultArgumentListString; if (defaultArgumentListTextRanges.isNotEmpty) @@ -2842,7 +2823,6 @@ if (locationStartLine != 0) _result["locationStartLine"] = locationStartLine; if (name != '') _result["name"] = name; - if (name2 != '') _result["name2"] = name2; if (parameterNames.isNotEmpty) _result["parameterNames"] = parameterNames; if (parameters != '') _result["parameters"] = parameters; if (parameterTypes.isNotEmpty) _result["parameterTypes"] = parameterTypes; @@ -2856,6 +2836,7 @@ @override Map<String, Object> toMap() => { + "children": children, "defaultArgumentListString": defaultArgumentListString, "defaultArgumentListTextRanges": defaultArgumentListTextRanges, "docComplete": docComplete, @@ -2870,7 +2851,6 @@ "locationStartColumn": locationStartColumn, "locationStartLine": locationStartLine, "name": name, - "name2": name2, "parameterNames": parameterNames, "parameters": parameters, "parameterTypes": parameterTypes, @@ -2887,36 +2867,36 @@ class AvailableFileBuilder extends Object with _AvailableFileMixin implements idl.AvailableFile { - DirectiveInfoBuilder _directiveInfo; List<AvailableDeclarationBuilder> _declarations; + DirectiveInfoBuilder _directiveInfo; List<AvailableFileExportBuilder> _exports; bool _isLibrary; bool _isLibraryDeprecated; List<String> _parts; @override - DirectiveInfoBuilder get directiveInfo => _directiveInfo; - - /// The Dartdoc directives in the file. - void set directiveInfo(DirectiveInfoBuilder value) { - this._directiveInfo = value; - } - - @override List<AvailableDeclarationBuilder> get declarations => _declarations ??= <AvailableDeclarationBuilder>[]; /// Declarations of the file. - void set declarations(List<AvailableDeclarationBuilder> value) { + set declarations(List<AvailableDeclarationBuilder> value) { this._declarations = value; } @override + DirectiveInfoBuilder get directiveInfo => _directiveInfo; + + /// The Dartdoc directives in the file. + set directiveInfo(DirectiveInfoBuilder value) { + this._directiveInfo = value; + } + + @override List<AvailableFileExportBuilder> get exports => _exports ??= <AvailableFileExportBuilder>[]; /// Exports directives of the file. - void set exports(List<AvailableFileExportBuilder> value) { + set exports(List<AvailableFileExportBuilder> value) { this._exports = value; } @@ -2924,7 +2904,7 @@ bool get isLibrary => _isLibrary ??= false; /// Is `true` if this file is a library. - void set isLibrary(bool value) { + set isLibrary(bool value) { this._isLibrary = value; } @@ -2932,7 +2912,7 @@ bool get isLibraryDeprecated => _isLibraryDeprecated ??= false; /// Is `true` if this file is a library, and it is deprecated. - void set isLibraryDeprecated(bool value) { + set isLibraryDeprecated(bool value) { this._isLibraryDeprecated = value; } @@ -2940,36 +2920,32 @@ List<String> get parts => _parts ??= <String>[]; /// URIs of `part` directives. - void set parts(List<String> value) { + set parts(List<String> value) { this._parts = value; } AvailableFileBuilder( - {DirectiveInfoBuilder directiveInfo, - List<AvailableDeclarationBuilder> declarations, + {List<AvailableDeclarationBuilder> declarations, + DirectiveInfoBuilder directiveInfo, List<AvailableFileExportBuilder> exports, bool isLibrary, bool isLibraryDeprecated, List<String> parts}) - : _directiveInfo = directiveInfo, - _declarations = declarations, + : _declarations = declarations, + _directiveInfo = directiveInfo, _exports = exports, _isLibrary = isLibrary, _isLibraryDeprecated = isLibraryDeprecated, _parts = parts; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { - _directiveInfo?.flushInformative(); _declarations?.forEach((b) => b.flushInformative()); + _directiveInfo?.flushInformative(); _exports?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._declarations == null) { signature.addInt(0); @@ -3007,17 +2983,17 @@ } fb.Offset finish(fb.Builder fbBuilder) { - fb.Offset offset_directiveInfo; fb.Offset offset_declarations; + fb.Offset offset_directiveInfo; fb.Offset offset_exports; fb.Offset offset_parts; - if (_directiveInfo != null) { - offset_directiveInfo = _directiveInfo.finish(fbBuilder); - } if (!(_declarations == null || _declarations.isEmpty)) { offset_declarations = fbBuilder .writeList(_declarations.map((b) => b.finish(fbBuilder)).toList()); } + if (_directiveInfo != null) { + offset_directiveInfo = _directiveInfo.finish(fbBuilder); + } if (!(_exports == null || _exports.isEmpty)) { offset_exports = fbBuilder .writeList(_exports.map((b) => b.finish(fbBuilder)).toList()); @@ -3027,12 +3003,12 @@ .writeList(_parts.map((b) => fbBuilder.writeString(b)).toList()); } fbBuilder.startTable(); - if (offset_directiveInfo != null) { - fbBuilder.addOffset(5, offset_directiveInfo); - } if (offset_declarations != null) { fbBuilder.addOffset(0, offset_declarations); } + if (offset_directiveInfo != null) { + fbBuilder.addOffset(5, offset_directiveInfo); + } if (offset_exports != null) { fbBuilder.addOffset(1, offset_exports); } @@ -3070,21 +3046,14 @@ _AvailableFileImpl(this._bc, this._bcOffset); - idl.DirectiveInfo _directiveInfo; List<idl.AvailableDeclaration> _declarations; + idl.DirectiveInfo _directiveInfo; List<idl.AvailableFileExport> _exports; bool _isLibrary; bool _isLibraryDeprecated; List<String> _parts; @override - idl.DirectiveInfo get directiveInfo { - _directiveInfo ??= - const _DirectiveInfoReader().vTableGet(_bc, _bcOffset, 5, null); - return _directiveInfo; - } - - @override List<idl.AvailableDeclaration> get declarations { _declarations ??= const fb.ListReader<idl.AvailableDeclaration>( const _AvailableDeclarationReader()) @@ -3093,6 +3062,13 @@ } @override + idl.DirectiveInfo get directiveInfo { + _directiveInfo ??= + const _DirectiveInfoReader().vTableGet(_bc, _bcOffset, 5, null); + return _directiveInfo; + } + + @override List<idl.AvailableFileExport> get exports { _exports ??= const fb.ListReader<idl.AvailableFileExport>( const _AvailableFileExportReader()) @@ -3125,11 +3101,11 @@ @override Map<String, Object> toJson() { Map<String, Object> _result = <String, Object>{}; - if (directiveInfo != null) - _result["directiveInfo"] = directiveInfo.toJson(); if (declarations.isNotEmpty) _result["declarations"] = declarations.map((_value) => _value.toJson()).toList(); + if (directiveInfo != null) + _result["directiveInfo"] = directiveInfo.toJson(); if (exports.isNotEmpty) _result["exports"] = exports.map((_value) => _value.toJson()).toList(); if (isLibrary != false) _result["isLibrary"] = isLibrary; @@ -3141,8 +3117,8 @@ @override Map<String, Object> toMap() => { - "directiveInfo": directiveInfo, "declarations": declarations, + "directiveInfo": directiveInfo, "exports": exports, "isLibrary": isLibrary, "isLibraryDeprecated": isLibraryDeprecated, @@ -3164,7 +3140,7 @@ _combinators ??= <AvailableFileExportCombinatorBuilder>[]; /// Combinators contained in this export directive. - void set combinators(List<AvailableFileExportCombinatorBuilder> value) { + set combinators(List<AvailableFileExportCombinatorBuilder> value) { this._combinators = value; } @@ -3172,7 +3148,7 @@ String get uri => _uri ??= ''; /// URI of the exported library. - void set uri(String value) { + set uri(String value) { this._uri = value; } @@ -3181,16 +3157,12 @@ : _combinators = combinators, _uri = uri; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _combinators?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._uri ?? ''); if (this._combinators == null) { @@ -3291,7 +3263,7 @@ List<String> get hides => _hides ??= <String>[]; /// List of names which are hidden. Empty if this is a `show` combinator. - void set hides(List<String> value) { + set hides(List<String> value) { this._hides = value; } @@ -3299,7 +3271,7 @@ List<String> get shows => _shows ??= <String>[]; /// List of names which are shown. Empty if this is a `hide` combinator. - void set shows(List<String> value) { + set shows(List<String> value) { this._shows = value; } @@ -3307,14 +3279,10 @@ : _hides = hides, _shows = shows; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() {} - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._shows == null) { signature.addInt(0); @@ -3422,7 +3390,7 @@ int get length => _length ??= 0; /// Length of the element code. - void set length(int value) { + set length(int value) { assert(value == null || value >= 0); this._length = value; } @@ -3431,7 +3399,7 @@ int get offset => _offset ??= 0; /// Offset of the element code relative to the beginning of the file. - void set offset(int value) { + set offset(int value) { assert(value == null || value >= 0); this._offset = value; } @@ -3440,14 +3408,10 @@ : _length = length, _offset = offset; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() {} - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addInt(this._offset ?? 0); signature.addInt(this._length ?? 0); @@ -3526,7 +3490,7 @@ List<String> get templateNames => _templateNames ??= <String>[]; /// The names of the defined templates. - void set templateNames(List<String> value) { + set templateNames(List<String> value) { this._templateNames = value; } @@ -3534,7 +3498,7 @@ List<String> get templateValues => _templateValues ??= <String>[]; /// The values of the defined templates. - void set templateValues(List<String> value) { + set templateValues(List<String> value) { this._templateValues = value; } @@ -3543,14 +3507,10 @@ : _templateNames = templateNames, _templateValues = templateValues; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() {} - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._templateNames == null) { signature.addInt(0); @@ -3663,7 +3623,7 @@ idl.EntityRefKind get entityKind => _entityKind ??= idl.EntityRefKind.named; /// The kind of entity being represented. - void set entityKind(idl.EntityRefKind value) { + set entityKind(idl.EntityRefKind value) { this._entityKind = value; } @@ -3697,7 +3657,7 @@ /// Note that if the entity being referred to is a generic method inside a /// generic class, then the type arguments in [typeArguments] are applied /// first to the class and then to the method. - void set implicitFunctionTypeIndices(List<int> value) { + set implicitFunctionTypeIndices(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._implicitFunctionTypeIndices = value; } @@ -3722,7 +3682,7 @@ /// /// If the type being referred to is not a type parameter, [paramReference] is /// zero. - void set paramReference(int value) { + set paramReference(int value) { assert(value == null || value >= 0); this._paramReference = value; } @@ -3732,7 +3692,7 @@ /// Index into [UnlinkedUnit.references] for the entity being referred to, or /// zero if this is a reference to a type parameter. - void set reference(int value) { + set reference(int value) { assert(value == null || value >= 0); this._reference = value; } @@ -3750,7 +3710,7 @@ /// This is called `refinedSlot` to clarify that if it points to an inferred /// type, it points to a type that is a "refinement" of this one (one in which /// some type arguments have been inferred). - void set refinedSlot(int value) { + set refinedSlot(int value) { assert(value == null || value >= 0); this._refinedSlot = value; } @@ -3763,7 +3723,7 @@ /// propagation or type inference with which this [EntityRef] is associated. /// /// Otherwise zero. - void set slot(int value) { + set slot(int value) { assert(value == null || value >= 0); this._slot = value; } @@ -3776,7 +3736,7 @@ /// [FunctionElement] is not in any library (e.g. a function type that was /// synthesized by a LUB computation), the function parameters. Otherwise /// empty. - void set syntheticParams(List<UnlinkedParamBuilder> value) { + set syntheticParams(List<UnlinkedParamBuilder> value) { this._syntheticParams = value; } @@ -3787,7 +3747,7 @@ /// [FunctionElement] is not in any library (e.g. a function type that was /// synthesized by a LUB computation), the return type of the function. /// Otherwise `null`. - void set syntheticReturnType(EntityRefBuilder value) { + set syntheticReturnType(EntityRefBuilder value) { this._syntheticReturnType = value; } @@ -3797,7 +3757,7 @@ /// If this is an instantiation of a generic type or generic executable, the /// type arguments used to instantiate it (if any). - void set typeArguments(List<EntityRefBuilder> value) { + set typeArguments(List<EntityRefBuilder> value) { this._typeArguments = value; } @@ -3807,7 +3767,7 @@ /// If this is a function type, the type parameters defined for the function /// type (if any). - void set typeParameters(List<UnlinkedTypeParamBuilder> value) { + set typeParameters(List<UnlinkedTypeParamBuilder> value) { this._typeParameters = value; } @@ -3833,9 +3793,7 @@ _typeArguments = typeArguments, _typeParameters = typeParameters; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _syntheticParams?.forEach((b) => b.flushInformative()); _syntheticReturnType?.flushInformative(); @@ -3843,9 +3801,7 @@ _typeParameters?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addInt(this._reference ?? 0); if (this._typeArguments == null) { @@ -4101,7 +4057,7 @@ /// Absolute URI for the compilation units listed in the library's `part` /// declarations, empty string for invalid URI. - void set parts(List<String> value) { + set parts(List<String> value) { this._parts = value; } @@ -4109,7 +4065,7 @@ String get uri => _uri ??= ''; /// The absolute URI of the dependent library, e.g. `package:foo/bar.dart`. - void set uri(String value) { + set uri(String value) { this._uri = value; } @@ -4117,14 +4073,10 @@ : _parts = parts, _uri = uri; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() {} - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._uri ?? ''); if (this._parts == null) { @@ -4223,7 +4175,7 @@ /// Index into [LinkedLibrary.dependencies] for the library in which the /// entity is defined. - void set dependency(int value) { + set dependency(int value) { assert(value == null || value >= 0); this._dependency = value; } @@ -4232,7 +4184,7 @@ idl.ReferenceKind get kind => _kind ??= idl.ReferenceKind.classOrEnum; /// The kind of the entity being referred to. - void set kind(idl.ReferenceKind value) { + set kind(idl.ReferenceKind value) { this._kind = value; } @@ -4241,7 +4193,7 @@ /// Name of the exported entity. For an exported setter, this name includes /// the trailing '='. - void set name(String value) { + set name(String value) { this._name = value; } @@ -4252,7 +4204,7 @@ /// definition of the entity. As with indices into [LinkedLibrary.units], /// zero represents the defining compilation unit, and nonzero values /// represent parts in the order of the corresponding `part` declarations. - void set unit(int value) { + set unit(int value) { assert(value == null || value >= 0); this._unit = value; } @@ -4264,14 +4216,10 @@ _name = name, _unit = unit; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() {} - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addInt(this._dependency ?? 0); signature.addString(this._name ?? ''); @@ -4400,7 +4348,7 @@ /// implicitly refers to an element declared in the library) or /// anti-dependency (e.g. the result of type propagation or type inference /// depends on the lack of a certain declaration in the library). - void set dependencies(List<LinkedDependencyBuilder> value) { + set dependencies(List<LinkedDependencyBuilder> value) { this._dependencies = value; } @@ -4409,7 +4357,7 @@ /// For each export in [UnlinkedUnit.exports], an index into [dependencies] /// of the library being exported. - void set exportDependencies(List<int> value) { + set exportDependencies(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._exportDependencies = value; } @@ -4423,7 +4371,7 @@ /// brought into the namespace via `export` directives). /// /// Sorted by name. - void set exportNames(List<LinkedExportNameBuilder> value) { + set exportNames(List<LinkedExportNameBuilder> value) { this._exportNames = value; } @@ -4436,7 +4384,7 @@ /// For each import in [UnlinkedUnit.imports], an index into [dependencies] /// of the library being imported. - void set importDependencies(List<int> value) { + set importDependencies(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._importDependencies = value; } @@ -4447,7 +4395,7 @@ /// The number of elements in [dependencies] which are not "linked" /// dependencies (that is, the number of libraries in the direct imports plus /// the transitive closure of exports, plus the library itself). - void set numPrelinkedDependencies(int value) { + set numPrelinkedDependencies(int value) { assert(value == null || value >= 0); this._numPrelinkedDependencies = value; } @@ -4459,7 +4407,7 @@ /// library. The summary of the defining compilation unit is listed first, /// followed by the summary of each part, in the order of the `part` /// declarations in the defining compilation unit. - void set units(List<LinkedUnitBuilder> value) { + set units(List<LinkedUnitBuilder> value) { this._units = value; } @@ -4477,18 +4425,14 @@ _numPrelinkedDependencies = numPrelinkedDependencies, _units = units; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _dependencies?.forEach((b) => b.flushInformative()); _exportNames?.forEach((b) => b.flushInformative()); _units?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._dependencies == null) { signature.addInt(0); @@ -4702,6 +4646,7 @@ class LinkedNodeBuilder extends Object with _LinkedNodeMixin implements idl.LinkedNode { + LinkedNodeTypeBuilder _variantField_24; List<LinkedNodeBuilder> _variantField_2; LinkedNodeBuilder _variantField_11; List<LinkedNodeBuilder> _variantField_4; @@ -4713,7 +4658,6 @@ int _variantField_17; int _variantField_18; int _variantField_19; - LinkedNodeTypeBuilder _variantField_24; bool _variantField_27; LinkedNodeBuilder _variantField_9; LinkedNodeBuilder _variantField_12; @@ -4739,6 +4683,78 @@ LinkedNodeVariablesDeclarationBuilder _variantField_32; @override + LinkedNodeTypeBuilder get actualReturnType { + assert(kind == idl.LinkedNodeKind.functionDeclaration || + kind == idl.LinkedNodeKind.functionExpression || + kind == idl.LinkedNodeKind.functionTypeAlias || + kind == idl.LinkedNodeKind.genericFunctionType || + kind == idl.LinkedNodeKind.methodDeclaration); + return _variantField_24; + } + + @override + LinkedNodeTypeBuilder get actualType { + assert(kind == idl.LinkedNodeKind.fieldFormalParameter || + kind == idl.LinkedNodeKind.functionTypedFormalParameter || + kind == idl.LinkedNodeKind.simpleFormalParameter || + kind == idl.LinkedNodeKind.variableDeclaration); + return _variantField_24; + } + + @override + LinkedNodeTypeBuilder get binaryExpression_invokeType { + assert(kind == idl.LinkedNodeKind.binaryExpression); + return _variantField_24; + } + + @override + LinkedNodeTypeBuilder get invocationExpression_invokeType { + assert(kind == idl.LinkedNodeKind.functionExpressionInvocation || + kind == idl.LinkedNodeKind.methodInvocation); + return _variantField_24; + } + + @override + LinkedNodeTypeBuilder get typeName_type { + assert(kind == idl.LinkedNodeKind.typeName); + return _variantField_24; + } + + /// The explicit or inferred return type of a function typed node. + set actualReturnType(LinkedNodeTypeBuilder value) { + assert(kind == idl.LinkedNodeKind.functionDeclaration || + kind == idl.LinkedNodeKind.functionExpression || + kind == idl.LinkedNodeKind.functionTypeAlias || + kind == idl.LinkedNodeKind.genericFunctionType || + kind == idl.LinkedNodeKind.methodDeclaration); + _variantField_24 = value; + } + + set actualType(LinkedNodeTypeBuilder value) { + assert(kind == idl.LinkedNodeKind.fieldFormalParameter || + kind == idl.LinkedNodeKind.functionTypedFormalParameter || + kind == idl.LinkedNodeKind.simpleFormalParameter || + kind == idl.LinkedNodeKind.variableDeclaration); + _variantField_24 = value; + } + + set binaryExpression_invokeType(LinkedNodeTypeBuilder value) { + assert(kind == idl.LinkedNodeKind.binaryExpression); + _variantField_24 = value; + } + + set invocationExpression_invokeType(LinkedNodeTypeBuilder value) { + assert(kind == idl.LinkedNodeKind.functionExpressionInvocation || + kind == idl.LinkedNodeKind.methodInvocation); + _variantField_24 = value; + } + + set typeName_type(LinkedNodeTypeBuilder value) { + assert(kind == idl.LinkedNodeKind.typeName); + _variantField_24 = value; + } + + @override List<LinkedNodeBuilder> get adjacentStrings_strings { assert(kind == idl.LinkedNodeKind.adjacentStrings); return _variantField_2 ??= <LinkedNodeBuilder>[]; @@ -4889,128 +4905,128 @@ return _variantField_2 ??= <LinkedNodeBuilder>[]; } - void set adjacentStrings_strings(List<LinkedNodeBuilder> value) { + set adjacentStrings_strings(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.adjacentStrings); _variantField_2 = value; } - void set argumentList_arguments(List<LinkedNodeBuilder> value) { + set argumentList_arguments(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.argumentList); _variantField_2 = value; } - void set block_statements(List<LinkedNodeBuilder> value) { + set block_statements(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.block); _variantField_2 = value; } - void set cascadeExpression_sections(List<LinkedNodeBuilder> value) { + set cascadeExpression_sections(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.cascadeExpression); _variantField_2 = value; } - void set compilationUnit_declarations(List<LinkedNodeBuilder> value) { + set compilationUnit_declarations(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.compilationUnit); _variantField_2 = value; } - void set constructorDeclaration_initializers(List<LinkedNodeBuilder> value) { + set constructorDeclaration_initializers(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.constructorDeclaration); _variantField_2 = value; } - void set dottedName_components(List<LinkedNodeBuilder> value) { + set dottedName_components(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.dottedName); _variantField_2 = value; } - void set enumDeclaration_constants(List<LinkedNodeBuilder> value) { + set enumDeclaration_constants(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.enumDeclaration); _variantField_2 = value; } - void set formalParameterList_parameters(List<LinkedNodeBuilder> value) { + set formalParameterList_parameters(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.formalParameterList); _variantField_2 = value; } - void set hideCombinator_hiddenNames(List<LinkedNodeBuilder> value) { + set hideCombinator_hiddenNames(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.hideCombinator); _variantField_2 = value; } - void set implementsClause_interfaces(List<LinkedNodeBuilder> value) { + set implementsClause_interfaces(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.implementsClause); _variantField_2 = value; } - void set labeledStatement_labels(List<LinkedNodeBuilder> value) { + set labeledStatement_labels(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.labeledStatement); _variantField_2 = value; } - void set libraryIdentifier_components(List<LinkedNodeBuilder> value) { + set libraryIdentifier_components(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.libraryIdentifier); _variantField_2 = value; } - void set listLiteral_elements(List<LinkedNodeBuilder> value) { + set listLiteral_elements(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.listLiteral); _variantField_2 = value; } - void set namespaceDirective_combinators(List<LinkedNodeBuilder> value) { + set namespaceDirective_combinators(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.exportDirective || kind == idl.LinkedNodeKind.importDirective); _variantField_2 = value; } - void set onClause_superclassConstraints(List<LinkedNodeBuilder> value) { + set onClause_superclassConstraints(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.onClause); _variantField_2 = value; } - void set setOrMapLiteral_elements(List<LinkedNodeBuilder> value) { + set setOrMapLiteral_elements(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.setOrMapLiteral); _variantField_2 = value; } - void set showCombinator_shownNames(List<LinkedNodeBuilder> value) { + set showCombinator_shownNames(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.showCombinator); _variantField_2 = value; } - void set stringInterpolation_elements(List<LinkedNodeBuilder> value) { + set stringInterpolation_elements(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.stringInterpolation); _variantField_2 = value; } - void set switchStatement_members(List<LinkedNodeBuilder> value) { + set switchStatement_members(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.switchStatement); _variantField_2 = value; } - void set tryStatement_catchClauses(List<LinkedNodeBuilder> value) { + set tryStatement_catchClauses(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.tryStatement); _variantField_2 = value; } - void set typeArgumentList_arguments(List<LinkedNodeBuilder> value) { + set typeArgumentList_arguments(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.typeArgumentList); _variantField_2 = value; } - void set typeParameterList_typeParameters(List<LinkedNodeBuilder> value) { + set typeParameterList_typeParameters(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.typeParameterList); _variantField_2 = value; } - void set variableDeclarationList_variables(List<LinkedNodeBuilder> value) { + set variableDeclarationList_variables(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.variableDeclarationList); _variantField_2 = value; } - void set withClause_mixinTypes(List<LinkedNodeBuilder> value) { + set withClause_mixinTypes(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.withClause); _variantField_2 = value; } @@ -5041,7 +5057,7 @@ return _variantField_11; } - void set annotatedNode_comment(LinkedNodeBuilder value) { + set annotatedNode_comment(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.classDeclaration || kind == idl.LinkedNodeKind.classTypeAlias || kind == idl.LinkedNodeKind.constructorDeclaration || @@ -5107,7 +5123,7 @@ return _variantField_4 ??= <LinkedNodeBuilder>[]; } - void set annotatedNode_metadata(List<LinkedNodeBuilder> value) { + set annotatedNode_metadata(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.classDeclaration || kind == idl.LinkedNodeKind.classTypeAlias || kind == idl.LinkedNodeKind.constructorDeclaration || @@ -5132,14 +5148,14 @@ _variantField_4 = value; } - void set normalFormalParameter_metadata(List<LinkedNodeBuilder> value) { + set normalFormalParameter_metadata(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.fieldFormalParameter || kind == idl.LinkedNodeKind.functionTypedFormalParameter || kind == idl.LinkedNodeKind.simpleFormalParameter); _variantField_4 = value; } - void set switchMember_statements(List<LinkedNodeBuilder> value) { + set switchMember_statements(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.switchCase || kind == idl.LinkedNodeKind.switchDefault); _variantField_4 = value; @@ -5617,398 +5633,397 @@ return _variantField_6; } - void set annotation_arguments(LinkedNodeBuilder value) { + set annotation_arguments(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.annotation); _variantField_6 = value; } - void set asExpression_expression(LinkedNodeBuilder value) { + set asExpression_expression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.asExpression); _variantField_6 = value; } - void set assertInitializer_condition(LinkedNodeBuilder value) { + set assertInitializer_condition(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.assertInitializer); _variantField_6 = value; } - void set assertStatement_condition(LinkedNodeBuilder value) { + set assertStatement_condition(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.assertStatement); _variantField_6 = value; } - void set assignmentExpression_leftHandSide(LinkedNodeBuilder value) { + set assignmentExpression_leftHandSide(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.assignmentExpression); _variantField_6 = value; } - void set awaitExpression_expression(LinkedNodeBuilder value) { + set awaitExpression_expression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.awaitExpression); _variantField_6 = value; } - void set binaryExpression_leftOperand(LinkedNodeBuilder value) { + set binaryExpression_leftOperand(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.binaryExpression); _variantField_6 = value; } - void set blockFunctionBody_block(LinkedNodeBuilder value) { + set blockFunctionBody_block(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.blockFunctionBody); _variantField_6 = value; } - void set breakStatement_label(LinkedNodeBuilder value) { + set breakStatement_label(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.breakStatement); _variantField_6 = value; } - void set cascadeExpression_target(LinkedNodeBuilder value) { + set cascadeExpression_target(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.cascadeExpression); _variantField_6 = value; } - void set catchClause_body(LinkedNodeBuilder value) { + set catchClause_body(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.catchClause); _variantField_6 = value; } - void set classDeclaration_extendsClause(LinkedNodeBuilder value) { + set classDeclaration_extendsClause(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.classDeclaration); _variantField_6 = value; } - void set classTypeAlias_typeParameters(LinkedNodeBuilder value) { + set classTypeAlias_typeParameters(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.classTypeAlias); _variantField_6 = value; } - void set compilationUnit_scriptTag(LinkedNodeBuilder value) { + set compilationUnit_scriptTag(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.compilationUnit); _variantField_6 = value; } - void set conditionalExpression_condition(LinkedNodeBuilder value) { + set conditionalExpression_condition(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.conditionalExpression); _variantField_6 = value; } - void set configuration_name(LinkedNodeBuilder value) { + set configuration_name(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.configuration); _variantField_6 = value; } - void set constructorDeclaration_body(LinkedNodeBuilder value) { + set constructorDeclaration_body(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.constructorDeclaration); _variantField_6 = value; } - void set constructorFieldInitializer_expression(LinkedNodeBuilder value) { + set constructorFieldInitializer_expression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.constructorFieldInitializer); _variantField_6 = value; } - void set constructorName_name(LinkedNodeBuilder value) { + set constructorName_name(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.constructorName); _variantField_6 = value; } - void set continueStatement_label(LinkedNodeBuilder value) { + set continueStatement_label(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.continueStatement); _variantField_6 = value; } - void set declaredIdentifier_identifier(LinkedNodeBuilder value) { + set declaredIdentifier_identifier(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.declaredIdentifier); _variantField_6 = value; } - void set defaultFormalParameter_defaultValue(LinkedNodeBuilder value) { + set defaultFormalParameter_defaultValue(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.defaultFormalParameter); _variantField_6 = value; } - void set doStatement_body(LinkedNodeBuilder value) { + set doStatement_body(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.doStatement); _variantField_6 = value; } - void set enumConstantDeclaration_name(LinkedNodeBuilder value) { + set enumConstantDeclaration_name(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.enumConstantDeclaration); _variantField_6 = value; } - void set expressionFunctionBody_expression(LinkedNodeBuilder value) { + set expressionFunctionBody_expression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.expressionFunctionBody); _variantField_6 = value; } - void set expressionStatement_expression(LinkedNodeBuilder value) { + set expressionStatement_expression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.expressionStatement); _variantField_6 = value; } - void set extendsClause_superclass(LinkedNodeBuilder value) { + set extendsClause_superclass(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.extendsClause); _variantField_6 = value; } - void set fieldDeclaration_fields(LinkedNodeBuilder value) { + set fieldDeclaration_fields(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.fieldDeclaration); _variantField_6 = value; } - void set fieldFormalParameter_type(LinkedNodeBuilder value) { + set fieldFormalParameter_type(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.fieldFormalParameter); _variantField_6 = value; } - void set forEachParts_iterable(LinkedNodeBuilder value) { + set forEachParts_iterable(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration || kind == idl.LinkedNodeKind.forEachPartsWithIdentifier); _variantField_6 = value; } - void set forMixin_forLoopParts(LinkedNodeBuilder value) { + set forMixin_forLoopParts(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.forElement || kind == idl.LinkedNodeKind.forStatement); _variantField_6 = value; } - void set forParts_condition(LinkedNodeBuilder value) { + set forParts_condition(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations || kind == idl.LinkedNodeKind.forPartsWithExpression); _variantField_6 = value; } - void set functionDeclaration_functionExpression(LinkedNodeBuilder value) { + set functionDeclaration_functionExpression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.functionDeclaration); _variantField_6 = value; } - void set functionDeclarationStatement_functionDeclaration( + set functionDeclarationStatement_functionDeclaration( LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.functionDeclarationStatement); _variantField_6 = value; } - void set functionExpression_body(LinkedNodeBuilder value) { + set functionExpression_body(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.functionExpression); _variantField_6 = value; } - void set functionExpressionInvocation_function(LinkedNodeBuilder value) { + set functionExpressionInvocation_function(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.functionExpressionInvocation); _variantField_6 = value; } - void set functionTypeAlias_formalParameters(LinkedNodeBuilder value) { + set functionTypeAlias_formalParameters(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.functionTypeAlias); _variantField_6 = value; } - void set functionTypedFormalParameter_formalParameters( - LinkedNodeBuilder value) { + set functionTypedFormalParameter_formalParameters(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter); _variantField_6 = value; } - void set genericFunctionType_typeParameters(LinkedNodeBuilder value) { + set genericFunctionType_typeParameters(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.genericFunctionType); _variantField_6 = value; } - void set genericTypeAlias_typeParameters(LinkedNodeBuilder value) { + set genericTypeAlias_typeParameters(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.genericTypeAlias); _variantField_6 = value; } - void set ifMixin_condition(LinkedNodeBuilder value) { + set ifMixin_condition(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.ifElement || kind == idl.LinkedNodeKind.ifStatement); _variantField_6 = value; } - void set importDirective_prefix(LinkedNodeBuilder value) { + set importDirective_prefix(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.importDirective); _variantField_6 = value; } - void set indexExpression_index(LinkedNodeBuilder value) { + set indexExpression_index(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.indexExpression); _variantField_6 = value; } - void set instanceCreationExpression_arguments(LinkedNodeBuilder value) { + set instanceCreationExpression_arguments(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.instanceCreationExpression); _variantField_6 = value; } - void set interpolationExpression_expression(LinkedNodeBuilder value) { + set interpolationExpression_expression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.interpolationExpression); _variantField_6 = value; } - void set isExpression_expression(LinkedNodeBuilder value) { + set isExpression_expression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.isExpression); _variantField_6 = value; } - void set label_label(LinkedNodeBuilder value) { + set label_label(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.label); _variantField_6 = value; } - void set labeledStatement_statement(LinkedNodeBuilder value) { + set labeledStatement_statement(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.labeledStatement); _variantField_6 = value; } - void set libraryDirective_name(LinkedNodeBuilder value) { + set libraryDirective_name(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.libraryDirective); _variantField_6 = value; } - void set mapLiteralEntry_key(LinkedNodeBuilder value) { + set mapLiteralEntry_key(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.mapLiteralEntry); _variantField_6 = value; } - void set methodDeclaration_body(LinkedNodeBuilder value) { + set methodDeclaration_body(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.methodDeclaration); _variantField_6 = value; } - void set methodInvocation_methodName(LinkedNodeBuilder value) { + set methodInvocation_methodName(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.methodInvocation); _variantField_6 = value; } - void set mixinDeclaration_onClause(LinkedNodeBuilder value) { + set mixinDeclaration_onClause(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.mixinDeclaration); _variantField_6 = value; } - void set namedExpression_expression(LinkedNodeBuilder value) { + set namedExpression_expression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.namedExpression); _variantField_6 = value; } - void set nativeClause_name(LinkedNodeBuilder value) { + set nativeClause_name(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.nativeClause); _variantField_6 = value; } - void set nativeFunctionBody_stringLiteral(LinkedNodeBuilder value) { + set nativeFunctionBody_stringLiteral(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.nativeFunctionBody); _variantField_6 = value; } - void set parenthesizedExpression_expression(LinkedNodeBuilder value) { + set parenthesizedExpression_expression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.parenthesizedExpression); _variantField_6 = value; } - void set partOfDirective_libraryName(LinkedNodeBuilder value) { + set partOfDirective_libraryName(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.partOfDirective); _variantField_6 = value; } - void set postfixExpression_operand(LinkedNodeBuilder value) { + set postfixExpression_operand(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.postfixExpression); _variantField_6 = value; } - void set prefixedIdentifier_identifier(LinkedNodeBuilder value) { + set prefixedIdentifier_identifier(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.prefixedIdentifier); _variantField_6 = value; } - void set prefixExpression_operand(LinkedNodeBuilder value) { + set prefixExpression_operand(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.prefixExpression); _variantField_6 = value; } - void set propertyAccess_propertyName(LinkedNodeBuilder value) { + set propertyAccess_propertyName(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.propertyAccess); _variantField_6 = value; } - void set redirectingConstructorInvocation_arguments(LinkedNodeBuilder value) { + set redirectingConstructorInvocation_arguments(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation); _variantField_6 = value; } - void set returnStatement_expression(LinkedNodeBuilder value) { + set returnStatement_expression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.returnStatement); _variantField_6 = value; } - void set simpleFormalParameter_type(LinkedNodeBuilder value) { + set simpleFormalParameter_type(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.simpleFormalParameter); _variantField_6 = value; } - void set spreadElement_expression(LinkedNodeBuilder value) { + set spreadElement_expression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.spreadElement); _variantField_6 = value; } - void set superConstructorInvocation_arguments(LinkedNodeBuilder value) { + set superConstructorInvocation_arguments(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.superConstructorInvocation); _variantField_6 = value; } - void set switchCase_expression(LinkedNodeBuilder value) { + set switchCase_expression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.switchCase); _variantField_6 = value; } - void set throwExpression_expression(LinkedNodeBuilder value) { + set throwExpression_expression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.throwExpression); _variantField_6 = value; } - void set topLevelVariableDeclaration_variableList(LinkedNodeBuilder value) { + set topLevelVariableDeclaration_variableList(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration); _variantField_6 = value; } - void set tryStatement_body(LinkedNodeBuilder value) { + set tryStatement_body(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.tryStatement); _variantField_6 = value; } - void set typeName_name(LinkedNodeBuilder value) { + set typeName_name(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.typeName); _variantField_6 = value; } - void set typeParameter_bound(LinkedNodeBuilder value) { + set typeParameter_bound(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.typeParameter); _variantField_6 = value; } - void set variableDeclaration_initializer(LinkedNodeBuilder value) { + set variableDeclaration_initializer(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.variableDeclaration); _variantField_6 = value; } - void set variableDeclarationList_type(LinkedNodeBuilder value) { + set variableDeclarationList_type(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.variableDeclarationList); _variantField_6 = value; } - void set variableDeclarationStatement_variables(LinkedNodeBuilder value) { + set variableDeclarationStatement_variables(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.variableDeclarationStatement); _variantField_6 = value; } - void set whileStatement_body(LinkedNodeBuilder value) { + set whileStatement_body(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.whileStatement); _variantField_6 = value; } - void set yieldStatement_expression(LinkedNodeBuilder value) { + set yieldStatement_expression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.yieldStatement); _variantField_6 = value; } @@ -6570,558 +6585,558 @@ return _variantField_15 ??= 0; } - void set annotation_atSign(int value) { + set annotation_atSign(int value) { assert(kind == idl.LinkedNodeKind.annotation); assert(value == null || value >= 0); _variantField_15 = value; } - void set argumentList_leftParenthesis(int value) { + set argumentList_leftParenthesis(int value) { assert(kind == idl.LinkedNodeKind.argumentList); assert(value == null || value >= 0); _variantField_15 = value; } - void set asExpression_asOperator(int value) { + set asExpression_asOperator(int value) { assert(kind == idl.LinkedNodeKind.asExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set assertInitializer_assertKeyword(int value) { + set assertInitializer_assertKeyword(int value) { assert(kind == idl.LinkedNodeKind.assertInitializer); assert(value == null || value >= 0); _variantField_15 = value; } - void set assertStatement_assertKeyword(int value) { + set assertStatement_assertKeyword(int value) { assert(kind == idl.LinkedNodeKind.assertStatement); assert(value == null || value >= 0); _variantField_15 = value; } - void set assignmentExpression_element(int value) { + set assignmentExpression_element(int value) { assert(kind == idl.LinkedNodeKind.assignmentExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set awaitExpression_awaitKeyword(int value) { + set awaitExpression_awaitKeyword(int value) { assert(kind == idl.LinkedNodeKind.awaitExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set binaryExpression_element(int value) { + set binaryExpression_element(int value) { assert(kind == idl.LinkedNodeKind.binaryExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set block_leftBracket(int value) { + set block_leftBracket(int value) { assert(kind == idl.LinkedNodeKind.block); assert(value == null || value >= 0); _variantField_15 = value; } - void set blockFunctionBody_keyword(int value) { + set blockFunctionBody_keyword(int value) { assert(kind == idl.LinkedNodeKind.blockFunctionBody); assert(value == null || value >= 0); _variantField_15 = value; } - void set booleanLiteral_literal(int value) { + set booleanLiteral_literal(int value) { assert(kind == idl.LinkedNodeKind.booleanLiteral); assert(value == null || value >= 0); _variantField_15 = value; } - void set breakStatement_breakKeyword(int value) { + set breakStatement_breakKeyword(int value) { assert(kind == idl.LinkedNodeKind.breakStatement); assert(value == null || value >= 0); _variantField_15 = value; } - void set catchClause_catchKeyword(int value) { + set catchClause_catchKeyword(int value) { assert(kind == idl.LinkedNodeKind.catchClause); assert(value == null || value >= 0); _variantField_15 = value; } - void set classDeclaration_abstractKeyword(int value) { + set classDeclaration_abstractKeyword(int value) { assert(kind == idl.LinkedNodeKind.classDeclaration); assert(value == null || value >= 0); _variantField_15 = value; } - void set classTypeAlias_abstractKeyword(int value) { + set classTypeAlias_abstractKeyword(int value) { assert(kind == idl.LinkedNodeKind.classTypeAlias); assert(value == null || value >= 0); _variantField_15 = value; } - void set compilationUnit_beginToken(int value) { + set compilationUnit_beginToken(int value) { assert(kind == idl.LinkedNodeKind.compilationUnit); assert(value == null || value >= 0); _variantField_15 = value; } - void set conditionalExpression_colon(int value) { + set conditionalExpression_colon(int value) { assert(kind == idl.LinkedNodeKind.conditionalExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set configuration_ifKeyword(int value) { + set configuration_ifKeyword(int value) { assert(kind == idl.LinkedNodeKind.configuration); assert(value == null || value >= 0); _variantField_15 = value; } - void set constructorDeclaration_constKeyword(int value) { + set constructorDeclaration_constKeyword(int value) { assert(kind == idl.LinkedNodeKind.constructorDeclaration); assert(value == null || value >= 0); _variantField_15 = value; } - void set constructorFieldInitializer_equals(int value) { + set constructorFieldInitializer_equals(int value) { assert(kind == idl.LinkedNodeKind.constructorFieldInitializer); assert(value == null || value >= 0); _variantField_15 = value; } - void set constructorName_element(int value) { + set constructorName_element(int value) { assert(kind == idl.LinkedNodeKind.constructorName); assert(value == null || value >= 0); _variantField_15 = value; } - void set continueStatement_continueKeyword(int value) { + set continueStatement_continueKeyword(int value) { assert(kind == idl.LinkedNodeKind.continueStatement); assert(value == null || value >= 0); _variantField_15 = value; } - void set declaredIdentifier_keyword(int value) { + set declaredIdentifier_keyword(int value) { assert(kind == idl.LinkedNodeKind.declaredIdentifier); assert(value == null || value >= 0); _variantField_15 = value; } - void set defaultFormalParameter_separator(int value) { + set defaultFormalParameter_separator(int value) { assert(kind == idl.LinkedNodeKind.defaultFormalParameter); assert(value == null || value >= 0); _variantField_15 = value; } - void set doStatement_leftParenthesis(int value) { + set doStatement_leftParenthesis(int value) { assert(kind == idl.LinkedNodeKind.doStatement); assert(value == null || value >= 0); _variantField_15 = value; } - void set doubleLiteral_literal(int value) { + set doubleLiteral_literal(int value) { assert(kind == idl.LinkedNodeKind.doubleLiteral); assert(value == null || value >= 0); _variantField_15 = value; } - void set emptyFunctionBody_semicolon(int value) { + set emptyFunctionBody_semicolon(int value) { assert(kind == idl.LinkedNodeKind.emptyFunctionBody); assert(value == null || value >= 0); _variantField_15 = value; } - void set emptyStatement_semicolon(int value) { + set emptyStatement_semicolon(int value) { assert(kind == idl.LinkedNodeKind.emptyStatement); assert(value == null || value >= 0); _variantField_15 = value; } - void set enumDeclaration_enumKeyword(int value) { + set enumDeclaration_enumKeyword(int value) { assert(kind == idl.LinkedNodeKind.enumDeclaration); assert(value == null || value >= 0); _variantField_15 = value; } - void set expressionFunctionBody_arrow(int value) { + set expressionFunctionBody_arrow(int value) { assert(kind == idl.LinkedNodeKind.expressionFunctionBody); assert(value == null || value >= 0); _variantField_15 = value; } - void set expressionStatement_semicolon(int value) { + set expressionStatement_semicolon(int value) { assert(kind == idl.LinkedNodeKind.expressionStatement); assert(value == null || value >= 0); _variantField_15 = value; } - void set extendsClause_extendsKeyword(int value) { + set extendsClause_extendsKeyword(int value) { assert(kind == idl.LinkedNodeKind.extendsClause); assert(value == null || value >= 0); _variantField_15 = value; } - void set fieldDeclaration_covariantKeyword(int value) { + set fieldDeclaration_covariantKeyword(int value) { assert(kind == idl.LinkedNodeKind.fieldDeclaration); assert(value == null || value >= 0); _variantField_15 = value; } - void set fieldFormalParameter_keyword(int value) { + set fieldFormalParameter_keyword(int value) { assert(kind == idl.LinkedNodeKind.fieldFormalParameter); assert(value == null || value >= 0); _variantField_15 = value; } - void set forEachParts_inKeyword(int value) { + set forEachParts_inKeyword(int value) { assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration || kind == idl.LinkedNodeKind.forEachPartsWithIdentifier); assert(value == null || value >= 0); _variantField_15 = value; } - void set formalParameterList_leftDelimiter(int value) { + set formalParameterList_leftDelimiter(int value) { assert(kind == idl.LinkedNodeKind.formalParameterList); assert(value == null || value >= 0); _variantField_15 = value; } - void set forMixin_awaitKeyword(int value) { + set forMixin_awaitKeyword(int value) { assert(kind == idl.LinkedNodeKind.forElement || kind == idl.LinkedNodeKind.forStatement); assert(value == null || value >= 0); _variantField_15 = value; } - void set forParts_leftSeparator(int value) { + set forParts_leftSeparator(int value) { assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations || kind == idl.LinkedNodeKind.forPartsWithExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set functionDeclaration_externalKeyword(int value) { + set functionDeclaration_externalKeyword(int value) { assert(kind == idl.LinkedNodeKind.functionDeclaration); assert(value == null || value >= 0); _variantField_15 = value; } - void set genericFunctionType_functionKeyword(int value) { + set genericFunctionType_functionKeyword(int value) { assert(kind == idl.LinkedNodeKind.genericFunctionType); assert(value == null || value >= 0); _variantField_15 = value; } - void set ifMixin_elseKeyword(int value) { + set ifMixin_elseKeyword(int value) { assert(kind == idl.LinkedNodeKind.ifElement || kind == idl.LinkedNodeKind.ifStatement); assert(value == null || value >= 0); _variantField_15 = value; } - void set implementsClause_implementsKeyword(int value) { + set implementsClause_implementsKeyword(int value) { assert(kind == idl.LinkedNodeKind.implementsClause); assert(value == null || value >= 0); _variantField_15 = value; } - void set importDirective_asKeyword(int value) { + set importDirective_asKeyword(int value) { assert(kind == idl.LinkedNodeKind.importDirective); assert(value == null || value >= 0); _variantField_15 = value; } - void set indexExpression_element(int value) { + set indexExpression_element(int value) { assert(kind == idl.LinkedNodeKind.indexExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set instanceCreationExpression_keyword(int value) { + set instanceCreationExpression_keyword(int value) { assert(kind == idl.LinkedNodeKind.instanceCreationExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set integerLiteral_literal(int value) { + set integerLiteral_literal(int value) { assert(kind == idl.LinkedNodeKind.integerLiteral); assert(value == null || value >= 0); _variantField_15 = value; } - void set interpolationExpression_leftBracket(int value) { + set interpolationExpression_leftBracket(int value) { assert(kind == idl.LinkedNodeKind.interpolationExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set interpolationString_token(int value) { + set interpolationString_token(int value) { assert(kind == idl.LinkedNodeKind.interpolationString); assert(value == null || value >= 0); _variantField_15 = value; } - void set isExpression_isOperator(int value) { + set isExpression_isOperator(int value) { assert(kind == idl.LinkedNodeKind.isExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set label_colon(int value) { + set label_colon(int value) { assert(kind == idl.LinkedNodeKind.label); assert(value == null || value >= 0); _variantField_15 = value; } - void set listLiteral_leftBracket(int value) { + set listLiteral_leftBracket(int value) { assert(kind == idl.LinkedNodeKind.listLiteral); assert(value == null || value >= 0); _variantField_15 = value; } - void set mapLiteralEntry_separator(int value) { + set mapLiteralEntry_separator(int value) { assert(kind == idl.LinkedNodeKind.mapLiteralEntry); assert(value == null || value >= 0); _variantField_15 = value; } - void set methodDeclaration_externalKeyword(int value) { + set methodDeclaration_externalKeyword(int value) { assert(kind == idl.LinkedNodeKind.methodDeclaration); assert(value == null || value >= 0); _variantField_15 = value; } - void set methodInvocation_operator(int value) { + set methodInvocation_operator(int value) { assert(kind == idl.LinkedNodeKind.methodInvocation); assert(value == null || value >= 0); _variantField_15 = value; } - void set mixinDeclaration_mixinKeyword(int value) { + set mixinDeclaration_mixinKeyword(int value) { assert(kind == idl.LinkedNodeKind.mixinDeclaration); assert(value == null || value >= 0); _variantField_15 = value; } - void set nativeClause_nativeKeyword(int value) { + set nativeClause_nativeKeyword(int value) { assert(kind == idl.LinkedNodeKind.nativeClause); assert(value == null || value >= 0); _variantField_15 = value; } - void set nativeFunctionBody_nativeKeyword(int value) { + set nativeFunctionBody_nativeKeyword(int value) { assert(kind == idl.LinkedNodeKind.nativeFunctionBody); assert(value == null || value >= 0); _variantField_15 = value; } - void set nullLiteral_literal(int value) { + set nullLiteral_literal(int value) { assert(kind == idl.LinkedNodeKind.nullLiteral); assert(value == null || value >= 0); _variantField_15 = value; } - void set onClause_onKeyword(int value) { + set onClause_onKeyword(int value) { assert(kind == idl.LinkedNodeKind.onClause); assert(value == null || value >= 0); _variantField_15 = value; } - void set parenthesizedExpression_leftParenthesis(int value) { + set parenthesizedExpression_leftParenthesis(int value) { assert(kind == idl.LinkedNodeKind.parenthesizedExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set postfixExpression_element(int value) { + set postfixExpression_element(int value) { assert(kind == idl.LinkedNodeKind.postfixExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set prefixedIdentifier_period(int value) { + set prefixedIdentifier_period(int value) { assert(kind == idl.LinkedNodeKind.prefixedIdentifier); assert(value == null || value >= 0); _variantField_15 = value; } - void set prefixExpression_element(int value) { + set prefixExpression_element(int value) { assert(kind == idl.LinkedNodeKind.prefixExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set propertyAccess_operator(int value) { + set propertyAccess_operator(int value) { assert(kind == idl.LinkedNodeKind.propertyAccess); assert(value == null || value >= 0); _variantField_15 = value; } - void set redirectingConstructorInvocation_element(int value) { + set redirectingConstructorInvocation_element(int value) { assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation); assert(value == null || value >= 0); _variantField_15 = value; } - void set rethrowExpression_rethrowKeyword(int value) { + set rethrowExpression_rethrowKeyword(int value) { assert(kind == idl.LinkedNodeKind.rethrowExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set returnStatement_returnKeyword(int value) { + set returnStatement_returnKeyword(int value) { assert(kind == idl.LinkedNodeKind.returnStatement); assert(value == null || value >= 0); _variantField_15 = value; } - void set scriptTag_scriptTag(int value) { + set scriptTag_scriptTag(int value) { assert(kind == idl.LinkedNodeKind.scriptTag); assert(value == null || value >= 0); _variantField_15 = value; } - void set setOrMapLiteral_leftBracket(int value) { + set setOrMapLiteral_leftBracket(int value) { assert(kind == idl.LinkedNodeKind.setOrMapLiteral); assert(value == null || value >= 0); _variantField_15 = value; } - void set simpleFormalParameter_keyword(int value) { + set simpleFormalParameter_keyword(int value) { assert(kind == idl.LinkedNodeKind.simpleFormalParameter); assert(value == null || value >= 0); _variantField_15 = value; } - void set simpleIdentifier_element(int value) { + set simpleIdentifier_element(int value) { assert(kind == idl.LinkedNodeKind.simpleIdentifier); assert(value == null || value >= 0); _variantField_15 = value; } - void set simpleStringLiteral_token(int value) { + set simpleStringLiteral_token(int value) { assert(kind == idl.LinkedNodeKind.simpleStringLiteral); assert(value == null || value >= 0); _variantField_15 = value; } - void set spreadElement_spreadOperator(int value) { + set spreadElement_spreadOperator(int value) { assert(kind == idl.LinkedNodeKind.spreadElement); assert(value == null || value >= 0); _variantField_15 = value; } - void set superConstructorInvocation_element(int value) { + set superConstructorInvocation_element(int value) { assert(kind == idl.LinkedNodeKind.superConstructorInvocation); assert(value == null || value >= 0); _variantField_15 = value; } - void set superExpression_superKeyword(int value) { + set superExpression_superKeyword(int value) { assert(kind == idl.LinkedNodeKind.superExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set switchMember_keyword(int value) { + set switchMember_keyword(int value) { assert(kind == idl.LinkedNodeKind.switchCase || kind == idl.LinkedNodeKind.switchDefault); assert(value == null || value >= 0); _variantField_15 = value; } - void set switchStatement_leftParenthesis(int value) { + set switchStatement_leftParenthesis(int value) { assert(kind == idl.LinkedNodeKind.switchStatement); assert(value == null || value >= 0); _variantField_15 = value; } - void set symbolLiteral_poundSign(int value) { + set symbolLiteral_poundSign(int value) { assert(kind == idl.LinkedNodeKind.symbolLiteral); assert(value == null || value >= 0); _variantField_15 = value; } - void set thisExpression_thisKeyword(int value) { + set thisExpression_thisKeyword(int value) { assert(kind == idl.LinkedNodeKind.thisExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set throwExpression_throwKeyword(int value) { + set throwExpression_throwKeyword(int value) { assert(kind == idl.LinkedNodeKind.throwExpression); assert(value == null || value >= 0); _variantField_15 = value; } - void set topLevelVariableDeclaration_semicolon(int value) { + set topLevelVariableDeclaration_semicolon(int value) { assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration); assert(value == null || value >= 0); _variantField_15 = value; } - void set tryStatement_finallyKeyword(int value) { + set tryStatement_finallyKeyword(int value) { assert(kind == idl.LinkedNodeKind.tryStatement); assert(value == null || value >= 0); _variantField_15 = value; } - void set typeArgumentList_leftBracket(int value) { + set typeArgumentList_leftBracket(int value) { assert(kind == idl.LinkedNodeKind.typeArgumentList); assert(value == null || value >= 0); _variantField_15 = value; } - void set typeName_question(int value) { + set typeName_question(int value) { assert(kind == idl.LinkedNodeKind.typeName); assert(value == null || value >= 0); _variantField_15 = value; } - void set typeParameter_extendsKeyword(int value) { + set typeParameter_extendsKeyword(int value) { assert(kind == idl.LinkedNodeKind.typeParameter); assert(value == null || value >= 0); _variantField_15 = value; } - void set typeParameterList_leftBracket(int value) { + set typeParameterList_leftBracket(int value) { assert(kind == idl.LinkedNodeKind.typeParameterList); assert(value == null || value >= 0); _variantField_15 = value; } - void set variableDeclaration_equals(int value) { + set variableDeclaration_equals(int value) { assert(kind == idl.LinkedNodeKind.variableDeclaration); assert(value == null || value >= 0); _variantField_15 = value; } - void set variableDeclarationList_keyword(int value) { + set variableDeclarationList_keyword(int value) { assert(kind == idl.LinkedNodeKind.variableDeclarationList); assert(value == null || value >= 0); _variantField_15 = value; } - void set variableDeclarationStatement_semicolon(int value) { + set variableDeclarationStatement_semicolon(int value) { assert(kind == idl.LinkedNodeKind.variableDeclarationStatement); assert(value == null || value >= 0); _variantField_15 = value; } - void set whileStatement_leftParenthesis(int value) { + set whileStatement_leftParenthesis(int value) { assert(kind == idl.LinkedNodeKind.whileStatement); assert(value == null || value >= 0); _variantField_15 = value; } - void set withClause_withKeyword(int value) { + set withClause_withKeyword(int value) { assert(kind == idl.LinkedNodeKind.withClause); assert(value == null || value >= 0); _variantField_15 = value; } - void set yieldStatement_yieldKeyword(int value) { + set yieldStatement_yieldKeyword(int value) { assert(kind == idl.LinkedNodeKind.yieldStatement); assert(value == null || value >= 0); _variantField_15 = value; @@ -7421,248 +7436,248 @@ return _variantField_7; } - void set annotation_constructorName(LinkedNodeBuilder value) { + set annotation_constructorName(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.annotation); _variantField_7 = value; } - void set asExpression_type(LinkedNodeBuilder value) { + set asExpression_type(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.asExpression); _variantField_7 = value; } - void set assertInitializer_message(LinkedNodeBuilder value) { + set assertInitializer_message(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.assertInitializer); _variantField_7 = value; } - void set assertStatement_message(LinkedNodeBuilder value) { + set assertStatement_message(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.assertStatement); _variantField_7 = value; } - void set assignmentExpression_rightHandSide(LinkedNodeBuilder value) { + set assignmentExpression_rightHandSide(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.assignmentExpression); _variantField_7 = value; } - void set binaryExpression_rightOperand(LinkedNodeBuilder value) { + set binaryExpression_rightOperand(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.binaryExpression); _variantField_7 = value; } - void set catchClause_exceptionParameter(LinkedNodeBuilder value) { + set catchClause_exceptionParameter(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.catchClause); _variantField_7 = value; } - void set classDeclaration_withClause(LinkedNodeBuilder value) { + set classDeclaration_withClause(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.classDeclaration); _variantField_7 = value; } - void set classTypeAlias_superclass(LinkedNodeBuilder value) { + set classTypeAlias_superclass(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.classTypeAlias); _variantField_7 = value; } - void set conditionalExpression_elseExpression(LinkedNodeBuilder value) { + set conditionalExpression_elseExpression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.conditionalExpression); _variantField_7 = value; } - void set configuration_value(LinkedNodeBuilder value) { + set configuration_value(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.configuration); _variantField_7 = value; } - void set constructorDeclaration_name(LinkedNodeBuilder value) { + set constructorDeclaration_name(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.constructorDeclaration); _variantField_7 = value; } - void set constructorFieldInitializer_fieldName(LinkedNodeBuilder value) { + set constructorFieldInitializer_fieldName(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.constructorFieldInitializer); _variantField_7 = value; } - void set constructorName_type(LinkedNodeBuilder value) { + set constructorName_type(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.constructorName); _variantField_7 = value; } - void set declaredIdentifier_type(LinkedNodeBuilder value) { + set declaredIdentifier_type(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.declaredIdentifier); _variantField_7 = value; } - void set defaultFormalParameter_parameter(LinkedNodeBuilder value) { + set defaultFormalParameter_parameter(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.defaultFormalParameter); _variantField_7 = value; } - void set doStatement_condition(LinkedNodeBuilder value) { + set doStatement_condition(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.doStatement); _variantField_7 = value; } - void set fieldFormalParameter_typeParameters(LinkedNodeBuilder value) { + set fieldFormalParameter_typeParameters(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.fieldFormalParameter); _variantField_7 = value; } - void set forEachPartsWithDeclaration_loopVariable(LinkedNodeBuilder value) { + set forEachPartsWithDeclaration_loopVariable(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration); _variantField_7 = value; } - void set forEachPartsWithIdentifier_identifier(LinkedNodeBuilder value) { + set forEachPartsWithIdentifier_identifier(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.forEachPartsWithIdentifier); _variantField_7 = value; } - void set forElement_body(LinkedNodeBuilder value) { + set forElement_body(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.forElement); _variantField_7 = value; } - void set forPartsWithDeclarations_variables(LinkedNodeBuilder value) { + set forPartsWithDeclarations_variables(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations); _variantField_7 = value; } - void set forPartsWithExpression_initialization(LinkedNodeBuilder value) { + set forPartsWithExpression_initialization(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.forPartsWithExpression); _variantField_7 = value; } - void set forStatement_body(LinkedNodeBuilder value) { + set forStatement_body(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.forStatement); _variantField_7 = value; } - void set functionDeclaration_returnType(LinkedNodeBuilder value) { + set functionDeclaration_returnType(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.functionDeclaration); _variantField_7 = value; } - void set functionExpression_formalParameters(LinkedNodeBuilder value) { + set functionExpression_formalParameters(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.functionExpression); _variantField_7 = value; } - void set functionTypeAlias_returnType(LinkedNodeBuilder value) { + set functionTypeAlias_returnType(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.functionTypeAlias); _variantField_7 = value; } - void set functionTypedFormalParameter_returnType(LinkedNodeBuilder value) { + set functionTypedFormalParameter_returnType(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter); _variantField_7 = value; } - void set genericFunctionType_returnType(LinkedNodeBuilder value) { + set genericFunctionType_returnType(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.genericFunctionType); _variantField_7 = value; } - void set genericTypeAlias_functionType(LinkedNodeBuilder value) { + set genericTypeAlias_functionType(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.genericTypeAlias); _variantField_7 = value; } - void set ifStatement_elseStatement(LinkedNodeBuilder value) { + set ifStatement_elseStatement(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.ifStatement); _variantField_7 = value; } - void set indexExpression_target(LinkedNodeBuilder value) { + set indexExpression_target(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.indexExpression); _variantField_7 = value; } - void set instanceCreationExpression_constructorName(LinkedNodeBuilder value) { + set instanceCreationExpression_constructorName(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.instanceCreationExpression); _variantField_7 = value; } - void set isExpression_type(LinkedNodeBuilder value) { + set isExpression_type(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.isExpression); _variantField_7 = value; } - void set mapLiteralEntry_value(LinkedNodeBuilder value) { + set mapLiteralEntry_value(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.mapLiteralEntry); _variantField_7 = value; } - void set methodDeclaration_formalParameters(LinkedNodeBuilder value) { + set methodDeclaration_formalParameters(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.methodDeclaration); _variantField_7 = value; } - void set methodInvocation_target(LinkedNodeBuilder value) { + set methodInvocation_target(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.methodInvocation); _variantField_7 = value; } - void set namedExpression_name(LinkedNodeBuilder value) { + set namedExpression_name(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.namedExpression); _variantField_7 = value; } - void set partOfDirective_uri(LinkedNodeBuilder value) { + set partOfDirective_uri(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.partOfDirective); _variantField_7 = value; } - void set prefixedIdentifier_prefix(LinkedNodeBuilder value) { + set prefixedIdentifier_prefix(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.prefixedIdentifier); _variantField_7 = value; } - void set propertyAccess_target(LinkedNodeBuilder value) { + set propertyAccess_target(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.propertyAccess); _variantField_7 = value; } - void set redirectingConstructorInvocation_constructorName( + set redirectingConstructorInvocation_constructorName( LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation); _variantField_7 = value; } - void set superConstructorInvocation_constructorName(LinkedNodeBuilder value) { + set superConstructorInvocation_constructorName(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.superConstructorInvocation); _variantField_7 = value; } - void set switchStatement_expression(LinkedNodeBuilder value) { + set switchStatement_expression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.switchStatement); _variantField_7 = value; } - void set tryStatement_finallyBlock(LinkedNodeBuilder value) { + set tryStatement_finallyBlock(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.tryStatement); _variantField_7 = value; } - void set typeName_typeArguments(LinkedNodeBuilder value) { + set typeName_typeArguments(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.typeName); _variantField_7 = value; } - void set typeParameter_name(LinkedNodeBuilder value) { + set typeParameter_name(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.typeParameter); _variantField_7 = value; } - void set variableDeclaration_name(LinkedNodeBuilder value) { + set variableDeclaration_name(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.variableDeclaration); _variantField_7 = value; } - void set whileStatement_condition(LinkedNodeBuilder value) { + set whileStatement_condition(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.whileStatement); _variantField_7 = value; } @@ -7763,83 +7778,82 @@ return _variantField_8; } - void set annotation_name(LinkedNodeBuilder value) { + set annotation_name(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.annotation); _variantField_8 = value; } - void set catchClause_exceptionType(LinkedNodeBuilder value) { + set catchClause_exceptionType(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.catchClause); _variantField_8 = value; } - void set classDeclaration_nativeClause(LinkedNodeBuilder value) { + set classDeclaration_nativeClause(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.classDeclaration); _variantField_8 = value; } - void set classTypeAlias_withClause(LinkedNodeBuilder value) { + set classTypeAlias_withClause(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.classTypeAlias); _variantField_8 = value; } - void set conditionalExpression_thenExpression(LinkedNodeBuilder value) { + set conditionalExpression_thenExpression(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.conditionalExpression); _variantField_8 = value; } - void set configuration_uri(LinkedNodeBuilder value) { + set configuration_uri(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.configuration); _variantField_8 = value; } - void set constructorDeclaration_parameters(LinkedNodeBuilder value) { + set constructorDeclaration_parameters(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.constructorDeclaration); _variantField_8 = value; } - void set fieldFormalParameter_formalParameters(LinkedNodeBuilder value) { + set fieldFormalParameter_formalParameters(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.fieldFormalParameter); _variantField_8 = value; } - void set functionExpression_typeParameters(LinkedNodeBuilder value) { + set functionExpression_typeParameters(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.functionExpression); _variantField_8 = value; } - void set functionTypeAlias_typeParameters(LinkedNodeBuilder value) { + set functionTypeAlias_typeParameters(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.functionTypeAlias); _variantField_8 = value; } - void set functionTypedFormalParameter_typeParameters( - LinkedNodeBuilder value) { + set functionTypedFormalParameter_typeParameters(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter); _variantField_8 = value; } - void set genericFunctionType_formalParameters(LinkedNodeBuilder value) { + set genericFunctionType_formalParameters(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.genericFunctionType); _variantField_8 = value; } - void set ifElement_thenElement(LinkedNodeBuilder value) { + set ifElement_thenElement(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.ifElement); _variantField_8 = value; } - void set ifStatement_thenStatement(LinkedNodeBuilder value) { + set ifStatement_thenStatement(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.ifStatement); _variantField_8 = value; } - void set instanceCreationExpression_typeArguments(LinkedNodeBuilder value) { + set instanceCreationExpression_typeArguments(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.instanceCreationExpression); _variantField_8 = value; } - void set methodDeclaration_returnType(LinkedNodeBuilder value) { + set methodDeclaration_returnType(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.methodDeclaration); _variantField_8 = value; } @@ -8178,335 +8192,335 @@ return _variantField_16 ??= 0; } - void set annotation_period(int value) { + set annotation_period(int value) { assert(kind == idl.LinkedNodeKind.annotation); assert(value == null || value >= 0); _variantField_16 = value; } - void set argumentList_rightParenthesis(int value) { + set argumentList_rightParenthesis(int value) { assert(kind == idl.LinkedNodeKind.argumentList); assert(value == null || value >= 0); _variantField_16 = value; } - void set assertInitializer_comma(int value) { + set assertInitializer_comma(int value) { assert(kind == idl.LinkedNodeKind.assertInitializer); assert(value == null || value >= 0); _variantField_16 = value; } - void set assertStatement_comma(int value) { + set assertStatement_comma(int value) { assert(kind == idl.LinkedNodeKind.assertStatement); assert(value == null || value >= 0); _variantField_16 = value; } - void set assignmentExpression_operator(int value) { + set assignmentExpression_operator(int value) { assert(kind == idl.LinkedNodeKind.assignmentExpression); assert(value == null || value >= 0); _variantField_16 = value; } - void set binaryExpression_operator(int value) { + set binaryExpression_operator(int value) { assert(kind == idl.LinkedNodeKind.binaryExpression); assert(value == null || value >= 0); _variantField_16 = value; } - void set block_rightBracket(int value) { + set block_rightBracket(int value) { assert(kind == idl.LinkedNodeKind.block); assert(value == null || value >= 0); _variantField_16 = value; } - void set blockFunctionBody_star(int value) { + set blockFunctionBody_star(int value) { assert(kind == idl.LinkedNodeKind.blockFunctionBody); assert(value == null || value >= 0); _variantField_16 = value; } - void set breakStatement_semicolon(int value) { + set breakStatement_semicolon(int value) { assert(kind == idl.LinkedNodeKind.breakStatement); assert(value == null || value >= 0); _variantField_16 = value; } - void set catchClause_comma(int value) { + set catchClause_comma(int value) { assert(kind == idl.LinkedNodeKind.catchClause); assert(value == null || value >= 0); _variantField_16 = value; } - void set classDeclaration_classKeyword(int value) { + set classDeclaration_classKeyword(int value) { assert(kind == idl.LinkedNodeKind.classDeclaration); assert(value == null || value >= 0); _variantField_16 = value; } - void set classTypeAlias_equals(int value) { + set classTypeAlias_equals(int value) { assert(kind == idl.LinkedNodeKind.classTypeAlias); assert(value == null || value >= 0); _variantField_16 = value; } - void set compilationUnit_endToken(int value) { + set compilationUnit_endToken(int value) { assert(kind == idl.LinkedNodeKind.compilationUnit); assert(value == null || value >= 0); _variantField_16 = value; } - void set conditionalExpression_question(int value) { + set conditionalExpression_question(int value) { assert(kind == idl.LinkedNodeKind.conditionalExpression); assert(value == null || value >= 0); _variantField_16 = value; } - void set configuration_leftParenthesis(int value) { + set configuration_leftParenthesis(int value) { assert(kind == idl.LinkedNodeKind.configuration); assert(value == null || value >= 0); _variantField_16 = value; } - void set constructorDeclaration_externalKeyword(int value) { + set constructorDeclaration_externalKeyword(int value) { assert(kind == idl.LinkedNodeKind.constructorDeclaration); assert(value == null || value >= 0); _variantField_16 = value; } - void set constructorFieldInitializer_period(int value) { + set constructorFieldInitializer_period(int value) { assert(kind == idl.LinkedNodeKind.constructorFieldInitializer); assert(value == null || value >= 0); _variantField_16 = value; } - void set constructorName_period(int value) { + set constructorName_period(int value) { assert(kind == idl.LinkedNodeKind.constructorName); assert(value == null || value >= 0); _variantField_16 = value; } - void set continueStatement_semicolon(int value) { + set continueStatement_semicolon(int value) { assert(kind == idl.LinkedNodeKind.continueStatement); assert(value == null || value >= 0); _variantField_16 = value; } - void set doStatement_rightParenthesis(int value) { + set doStatement_rightParenthesis(int value) { assert(kind == idl.LinkedNodeKind.doStatement); assert(value == null || value >= 0); _variantField_16 = value; } - void set enumDeclaration_leftBracket(int value) { + set enumDeclaration_leftBracket(int value) { assert(kind == idl.LinkedNodeKind.enumDeclaration); assert(value == null || value >= 0); _variantField_16 = value; } - void set expressionFunctionBody_keyword(int value) { + set expressionFunctionBody_keyword(int value) { assert(kind == idl.LinkedNodeKind.expressionFunctionBody); assert(value == null || value >= 0); _variantField_16 = value; } - void set fieldDeclaration_semicolon(int value) { + set fieldDeclaration_semicolon(int value) { assert(kind == idl.LinkedNodeKind.fieldDeclaration); assert(value == null || value >= 0); _variantField_16 = value; } - void set fieldFormalParameter_period(int value) { + set fieldFormalParameter_period(int value) { assert(kind == idl.LinkedNodeKind.fieldFormalParameter); assert(value == null || value >= 0); _variantField_16 = value; } - void set formalParameterList_leftParenthesis(int value) { + set formalParameterList_leftParenthesis(int value) { assert(kind == idl.LinkedNodeKind.formalParameterList); assert(value == null || value >= 0); _variantField_16 = value; } - void set forMixin_forKeyword(int value) { + set forMixin_forKeyword(int value) { assert(kind == idl.LinkedNodeKind.forElement || kind == idl.LinkedNodeKind.forStatement); assert(value == null || value >= 0); _variantField_16 = value; } - void set forParts_rightSeparator(int value) { + set forParts_rightSeparator(int value) { assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations || kind == idl.LinkedNodeKind.forPartsWithExpression); assert(value == null || value >= 0); _variantField_16 = value; } - void set functionDeclaration_propertyKeyword(int value) { + set functionDeclaration_propertyKeyword(int value) { assert(kind == idl.LinkedNodeKind.functionDeclaration); assert(value == null || value >= 0); _variantField_16 = value; } - void set genericFunctionType_question(int value) { + set genericFunctionType_question(int value) { assert(kind == idl.LinkedNodeKind.genericFunctionType); assert(value == null || value >= 0); _variantField_16 = value; } - void set genericTypeAlias_equals(int value) { + set genericTypeAlias_equals(int value) { assert(kind == idl.LinkedNodeKind.genericTypeAlias); assert(value == null || value >= 0); _variantField_16 = value; } - void set ifMixin_ifKeyword(int value) { + set ifMixin_ifKeyword(int value) { assert(kind == idl.LinkedNodeKind.ifElement || kind == idl.LinkedNodeKind.ifStatement); assert(value == null || value >= 0); _variantField_16 = value; } - void set importDirective_deferredKeyword(int value) { + set importDirective_deferredKeyword(int value) { assert(kind == idl.LinkedNodeKind.importDirective); assert(value == null || value >= 0); _variantField_16 = value; } - void set indexExpression_period(int value) { + set indexExpression_period(int value) { assert(kind == idl.LinkedNodeKind.indexExpression); assert(value == null || value >= 0); _variantField_16 = value; } - void set integerLiteral_value(int value) { + set integerLiteral_value(int value) { assert(kind == idl.LinkedNodeKind.integerLiteral); assert(value == null || value >= 0); _variantField_16 = value; } - void set interpolationExpression_rightBracket(int value) { + set interpolationExpression_rightBracket(int value) { assert(kind == idl.LinkedNodeKind.interpolationExpression); assert(value == null || value >= 0); _variantField_16 = value; } - void set isExpression_notOperator(int value) { + set isExpression_notOperator(int value) { assert(kind == idl.LinkedNodeKind.isExpression); assert(value == null || value >= 0); _variantField_16 = value; } - void set listLiteral_rightBracket(int value) { + set listLiteral_rightBracket(int value) { assert(kind == idl.LinkedNodeKind.listLiteral); assert(value == null || value >= 0); _variantField_16 = value; } - void set methodDeclaration_modifierKeyword(int value) { + set methodDeclaration_modifierKeyword(int value) { assert(kind == idl.LinkedNodeKind.methodDeclaration); assert(value == null || value >= 0); _variantField_16 = value; } - void set nativeFunctionBody_semicolon(int value) { + set nativeFunctionBody_semicolon(int value) { assert(kind == idl.LinkedNodeKind.nativeFunctionBody); assert(value == null || value >= 0); _variantField_16 = value; } - void set parenthesizedExpression_rightParenthesis(int value) { + set parenthesizedExpression_rightParenthesis(int value) { assert(kind == idl.LinkedNodeKind.parenthesizedExpression); assert(value == null || value >= 0); _variantField_16 = value; } - void set partOfDirective_ofKeyword(int value) { + set partOfDirective_ofKeyword(int value) { assert(kind == idl.LinkedNodeKind.partOfDirective); assert(value == null || value >= 0); _variantField_16 = value; } - void set postfixExpression_operator(int value) { + set postfixExpression_operator(int value) { assert(kind == idl.LinkedNodeKind.postfixExpression); assert(value == null || value >= 0); _variantField_16 = value; } - void set prefixExpression_operator(int value) { + set prefixExpression_operator(int value) { assert(kind == idl.LinkedNodeKind.prefixExpression); assert(value == null || value >= 0); _variantField_16 = value; } - void set redirectingConstructorInvocation_period(int value) { + set redirectingConstructorInvocation_period(int value) { assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation); assert(value == null || value >= 0); _variantField_16 = value; } - void set returnStatement_semicolon(int value) { + set returnStatement_semicolon(int value) { assert(kind == idl.LinkedNodeKind.returnStatement); assert(value == null || value >= 0); _variantField_16 = value; } - void set setOrMapLiteral_rightBracket(int value) { + set setOrMapLiteral_rightBracket(int value) { assert(kind == idl.LinkedNodeKind.setOrMapLiteral); assert(value == null || value >= 0); _variantField_16 = value; } - void set simpleIdentifier_token(int value) { + set simpleIdentifier_token(int value) { assert(kind == idl.LinkedNodeKind.simpleIdentifier); assert(value == null || value >= 0); _variantField_16 = value; } - void set superConstructorInvocation_period(int value) { + set superConstructorInvocation_period(int value) { assert(kind == idl.LinkedNodeKind.superConstructorInvocation); assert(value == null || value >= 0); _variantField_16 = value; } - void set switchMember_colon(int value) { + set switchMember_colon(int value) { assert(kind == idl.LinkedNodeKind.switchCase || kind == idl.LinkedNodeKind.switchDefault); assert(value == null || value >= 0); _variantField_16 = value; } - void set switchStatement_rightParenthesis(int value) { + set switchStatement_rightParenthesis(int value) { assert(kind == idl.LinkedNodeKind.switchStatement); assert(value == null || value >= 0); _variantField_16 = value; } - void set tryStatement_tryKeyword(int value) { + set tryStatement_tryKeyword(int value) { assert(kind == idl.LinkedNodeKind.tryStatement); assert(value == null || value >= 0); _variantField_16 = value; } - void set typeArgumentList_rightBracket(int value) { + set typeArgumentList_rightBracket(int value) { assert(kind == idl.LinkedNodeKind.typeArgumentList); assert(value == null || value >= 0); _variantField_16 = value; } - void set typeParameterList_rightBracket(int value) { + set typeParameterList_rightBracket(int value) { assert(kind == idl.LinkedNodeKind.typeParameterList); assert(value == null || value >= 0); _variantField_16 = value; } - void set whileStatement_rightParenthesis(int value) { + set whileStatement_rightParenthesis(int value) { assert(kind == idl.LinkedNodeKind.whileStatement); assert(value == null || value >= 0); _variantField_16 = value; } - void set yieldStatement_star(int value) { + set yieldStatement_star(int value) { assert(kind == idl.LinkedNodeKind.yieldStatement); assert(value == null || value >= 0); _variantField_16 = value; @@ -8640,129 +8654,129 @@ return _variantField_17 ??= 0; } - void set assertInitializer_leftParenthesis(int value) { + set assertInitializer_leftParenthesis(int value) { assert(kind == idl.LinkedNodeKind.assertInitializer); assert(value == null || value >= 0); _variantField_17 = value; } - void set assertStatement_leftParenthesis(int value) { + set assertStatement_leftParenthesis(int value) { assert(kind == idl.LinkedNodeKind.assertStatement); assert(value == null || value >= 0); _variantField_17 = value; } - void set catchClause_leftParenthesis(int value) { + set catchClause_leftParenthesis(int value) { assert(kind == idl.LinkedNodeKind.catchClause); assert(value == null || value >= 0); _variantField_17 = value; } - void set configuration_rightParenthesis(int value) { + set configuration_rightParenthesis(int value) { assert(kind == idl.LinkedNodeKind.configuration); assert(value == null || value >= 0); _variantField_17 = value; } - void set constructorDeclaration_factoryKeyword(int value) { + set constructorDeclaration_factoryKeyword(int value) { assert(kind == idl.LinkedNodeKind.constructorDeclaration); assert(value == null || value >= 0); _variantField_17 = value; } - void set constructorFieldInitializer_thisKeyword(int value) { + set constructorFieldInitializer_thisKeyword(int value) { assert(kind == idl.LinkedNodeKind.constructorFieldInitializer); assert(value == null || value >= 0); _variantField_17 = value; } - void set doStatement_doKeyword(int value) { + set doStatement_doKeyword(int value) { assert(kind == idl.LinkedNodeKind.doStatement); assert(value == null || value >= 0); _variantField_17 = value; } - void set enumDeclaration_rightBracket(int value) { + set enumDeclaration_rightBracket(int value) { assert(kind == idl.LinkedNodeKind.enumDeclaration); assert(value == null || value >= 0); _variantField_17 = value; } - void set expressionFunctionBody_semicolon(int value) { + set expressionFunctionBody_semicolon(int value) { assert(kind == idl.LinkedNodeKind.expressionFunctionBody); assert(value == null || value >= 0); _variantField_17 = value; } - void set fieldDeclaration_staticKeyword(int value) { + set fieldDeclaration_staticKeyword(int value) { assert(kind == idl.LinkedNodeKind.fieldDeclaration); assert(value == null || value >= 0); _variantField_17 = value; } - void set fieldFormalParameter_thisKeyword(int value) { + set fieldFormalParameter_thisKeyword(int value) { assert(kind == idl.LinkedNodeKind.fieldFormalParameter); assert(value == null || value >= 0); _variantField_17 = value; } - void set formalParameterList_rightDelimiter(int value) { + set formalParameterList_rightDelimiter(int value) { assert(kind == idl.LinkedNodeKind.formalParameterList); assert(value == null || value >= 0); _variantField_17 = value; } - void set forMixin_leftParenthesis(int value) { + set forMixin_leftParenthesis(int value) { assert(kind == idl.LinkedNodeKind.forElement || kind == idl.LinkedNodeKind.forStatement); assert(value == null || value >= 0); _variantField_17 = value; } - void set ifMixin_leftParenthesis(int value) { + set ifMixin_leftParenthesis(int value) { assert(kind == idl.LinkedNodeKind.ifElement || kind == idl.LinkedNodeKind.ifStatement); assert(value == null || value >= 0); _variantField_17 = value; } - void set indexExpression_leftBracket(int value) { + set indexExpression_leftBracket(int value) { assert(kind == idl.LinkedNodeKind.indexExpression); assert(value == null || value >= 0); _variantField_17 = value; } - void set methodDeclaration_operatorKeyword(int value) { + set methodDeclaration_operatorKeyword(int value) { assert(kind == idl.LinkedNodeKind.methodDeclaration); assert(value == null || value >= 0); _variantField_17 = value; } - void set redirectingConstructorInvocation_thisKeyword(int value) { + set redirectingConstructorInvocation_thisKeyword(int value) { assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation); assert(value == null || value >= 0); _variantField_17 = value; } - void set superConstructorInvocation_superKeyword(int value) { + set superConstructorInvocation_superKeyword(int value) { assert(kind == idl.LinkedNodeKind.superConstructorInvocation); assert(value == null || value >= 0); _variantField_17 = value; } - void set switchStatement_switchKeyword(int value) { + set switchStatement_switchKeyword(int value) { assert(kind == idl.LinkedNodeKind.switchStatement); assert(value == null || value >= 0); _variantField_17 = value; } - void set whileStatement_whileKeyword(int value) { + set whileStatement_whileKeyword(int value) { assert(kind == idl.LinkedNodeKind.whileStatement); assert(value == null || value >= 0); _variantField_17 = value; } - void set yieldStatement_semicolon(int value) { + set yieldStatement_semicolon(int value) { assert(kind == idl.LinkedNodeKind.yieldStatement); assert(value == null || value >= 0); _variantField_17 = value; @@ -8860,44 +8874,44 @@ return _variantField_18 ??= 0; } - void set assertInitializer_rightParenthesis(int value) { + set assertInitializer_rightParenthesis(int value) { assert(kind == idl.LinkedNodeKind.assertInitializer); assert(value == null || value >= 0); _variantField_18 = value; } - void set assertStatement_rightParenthesis(int value) { + set assertStatement_rightParenthesis(int value) { assert(kind == idl.LinkedNodeKind.assertStatement); assert(value == null || value >= 0); _variantField_18 = value; } - void set catchClause_onKeyword(int value) { + set catchClause_onKeyword(int value) { assert(kind == idl.LinkedNodeKind.catchClause); assert(value == null || value >= 0); _variantField_18 = value; } - void set classOrMixinDeclaration_rightBracket(int value) { + set classOrMixinDeclaration_rightBracket(int value) { assert(kind == idl.LinkedNodeKind.classDeclaration || kind == idl.LinkedNodeKind.mixinDeclaration); assert(value == null || value >= 0); _variantField_18 = value; } - void set configuration_equalToken(int value) { + set configuration_equalToken(int value) { assert(kind == idl.LinkedNodeKind.configuration); assert(value == null || value >= 0); _variantField_18 = value; } - void set constructorDeclaration_period(int value) { + set constructorDeclaration_period(int value) { assert(kind == idl.LinkedNodeKind.constructorDeclaration); assert(value == null || value >= 0); _variantField_18 = value; } - void set directive_keyword(int value) { + set directive_keyword(int value) { assert(kind == idl.LinkedNodeKind.exportDirective || kind == idl.LinkedNodeKind.importDirective || kind == idl.LinkedNodeKind.libraryDirective || @@ -8907,44 +8921,44 @@ _variantField_18 = value; } - void set doStatement_semicolon(int value) { + set doStatement_semicolon(int value) { assert(kind == idl.LinkedNodeKind.doStatement); assert(value == null || value >= 0); _variantField_18 = value; } - void set formalParameterList_rightParenthesis(int value) { + set formalParameterList_rightParenthesis(int value) { assert(kind == idl.LinkedNodeKind.formalParameterList); assert(value == null || value >= 0); _variantField_18 = value; } - void set ifMixin_rightParenthesis(int value) { + set ifMixin_rightParenthesis(int value) { assert(kind == idl.LinkedNodeKind.ifElement || kind == idl.LinkedNodeKind.ifStatement); assert(value == null || value >= 0); _variantField_18 = value; } - void set indexExpression_rightBracket(int value) { + set indexExpression_rightBracket(int value) { assert(kind == idl.LinkedNodeKind.indexExpression); assert(value == null || value >= 0); _variantField_18 = value; } - void set methodDeclaration_propertyKeyword(int value) { + set methodDeclaration_propertyKeyword(int value) { assert(kind == idl.LinkedNodeKind.methodDeclaration); assert(value == null || value >= 0); _variantField_18 = value; } - void set switchStatement_leftBracket(int value) { + set switchStatement_leftBracket(int value) { assert(kind == idl.LinkedNodeKind.switchStatement); assert(value == null || value >= 0); _variantField_18 = value; } - void set typeAlias_typedefKeyword(int value) { + set typeAlias_typedefKeyword(int value) { assert(kind == idl.LinkedNodeKind.classTypeAlias || kind == idl.LinkedNodeKind.functionTypeAlias || kind == idl.LinkedNodeKind.genericTypeAlias); @@ -9040,58 +9054,58 @@ return _variantField_19 ??= 0; } - void set assertStatement_semicolon(int value) { + set assertStatement_semicolon(int value) { assert(kind == idl.LinkedNodeKind.assertStatement); assert(value == null || value >= 0); _variantField_19 = value; } - void set catchClause_rightParenthesis(int value) { + set catchClause_rightParenthesis(int value) { assert(kind == idl.LinkedNodeKind.catchClause); assert(value == null || value >= 0); _variantField_19 = value; } - void set classOrMixinDeclaration_leftBracket(int value) { + set classOrMixinDeclaration_leftBracket(int value) { assert(kind == idl.LinkedNodeKind.classDeclaration || kind == idl.LinkedNodeKind.mixinDeclaration); assert(value == null || value >= 0); _variantField_19 = value; } - void set combinator_keyword(int value) { + set combinator_keyword(int value) { assert(kind == idl.LinkedNodeKind.hideCombinator || kind == idl.LinkedNodeKind.showCombinator); assert(value == null || value >= 0); _variantField_19 = value; } - void set constructorDeclaration_separator(int value) { + set constructorDeclaration_separator(int value) { assert(kind == idl.LinkedNodeKind.constructorDeclaration); assert(value == null || value >= 0); _variantField_19 = value; } - void set doStatement_whileKeyword(int value) { + set doStatement_whileKeyword(int value) { assert(kind == idl.LinkedNodeKind.doStatement); assert(value == null || value >= 0); _variantField_19 = value; } - void set forMixin_rightParenthesis(int value) { + set forMixin_rightParenthesis(int value) { assert(kind == idl.LinkedNodeKind.forElement || kind == idl.LinkedNodeKind.forStatement); assert(value == null || value >= 0); _variantField_19 = value; } - void set methodDeclaration_actualProperty(int value) { + set methodDeclaration_actualProperty(int value) { assert(kind == idl.LinkedNodeKind.methodDeclaration); assert(value == null || value >= 0); _variantField_19 = value; } - void set normalFormalParameter_covariantKeyword(int value) { + set normalFormalParameter_covariantKeyword(int value) { assert(kind == idl.LinkedNodeKind.fieldFormalParameter || kind == idl.LinkedNodeKind.functionTypedFormalParameter || kind == idl.LinkedNodeKind.simpleFormalParameter); @@ -9099,13 +9113,13 @@ _variantField_19 = value; } - void set switchStatement_rightBracket(int value) { + set switchStatement_rightBracket(int value) { assert(kind == idl.LinkedNodeKind.switchStatement); assert(value == null || value >= 0); _variantField_19 = value; } - void set typeAlias_semicolon(int value) { + set typeAlias_semicolon(int value) { assert(kind == idl.LinkedNodeKind.classTypeAlias || kind == idl.LinkedNodeKind.functionTypeAlias || kind == idl.LinkedNodeKind.genericTypeAlias); @@ -9113,14 +9127,14 @@ _variantField_19 = value; } - void set typedLiteral_constKeyword(int value) { + set typedLiteral_constKeyword(int value) { assert(kind == idl.LinkedNodeKind.listLiteral || kind == idl.LinkedNodeKind.setOrMapLiteral); assert(value == null || value >= 0); _variantField_19 = value; } - void set uriBasedDirective_uriElement(int value) { + set uriBasedDirective_uriElement(int value) { assert(kind == idl.LinkedNodeKind.exportDirective || kind == idl.LinkedNodeKind.importDirective || kind == idl.LinkedNodeKind.partDirective); @@ -9129,131 +9143,6 @@ } @override - LinkedNodeTypeBuilder get binaryExpression_invokeType { - assert(kind == idl.LinkedNodeKind.binaryExpression); - return _variantField_24; - } - - @override - LinkedNodeTypeBuilder get fieldFormalParameter_type2 { - assert(kind == idl.LinkedNodeKind.fieldFormalParameter); - return _variantField_24; - } - - @override - LinkedNodeTypeBuilder get functionDeclaration_returnType2 { - assert(kind == idl.LinkedNodeKind.functionDeclaration || - kind == idl.LinkedNodeKind.functionExpression); - return _variantField_24; - } - - @override - LinkedNodeTypeBuilder get functionTypeAlias_returnType2 { - assert(kind == idl.LinkedNodeKind.functionTypeAlias); - return _variantField_24; - } - - @override - LinkedNodeTypeBuilder get functionTypedFormalParameter_type2 { - assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter); - return _variantField_24; - } - - @override - LinkedNodeTypeBuilder get genericFunctionType_returnType2 { - assert(kind == idl.LinkedNodeKind.genericFunctionType); - return _variantField_24; - } - - @override - LinkedNodeTypeBuilder get invocationExpression_invokeType { - assert(kind == idl.LinkedNodeKind.functionExpressionInvocation || - kind == idl.LinkedNodeKind.methodInvocation); - return _variantField_24; - } - - @override - LinkedNodeTypeBuilder get methodDeclaration_returnType2 { - assert(kind == idl.LinkedNodeKind.methodDeclaration); - return _variantField_24; - } - - @override - LinkedNodeTypeBuilder get simpleFormalParameter_type2 { - assert(kind == idl.LinkedNodeKind.simpleFormalParameter); - return _variantField_24; - } - - @override - LinkedNodeTypeBuilder get typeName_type { - assert(kind == idl.LinkedNodeKind.typeName); - return _variantField_24; - } - - @override - LinkedNodeTypeBuilder get variableDeclaration_type2 { - assert(kind == idl.LinkedNodeKind.variableDeclaration); - return _variantField_24; - } - - void set binaryExpression_invokeType(LinkedNodeTypeBuilder value) { - assert(kind == idl.LinkedNodeKind.binaryExpression); - _variantField_24 = value; - } - - void set fieldFormalParameter_type2(LinkedNodeTypeBuilder value) { - assert(kind == idl.LinkedNodeKind.fieldFormalParameter); - _variantField_24 = value; - } - - void set functionDeclaration_returnType2(LinkedNodeTypeBuilder value) { - assert(kind == idl.LinkedNodeKind.functionDeclaration || - kind == idl.LinkedNodeKind.functionExpression); - _variantField_24 = value; - } - - void set functionTypeAlias_returnType2(LinkedNodeTypeBuilder value) { - assert(kind == idl.LinkedNodeKind.functionTypeAlias); - _variantField_24 = value; - } - - void set functionTypedFormalParameter_type2(LinkedNodeTypeBuilder value) { - assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter); - _variantField_24 = value; - } - - void set genericFunctionType_returnType2(LinkedNodeTypeBuilder value) { - assert(kind == idl.LinkedNodeKind.genericFunctionType); - _variantField_24 = value; - } - - void set invocationExpression_invokeType(LinkedNodeTypeBuilder value) { - assert(kind == idl.LinkedNodeKind.functionExpressionInvocation || - kind == idl.LinkedNodeKind.methodInvocation); - _variantField_24 = value; - } - - void set methodDeclaration_returnType2(LinkedNodeTypeBuilder value) { - assert(kind == idl.LinkedNodeKind.methodDeclaration); - _variantField_24 = value; - } - - void set simpleFormalParameter_type2(LinkedNodeTypeBuilder value) { - assert(kind == idl.LinkedNodeKind.simpleFormalParameter); - _variantField_24 = value; - } - - void set typeName_type(LinkedNodeTypeBuilder value) { - assert(kind == idl.LinkedNodeKind.typeName); - _variantField_24 = value; - } - - void set variableDeclaration_type2(LinkedNodeTypeBuilder value) { - assert(kind == idl.LinkedNodeKind.variableDeclaration); - _variantField_24 = value; - } - - @override bool get booleanLiteral_value { assert(kind == idl.LinkedNodeKind.booleanLiteral); return _variantField_27 ??= false; @@ -9285,29 +9174,29 @@ return _variantField_27 ??= false; } - void set booleanLiteral_value(bool value) { + set booleanLiteral_value(bool value) { assert(kind == idl.LinkedNodeKind.booleanLiteral); _variantField_27 = value; } - void set classDeclaration_isDartObject(bool value) { + set classDeclaration_isDartObject(bool value) { assert(kind == idl.LinkedNodeKind.classDeclaration); _variantField_27 = value; } - void set defaultFormalParameter_isNamed(bool value) { + set defaultFormalParameter_isNamed(bool value) { assert(kind == idl.LinkedNodeKind.defaultFormalParameter); _variantField_27 = value; } - void set normalFormalParameter_isCovariant(bool value) { + set normalFormalParameter_isCovariant(bool value) { assert(kind == idl.LinkedNodeKind.fieldFormalParameter || kind == idl.LinkedNodeKind.functionTypedFormalParameter || kind == idl.LinkedNodeKind.simpleFormalParameter); _variantField_27 = value; } - void set setOrMapLiteral_isMap(bool value) { + set setOrMapLiteral_isMap(bool value) { assert(kind == idl.LinkedNodeKind.setOrMapLiteral); _variantField_27 = value; } @@ -9342,28 +9231,27 @@ return _variantField_9; } - void set catchClause_stackTraceParameter(LinkedNodeBuilder value) { + set catchClause_stackTraceParameter(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.catchClause); _variantField_9 = value; } - void set classTypeAlias_implementsClause(LinkedNodeBuilder value) { + set classTypeAlias_implementsClause(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.classTypeAlias); _variantField_9 = value; } - void set constructorDeclaration_redirectedConstructor( - LinkedNodeBuilder value) { + set constructorDeclaration_redirectedConstructor(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.constructorDeclaration); _variantField_9 = value; } - void set ifElement_elseElement(LinkedNodeBuilder value) { + set ifElement_elseElement(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.ifElement); _variantField_9 = value; } - void set methodDeclaration_typeParameters(LinkedNodeBuilder value) { + set methodDeclaration_typeParameters(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.methodDeclaration); _variantField_9 = value; } @@ -9390,19 +9278,19 @@ return _variantField_12; } - void set classOrMixinDeclaration_implementsClause(LinkedNodeBuilder value) { + set classOrMixinDeclaration_implementsClause(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.classDeclaration || kind == idl.LinkedNodeKind.mixinDeclaration); _variantField_12 = value; } - void set invocationExpression_typeArguments(LinkedNodeBuilder value) { + set invocationExpression_typeArguments(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.functionExpressionInvocation || kind == idl.LinkedNodeKind.methodInvocation); _variantField_12 = value; } - void set normalFormalParameter_identifier(LinkedNodeBuilder value) { + set normalFormalParameter_identifier(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.fieldFormalParameter || kind == idl.LinkedNodeKind.functionTypedFormalParameter || kind == idl.LinkedNodeKind.simpleFormalParameter); @@ -9423,13 +9311,13 @@ return _variantField_5 ??= <LinkedNodeBuilder>[]; } - void set classOrMixinDeclaration_members(List<LinkedNodeBuilder> value) { + set classOrMixinDeclaration_members(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.classDeclaration || kind == idl.LinkedNodeKind.mixinDeclaration); _variantField_5 = value; } - void set forParts_updaters(List<LinkedNodeBuilder> value) { + set forParts_updaters(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations || kind == idl.LinkedNodeKind.forPartsWithExpression); _variantField_5 = value; @@ -9442,7 +9330,7 @@ return _variantField_13; } - void set classOrMixinDeclaration_typeParameters(LinkedNodeBuilder value) { + set classOrMixinDeclaration_typeParameters(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.classDeclaration || kind == idl.LinkedNodeKind.mixinDeclaration); _variantField_13 = value; @@ -9468,7 +9356,7 @@ return _variantField_34 ??= 0; } - void set codeLength(int value) { + set codeLength(int value) { assert(kind == idl.LinkedNodeKind.classDeclaration || kind == idl.LinkedNodeKind.classTypeAlias || kind == idl.LinkedNodeKind.constructorDeclaration || @@ -9518,7 +9406,7 @@ return _variantField_33 ??= 0; } - void set codeOffset(int value) { + set codeOffset(int value) { assert(kind == idl.LinkedNodeKind.classDeclaration || kind == idl.LinkedNodeKind.classTypeAlias || kind == idl.LinkedNodeKind.constructorDeclaration || @@ -9538,7 +9426,7 @@ _variantField_33 = value; } - void set directive_semicolon(int value) { + set directive_semicolon(int value) { assert(kind == idl.LinkedNodeKind.exportDirective || kind == idl.LinkedNodeKind.importDirective || kind == idl.LinkedNodeKind.libraryDirective || @@ -9560,13 +9448,13 @@ return _variantField_28 ??= <int>[]; } - void set comment_tokens(List<int> value) { + set comment_tokens(List<int> value) { assert(kind == idl.LinkedNodeKind.comment); assert(value == null || value.every((e) => e >= 0)); _variantField_28 = value; } - void set symbolLiteral_components(List<int> value) { + set symbolLiteral_components(List<int> value) { assert(kind == idl.LinkedNodeKind.symbolLiteral); assert(value == null || value.every((e) => e >= 0)); _variantField_28 = value; @@ -9578,7 +9466,7 @@ return _variantField_29 ??= idl.LinkedNodeCommentType.block; } - void set comment_type(idl.LinkedNodeCommentType value) { + set comment_type(idl.LinkedNodeCommentType value) { assert(kind == idl.LinkedNodeKind.comment); _variantField_29 = value; } @@ -9603,18 +9491,18 @@ return _variantField_3 ??= <LinkedNodeBuilder>[]; } - void set compilationUnit_directives(List<LinkedNodeBuilder> value) { + set compilationUnit_directives(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.compilationUnit); _variantField_3 = value; } - void set namespaceDirective_configurations(List<LinkedNodeBuilder> value) { + set namespaceDirective_configurations(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.exportDirective || kind == idl.LinkedNodeKind.importDirective); _variantField_3 = value; } - void set switchMember_labels(List<LinkedNodeBuilder> value) { + set switchMember_labels(List<LinkedNodeBuilder> value) { assert(kind == idl.LinkedNodeKind.switchCase || kind == idl.LinkedNodeKind.switchDefault); _variantField_3 = value; @@ -9632,12 +9520,12 @@ return _variantField_10; } - void set constructorDeclaration_returnType(LinkedNodeBuilder value) { + set constructorDeclaration_returnType(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.constructorDeclaration); _variantField_10 = value; } - void set methodDeclaration_name(LinkedNodeBuilder value) { + set methodDeclaration_name(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.methodDeclaration); _variantField_10 = value; } @@ -9648,7 +9536,7 @@ return _variantField_21 ??= 0.0; } - void set doubleLiteral_value(double value) { + set doubleLiteral_value(double value) { assert(kind == idl.LinkedNodeKind.doubleLiteral); _variantField_21 = value; } @@ -9696,7 +9584,7 @@ return _variantField_25; } - void set expression_type(LinkedNodeTypeBuilder value) { + set expression_type(LinkedNodeTypeBuilder value) { assert(kind == idl.LinkedNodeKind.adjacentStrings || kind == idl.LinkedNodeKind.assignmentExpression || kind == idl.LinkedNodeKind.asExpression || @@ -9732,7 +9620,7 @@ _variantField_25 = value; } - void set genericFunctionType_type(LinkedNodeTypeBuilder value) { + set genericFunctionType_type(LinkedNodeTypeBuilder value) { assert(kind == idl.LinkedNodeKind.genericFunctionType); _variantField_25 = value; } @@ -9745,7 +9633,7 @@ return _variantField_26 ??= idl.LinkedNodeFormalParameterKind.required; } - void set formalParameter_kind(idl.LinkedNodeFormalParameterKind value) { + set formalParameter_kind(idl.LinkedNodeFormalParameterKind value) { assert(kind == idl.LinkedNodeKind.fieldFormalParameter || kind == idl.LinkedNodeKind.functionTypedFormalParameter || kind == idl.LinkedNodeKind.simpleFormalParameter); @@ -9758,7 +9646,7 @@ return _variantField_30 ??= ''; } - void set interpolationString_value(String value) { + set interpolationString_value(String value) { assert(kind == idl.LinkedNodeKind.interpolationString); _variantField_30 = value; } @@ -9805,13 +9693,13 @@ return _variantField_14; } - void set invocationExpression_arguments(LinkedNodeBuilder value) { + set invocationExpression_arguments(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.functionExpressionInvocation || kind == idl.LinkedNodeKind.methodInvocation); _variantField_14 = value; } - void set namedCompilationUnitMember_name(LinkedNodeBuilder value) { + set namedCompilationUnitMember_name(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.classDeclaration || kind == idl.LinkedNodeKind.classTypeAlias || kind == idl.LinkedNodeKind.enumDeclaration || @@ -9822,20 +9710,20 @@ _variantField_14 = value; } - void set normalFormalParameter_comment(LinkedNodeBuilder value) { + set normalFormalParameter_comment(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.fieldFormalParameter || kind == idl.LinkedNodeKind.functionTypedFormalParameter || kind == idl.LinkedNodeKind.simpleFormalParameter); _variantField_14 = value; } - void set typedLiteral_typeArguments(LinkedNodeBuilder value) { + set typedLiteral_typeArguments(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.listLiteral || kind == idl.LinkedNodeKind.setOrMapLiteral); _variantField_14 = value; } - void set uriBasedDirective_uri(LinkedNodeBuilder value) { + set uriBasedDirective_uri(LinkedNodeBuilder value) { assert(kind == idl.LinkedNodeKind.exportDirective || kind == idl.LinkedNodeKind.importDirective || kind == idl.LinkedNodeKind.partDirective); @@ -9845,14 +9733,14 @@ @override bool get isSynthetic => _isSynthetic ??= false; - void set isSynthetic(bool value) { + set isSynthetic(bool value) { this._isSynthetic = value; } @override idl.LinkedNodeKind get kind => _kind ??= idl.LinkedNodeKind.adjacentStrings; - void set kind(idl.LinkedNodeKind value) { + set kind(idl.LinkedNodeKind value) { this._kind = value; } @@ -9865,7 +9753,7 @@ return _variantField_23 ??= ''; } - void set namespaceDirective_selectedUriContent(String value) { + set namespaceDirective_selectedUriContent(String value) { assert(kind == idl.LinkedNodeKind.exportDirective || kind == idl.LinkedNodeKind.importDirective || kind == idl.LinkedNodeKind.partDirective || @@ -9879,18 +9767,37 @@ return _variantField_31 ??= false; } - void set setOrMapLiteral_isSet(bool value) { + @override + bool get simplyBoundable_isSimplyBounded { + assert(kind == idl.LinkedNodeKind.classDeclaration || + kind == idl.LinkedNodeKind.classTypeAlias || + kind == idl.LinkedNodeKind.functionTypeAlias || + kind == idl.LinkedNodeKind.genericTypeAlias || + kind == idl.LinkedNodeKind.mixinDeclaration); + return _variantField_31 ??= false; + } + + set setOrMapLiteral_isSet(bool value) { assert(kind == idl.LinkedNodeKind.setOrMapLiteral); _variantField_31 = value; } + set simplyBoundable_isSimplyBounded(bool value) { + assert(kind == idl.LinkedNodeKind.classDeclaration || + kind == idl.LinkedNodeKind.classTypeAlias || + kind == idl.LinkedNodeKind.functionTypeAlias || + kind == idl.LinkedNodeKind.genericTypeAlias || + kind == idl.LinkedNodeKind.mixinDeclaration); + _variantField_31 = value; + } + @override String get simpleStringLiteral_value { assert(kind == idl.LinkedNodeKind.simpleStringLiteral); return _variantField_20 ??= ''; } - void set simpleStringLiteral_value(String value) { + set simpleStringLiteral_value(String value) { assert(kind == idl.LinkedNodeKind.simpleStringLiteral); _variantField_20 = value; } @@ -9903,7 +9810,7 @@ return _variantField_22 ??= ''; } - void set uriBasedDirective_uriContent(String value) { + set uriBasedDirective_uriContent(String value) { assert(kind == idl.LinkedNodeKind.exportDirective || kind == idl.LinkedNodeKind.importDirective || kind == idl.LinkedNodeKind.partDirective); @@ -9916,12 +9823,285 @@ return _variantField_32; } - void set variableDeclaration_declaration( + set variableDeclaration_declaration( LinkedNodeVariablesDeclarationBuilder value) { assert(kind == idl.LinkedNodeKind.variableDeclaration); _variantField_32 = value; } + LinkedNodeBuilder.functionDeclaration({ + LinkedNodeTypeBuilder actualReturnType, + LinkedNodeBuilder annotatedNode_comment, + List<LinkedNodeBuilder> annotatedNode_metadata, + LinkedNodeBuilder functionDeclaration_functionExpression, + int functionDeclaration_externalKeyword, + LinkedNodeBuilder functionDeclaration_returnType, + int functionDeclaration_propertyKeyword, + int codeLength, + int codeOffset, + LinkedNodeBuilder namedCompilationUnitMember_name, + }) : _kind = idl.LinkedNodeKind.functionDeclaration, + _variantField_24 = actualReturnType, + _variantField_11 = annotatedNode_comment, + _variantField_4 = annotatedNode_metadata, + _variantField_6 = functionDeclaration_functionExpression, + _variantField_15 = functionDeclaration_externalKeyword, + _variantField_7 = functionDeclaration_returnType, + _variantField_16 = functionDeclaration_propertyKeyword, + _variantField_34 = codeLength, + _variantField_33 = codeOffset, + _variantField_14 = namedCompilationUnitMember_name; + + LinkedNodeBuilder.functionExpression({ + LinkedNodeTypeBuilder actualReturnType, + LinkedNodeBuilder functionExpression_body, + LinkedNodeBuilder functionExpression_formalParameters, + LinkedNodeBuilder functionExpression_typeParameters, + }) : _kind = idl.LinkedNodeKind.functionExpression, + _variantField_24 = actualReturnType, + _variantField_6 = functionExpression_body, + _variantField_7 = functionExpression_formalParameters, + _variantField_8 = functionExpression_typeParameters; + + LinkedNodeBuilder.functionTypeAlias({ + LinkedNodeTypeBuilder actualReturnType, + LinkedNodeBuilder annotatedNode_comment, + List<LinkedNodeBuilder> annotatedNode_metadata, + LinkedNodeBuilder functionTypeAlias_formalParameters, + LinkedNodeBuilder functionTypeAlias_returnType, + LinkedNodeBuilder functionTypeAlias_typeParameters, + int typeAlias_typedefKeyword, + int typeAlias_semicolon, + int codeLength, + int codeOffset, + LinkedNodeBuilder namedCompilationUnitMember_name, + bool simplyBoundable_isSimplyBounded, + }) : _kind = idl.LinkedNodeKind.functionTypeAlias, + _variantField_24 = actualReturnType, + _variantField_11 = annotatedNode_comment, + _variantField_4 = annotatedNode_metadata, + _variantField_6 = functionTypeAlias_formalParameters, + _variantField_7 = functionTypeAlias_returnType, + _variantField_8 = functionTypeAlias_typeParameters, + _variantField_18 = typeAlias_typedefKeyword, + _variantField_19 = typeAlias_semicolon, + _variantField_34 = codeLength, + _variantField_33 = codeOffset, + _variantField_14 = namedCompilationUnitMember_name, + _variantField_31 = simplyBoundable_isSimplyBounded; + + LinkedNodeBuilder.genericFunctionType({ + LinkedNodeTypeBuilder actualReturnType, + LinkedNodeBuilder genericFunctionType_typeParameters, + int genericFunctionType_functionKeyword, + LinkedNodeBuilder genericFunctionType_returnType, + LinkedNodeBuilder genericFunctionType_formalParameters, + int genericFunctionType_question, + LinkedNodeTypeBuilder genericFunctionType_type, + }) : _kind = idl.LinkedNodeKind.genericFunctionType, + _variantField_24 = actualReturnType, + _variantField_6 = genericFunctionType_typeParameters, + _variantField_15 = genericFunctionType_functionKeyword, + _variantField_7 = genericFunctionType_returnType, + _variantField_8 = genericFunctionType_formalParameters, + _variantField_16 = genericFunctionType_question, + _variantField_25 = genericFunctionType_type; + + LinkedNodeBuilder.methodDeclaration({ + LinkedNodeTypeBuilder actualReturnType, + LinkedNodeBuilder annotatedNode_comment, + List<LinkedNodeBuilder> annotatedNode_metadata, + LinkedNodeBuilder methodDeclaration_body, + int methodDeclaration_externalKeyword, + LinkedNodeBuilder methodDeclaration_formalParameters, + LinkedNodeBuilder methodDeclaration_returnType, + int methodDeclaration_modifierKeyword, + int methodDeclaration_operatorKeyword, + int methodDeclaration_propertyKeyword, + int methodDeclaration_actualProperty, + LinkedNodeBuilder methodDeclaration_typeParameters, + int codeLength, + int codeOffset, + LinkedNodeBuilder methodDeclaration_name, + }) : _kind = idl.LinkedNodeKind.methodDeclaration, + _variantField_24 = actualReturnType, + _variantField_11 = annotatedNode_comment, + _variantField_4 = annotatedNode_metadata, + _variantField_6 = methodDeclaration_body, + _variantField_15 = methodDeclaration_externalKeyword, + _variantField_7 = methodDeclaration_formalParameters, + _variantField_8 = methodDeclaration_returnType, + _variantField_16 = methodDeclaration_modifierKeyword, + _variantField_17 = methodDeclaration_operatorKeyword, + _variantField_18 = methodDeclaration_propertyKeyword, + _variantField_19 = methodDeclaration_actualProperty, + _variantField_9 = methodDeclaration_typeParameters, + _variantField_34 = codeLength, + _variantField_33 = codeOffset, + _variantField_10 = methodDeclaration_name; + + LinkedNodeBuilder.fieldFormalParameter({ + LinkedNodeTypeBuilder actualType, + List<LinkedNodeBuilder> normalFormalParameter_metadata, + LinkedNodeBuilder fieldFormalParameter_type, + int fieldFormalParameter_keyword, + LinkedNodeBuilder fieldFormalParameter_typeParameters, + LinkedNodeBuilder fieldFormalParameter_formalParameters, + int fieldFormalParameter_period, + int fieldFormalParameter_thisKeyword, + int normalFormalParameter_covariantKeyword, + bool normalFormalParameter_isCovariant, + LinkedNodeBuilder normalFormalParameter_identifier, + int codeLength, + int codeOffset, + idl.LinkedNodeFormalParameterKind formalParameter_kind, + LinkedNodeBuilder normalFormalParameter_comment, + }) : _kind = idl.LinkedNodeKind.fieldFormalParameter, + _variantField_24 = actualType, + _variantField_4 = normalFormalParameter_metadata, + _variantField_6 = fieldFormalParameter_type, + _variantField_15 = fieldFormalParameter_keyword, + _variantField_7 = fieldFormalParameter_typeParameters, + _variantField_8 = fieldFormalParameter_formalParameters, + _variantField_16 = fieldFormalParameter_period, + _variantField_17 = fieldFormalParameter_thisKeyword, + _variantField_19 = normalFormalParameter_covariantKeyword, + _variantField_27 = normalFormalParameter_isCovariant, + _variantField_12 = normalFormalParameter_identifier, + _variantField_34 = codeLength, + _variantField_33 = codeOffset, + _variantField_26 = formalParameter_kind, + _variantField_14 = normalFormalParameter_comment; + + LinkedNodeBuilder.functionTypedFormalParameter({ + LinkedNodeTypeBuilder actualType, + List<LinkedNodeBuilder> normalFormalParameter_metadata, + LinkedNodeBuilder functionTypedFormalParameter_formalParameters, + LinkedNodeBuilder functionTypedFormalParameter_returnType, + LinkedNodeBuilder functionTypedFormalParameter_typeParameters, + int normalFormalParameter_covariantKeyword, + bool normalFormalParameter_isCovariant, + LinkedNodeBuilder normalFormalParameter_identifier, + int codeLength, + int codeOffset, + idl.LinkedNodeFormalParameterKind formalParameter_kind, + LinkedNodeBuilder normalFormalParameter_comment, + }) : _kind = idl.LinkedNodeKind.functionTypedFormalParameter, + _variantField_24 = actualType, + _variantField_4 = normalFormalParameter_metadata, + _variantField_6 = functionTypedFormalParameter_formalParameters, + _variantField_7 = functionTypedFormalParameter_returnType, + _variantField_8 = functionTypedFormalParameter_typeParameters, + _variantField_19 = normalFormalParameter_covariantKeyword, + _variantField_27 = normalFormalParameter_isCovariant, + _variantField_12 = normalFormalParameter_identifier, + _variantField_34 = codeLength, + _variantField_33 = codeOffset, + _variantField_26 = formalParameter_kind, + _variantField_14 = normalFormalParameter_comment; + + LinkedNodeBuilder.simpleFormalParameter({ + LinkedNodeTypeBuilder actualType, + List<LinkedNodeBuilder> normalFormalParameter_metadata, + LinkedNodeBuilder simpleFormalParameter_type, + int simpleFormalParameter_keyword, + int normalFormalParameter_covariantKeyword, + bool normalFormalParameter_isCovariant, + LinkedNodeBuilder normalFormalParameter_identifier, + int codeLength, + int codeOffset, + idl.LinkedNodeFormalParameterKind formalParameter_kind, + LinkedNodeBuilder normalFormalParameter_comment, + }) : _kind = idl.LinkedNodeKind.simpleFormalParameter, + _variantField_24 = actualType, + _variantField_4 = normalFormalParameter_metadata, + _variantField_6 = simpleFormalParameter_type, + _variantField_15 = simpleFormalParameter_keyword, + _variantField_19 = normalFormalParameter_covariantKeyword, + _variantField_27 = normalFormalParameter_isCovariant, + _variantField_12 = normalFormalParameter_identifier, + _variantField_34 = codeLength, + _variantField_33 = codeOffset, + _variantField_26 = formalParameter_kind, + _variantField_14 = normalFormalParameter_comment; + + LinkedNodeBuilder.variableDeclaration({ + LinkedNodeTypeBuilder actualType, + LinkedNodeBuilder annotatedNode_comment, + List<LinkedNodeBuilder> annotatedNode_metadata, + LinkedNodeBuilder variableDeclaration_initializer, + int variableDeclaration_equals, + LinkedNodeBuilder variableDeclaration_name, + int codeLength, + int codeOffset, + LinkedNodeVariablesDeclarationBuilder variableDeclaration_declaration, + }) : _kind = idl.LinkedNodeKind.variableDeclaration, + _variantField_24 = actualType, + _variantField_11 = annotatedNode_comment, + _variantField_4 = annotatedNode_metadata, + _variantField_6 = variableDeclaration_initializer, + _variantField_15 = variableDeclaration_equals, + _variantField_7 = variableDeclaration_name, + _variantField_34 = codeLength, + _variantField_33 = codeOffset, + _variantField_32 = variableDeclaration_declaration; + + LinkedNodeBuilder.binaryExpression({ + LinkedNodeTypeBuilder binaryExpression_invokeType, + LinkedNodeBuilder binaryExpression_leftOperand, + int binaryExpression_element, + LinkedNodeBuilder binaryExpression_rightOperand, + int binaryExpression_operator, + LinkedNodeTypeBuilder expression_type, + }) : _kind = idl.LinkedNodeKind.binaryExpression, + _variantField_24 = binaryExpression_invokeType, + _variantField_6 = binaryExpression_leftOperand, + _variantField_15 = binaryExpression_element, + _variantField_7 = binaryExpression_rightOperand, + _variantField_16 = binaryExpression_operator, + _variantField_25 = expression_type; + + LinkedNodeBuilder.functionExpressionInvocation({ + LinkedNodeTypeBuilder invocationExpression_invokeType, + LinkedNodeBuilder functionExpressionInvocation_function, + LinkedNodeBuilder invocationExpression_typeArguments, + LinkedNodeTypeBuilder expression_type, + LinkedNodeBuilder invocationExpression_arguments, + }) : _kind = idl.LinkedNodeKind.functionExpressionInvocation, + _variantField_24 = invocationExpression_invokeType, + _variantField_6 = functionExpressionInvocation_function, + _variantField_12 = invocationExpression_typeArguments, + _variantField_25 = expression_type, + _variantField_14 = invocationExpression_arguments; + + LinkedNodeBuilder.methodInvocation({ + LinkedNodeTypeBuilder invocationExpression_invokeType, + LinkedNodeBuilder methodInvocation_methodName, + int methodInvocation_operator, + LinkedNodeBuilder methodInvocation_target, + LinkedNodeBuilder invocationExpression_typeArguments, + LinkedNodeTypeBuilder expression_type, + LinkedNodeBuilder invocationExpression_arguments, + }) : _kind = idl.LinkedNodeKind.methodInvocation, + _variantField_24 = invocationExpression_invokeType, + _variantField_6 = methodInvocation_methodName, + _variantField_15 = methodInvocation_operator, + _variantField_7 = methodInvocation_target, + _variantField_12 = invocationExpression_typeArguments, + _variantField_25 = expression_type, + _variantField_14 = invocationExpression_arguments; + + LinkedNodeBuilder.typeName({ + LinkedNodeTypeBuilder typeName_type, + LinkedNodeBuilder typeName_name, + int typeName_question, + LinkedNodeBuilder typeName_typeArguments, + }) : _kind = idl.LinkedNodeKind.typeName, + _variantField_24 = typeName_type, + _variantField_6 = typeName_name, + _variantField_15 = typeName_question, + _variantField_7 = typeName_typeArguments; + LinkedNodeBuilder.adjacentStrings({ List<LinkedNodeBuilder> adjacentStrings_strings, LinkedNodeTypeBuilder expression_type, @@ -10259,6 +10439,7 @@ int codeLength, int codeOffset, LinkedNodeBuilder namedCompilationUnitMember_name, + bool simplyBoundable_isSimplyBounded, }) : _kind = idl.LinkedNodeKind.classDeclaration, _variantField_11 = annotatedNode_comment, _variantField_4 = annotatedNode_metadata, @@ -10275,7 +10456,8 @@ _variantField_13 = classOrMixinDeclaration_typeParameters, _variantField_34 = codeLength, _variantField_33 = codeOffset, - _variantField_14 = namedCompilationUnitMember_name; + _variantField_14 = namedCompilationUnitMember_name, + _variantField_31 = simplyBoundable_isSimplyBounded; LinkedNodeBuilder.classTypeAlias({ LinkedNodeBuilder annotatedNode_comment, @@ -10291,6 +10473,7 @@ int codeLength, int codeOffset, LinkedNodeBuilder namedCompilationUnitMember_name, + bool simplyBoundable_isSimplyBounded, }) : _kind = idl.LinkedNodeKind.classTypeAlias, _variantField_11 = annotatedNode_comment, _variantField_4 = annotatedNode_metadata, @@ -10304,7 +10487,8 @@ _variantField_9 = classTypeAlias_implementsClause, _variantField_34 = codeLength, _variantField_33 = codeOffset, - _variantField_14 = namedCompilationUnitMember_name; + _variantField_14 = namedCompilationUnitMember_name, + _variantField_31 = simplyBoundable_isSimplyBounded; LinkedNodeBuilder.declaredIdentifier({ LinkedNodeBuilder annotatedNode_comment, @@ -10343,54 +10527,6 @@ _variantField_16 = fieldDeclaration_semicolon, _variantField_17 = fieldDeclaration_staticKeyword; - LinkedNodeBuilder.functionDeclaration({ - LinkedNodeBuilder annotatedNode_comment, - List<LinkedNodeBuilder> annotatedNode_metadata, - LinkedNodeBuilder functionDeclaration_functionExpression, - int functionDeclaration_externalKeyword, - LinkedNodeBuilder functionDeclaration_returnType, - int functionDeclaration_propertyKeyword, - LinkedNodeTypeBuilder functionDeclaration_returnType2, - int codeLength, - int codeOffset, - LinkedNodeBuilder namedCompilationUnitMember_name, - }) : _kind = idl.LinkedNodeKind.functionDeclaration, - _variantField_11 = annotatedNode_comment, - _variantField_4 = annotatedNode_metadata, - _variantField_6 = functionDeclaration_functionExpression, - _variantField_15 = functionDeclaration_externalKeyword, - _variantField_7 = functionDeclaration_returnType, - _variantField_16 = functionDeclaration_propertyKeyword, - _variantField_24 = functionDeclaration_returnType2, - _variantField_34 = codeLength, - _variantField_33 = codeOffset, - _variantField_14 = namedCompilationUnitMember_name; - - LinkedNodeBuilder.functionTypeAlias({ - LinkedNodeBuilder annotatedNode_comment, - List<LinkedNodeBuilder> annotatedNode_metadata, - LinkedNodeBuilder functionTypeAlias_formalParameters, - LinkedNodeBuilder functionTypeAlias_returnType, - LinkedNodeBuilder functionTypeAlias_typeParameters, - int typeAlias_typedefKeyword, - int typeAlias_semicolon, - LinkedNodeTypeBuilder functionTypeAlias_returnType2, - int codeLength, - int codeOffset, - LinkedNodeBuilder namedCompilationUnitMember_name, - }) : _kind = idl.LinkedNodeKind.functionTypeAlias, - _variantField_11 = annotatedNode_comment, - _variantField_4 = annotatedNode_metadata, - _variantField_6 = functionTypeAlias_formalParameters, - _variantField_7 = functionTypeAlias_returnType, - _variantField_8 = functionTypeAlias_typeParameters, - _variantField_18 = typeAlias_typedefKeyword, - _variantField_19 = typeAlias_semicolon, - _variantField_24 = functionTypeAlias_returnType2, - _variantField_34 = codeLength, - _variantField_33 = codeOffset, - _variantField_14 = namedCompilationUnitMember_name; - LinkedNodeBuilder.genericTypeAlias({ LinkedNodeBuilder annotatedNode_comment, List<LinkedNodeBuilder> annotatedNode_metadata, @@ -10402,6 +10538,7 @@ int codeLength, int codeOffset, LinkedNodeBuilder namedCompilationUnitMember_name, + bool simplyBoundable_isSimplyBounded, }) : _kind = idl.LinkedNodeKind.genericTypeAlias, _variantField_11 = annotatedNode_comment, _variantField_4 = annotatedNode_metadata, @@ -10412,7 +10549,8 @@ _variantField_19 = typeAlias_semicolon, _variantField_34 = codeLength, _variantField_33 = codeOffset, - _variantField_14 = namedCompilationUnitMember_name; + _variantField_14 = namedCompilationUnitMember_name, + _variantField_31 = simplyBoundable_isSimplyBounded; LinkedNodeBuilder.libraryDirective({ LinkedNodeBuilder annotatedNode_comment, @@ -10427,39 +10565,6 @@ _variantField_18 = directive_keyword, _variantField_33 = directive_semicolon; - LinkedNodeBuilder.methodDeclaration({ - LinkedNodeBuilder annotatedNode_comment, - List<LinkedNodeBuilder> annotatedNode_metadata, - LinkedNodeBuilder methodDeclaration_body, - int methodDeclaration_externalKeyword, - LinkedNodeBuilder methodDeclaration_formalParameters, - LinkedNodeBuilder methodDeclaration_returnType, - int methodDeclaration_modifierKeyword, - int methodDeclaration_operatorKeyword, - int methodDeclaration_propertyKeyword, - int methodDeclaration_actualProperty, - LinkedNodeTypeBuilder methodDeclaration_returnType2, - LinkedNodeBuilder methodDeclaration_typeParameters, - int codeLength, - int codeOffset, - LinkedNodeBuilder methodDeclaration_name, - }) : _kind = idl.LinkedNodeKind.methodDeclaration, - _variantField_11 = annotatedNode_comment, - _variantField_4 = annotatedNode_metadata, - _variantField_6 = methodDeclaration_body, - _variantField_15 = methodDeclaration_externalKeyword, - _variantField_7 = methodDeclaration_formalParameters, - _variantField_8 = methodDeclaration_returnType, - _variantField_16 = methodDeclaration_modifierKeyword, - _variantField_17 = methodDeclaration_operatorKeyword, - _variantField_18 = methodDeclaration_propertyKeyword, - _variantField_19 = methodDeclaration_actualProperty, - _variantField_24 = methodDeclaration_returnType2, - _variantField_9 = methodDeclaration_typeParameters, - _variantField_34 = codeLength, - _variantField_33 = codeOffset, - _variantField_10 = methodDeclaration_name; - LinkedNodeBuilder.mixinDeclaration({ LinkedNodeBuilder annotatedNode_comment, List<LinkedNodeBuilder> annotatedNode_metadata, @@ -10473,6 +10578,7 @@ int codeLength, int codeOffset, LinkedNodeBuilder namedCompilationUnitMember_name, + bool simplyBoundable_isSimplyBounded, }) : _kind = idl.LinkedNodeKind.mixinDeclaration, _variantField_11 = annotatedNode_comment, _variantField_4 = annotatedNode_metadata, @@ -10485,7 +10591,8 @@ _variantField_13 = classOrMixinDeclaration_typeParameters, _variantField_34 = codeLength, _variantField_33 = codeOffset, - _variantField_14 = namedCompilationUnitMember_name; + _variantField_14 = namedCompilationUnitMember_name, + _variantField_31 = simplyBoundable_isSimplyBounded; LinkedNodeBuilder.partDirective({ LinkedNodeBuilder annotatedNode_comment, @@ -10553,112 +10660,6 @@ _variantField_34 = codeLength, _variantField_33 = codeOffset; - LinkedNodeBuilder.variableDeclaration({ - LinkedNodeBuilder annotatedNode_comment, - List<LinkedNodeBuilder> annotatedNode_metadata, - LinkedNodeBuilder variableDeclaration_initializer, - int variableDeclaration_equals, - LinkedNodeBuilder variableDeclaration_name, - LinkedNodeTypeBuilder variableDeclaration_type2, - int codeLength, - int codeOffset, - LinkedNodeVariablesDeclarationBuilder variableDeclaration_declaration, - }) : _kind = idl.LinkedNodeKind.variableDeclaration, - _variantField_11 = annotatedNode_comment, - _variantField_4 = annotatedNode_metadata, - _variantField_6 = variableDeclaration_initializer, - _variantField_15 = variableDeclaration_equals, - _variantField_7 = variableDeclaration_name, - _variantField_24 = variableDeclaration_type2, - _variantField_34 = codeLength, - _variantField_33 = codeOffset, - _variantField_32 = variableDeclaration_declaration; - - LinkedNodeBuilder.fieldFormalParameter({ - List<LinkedNodeBuilder> normalFormalParameter_metadata, - LinkedNodeBuilder fieldFormalParameter_type, - int fieldFormalParameter_keyword, - LinkedNodeBuilder fieldFormalParameter_typeParameters, - LinkedNodeBuilder fieldFormalParameter_formalParameters, - int fieldFormalParameter_period, - int fieldFormalParameter_thisKeyword, - int normalFormalParameter_covariantKeyword, - LinkedNodeTypeBuilder fieldFormalParameter_type2, - bool normalFormalParameter_isCovariant, - LinkedNodeBuilder normalFormalParameter_identifier, - int codeLength, - int codeOffset, - idl.LinkedNodeFormalParameterKind formalParameter_kind, - LinkedNodeBuilder normalFormalParameter_comment, - }) : _kind = idl.LinkedNodeKind.fieldFormalParameter, - _variantField_4 = normalFormalParameter_metadata, - _variantField_6 = fieldFormalParameter_type, - _variantField_15 = fieldFormalParameter_keyword, - _variantField_7 = fieldFormalParameter_typeParameters, - _variantField_8 = fieldFormalParameter_formalParameters, - _variantField_16 = fieldFormalParameter_period, - _variantField_17 = fieldFormalParameter_thisKeyword, - _variantField_19 = normalFormalParameter_covariantKeyword, - _variantField_24 = fieldFormalParameter_type2, - _variantField_27 = normalFormalParameter_isCovariant, - _variantField_12 = normalFormalParameter_identifier, - _variantField_34 = codeLength, - _variantField_33 = codeOffset, - _variantField_26 = formalParameter_kind, - _variantField_14 = normalFormalParameter_comment; - - LinkedNodeBuilder.functionTypedFormalParameter({ - List<LinkedNodeBuilder> normalFormalParameter_metadata, - LinkedNodeBuilder functionTypedFormalParameter_formalParameters, - LinkedNodeBuilder functionTypedFormalParameter_returnType, - LinkedNodeBuilder functionTypedFormalParameter_typeParameters, - int normalFormalParameter_covariantKeyword, - LinkedNodeTypeBuilder functionTypedFormalParameter_type2, - bool normalFormalParameter_isCovariant, - LinkedNodeBuilder normalFormalParameter_identifier, - int codeLength, - int codeOffset, - idl.LinkedNodeFormalParameterKind formalParameter_kind, - LinkedNodeBuilder normalFormalParameter_comment, - }) : _kind = idl.LinkedNodeKind.functionTypedFormalParameter, - _variantField_4 = normalFormalParameter_metadata, - _variantField_6 = functionTypedFormalParameter_formalParameters, - _variantField_7 = functionTypedFormalParameter_returnType, - _variantField_8 = functionTypedFormalParameter_typeParameters, - _variantField_19 = normalFormalParameter_covariantKeyword, - _variantField_24 = functionTypedFormalParameter_type2, - _variantField_27 = normalFormalParameter_isCovariant, - _variantField_12 = normalFormalParameter_identifier, - _variantField_34 = codeLength, - _variantField_33 = codeOffset, - _variantField_26 = formalParameter_kind, - _variantField_14 = normalFormalParameter_comment; - - LinkedNodeBuilder.simpleFormalParameter({ - List<LinkedNodeBuilder> normalFormalParameter_metadata, - LinkedNodeBuilder simpleFormalParameter_type, - int simpleFormalParameter_keyword, - int normalFormalParameter_covariantKeyword, - LinkedNodeTypeBuilder simpleFormalParameter_type2, - bool normalFormalParameter_isCovariant, - LinkedNodeBuilder normalFormalParameter_identifier, - int codeLength, - int codeOffset, - idl.LinkedNodeFormalParameterKind formalParameter_kind, - LinkedNodeBuilder normalFormalParameter_comment, - }) : _kind = idl.LinkedNodeKind.simpleFormalParameter, - _variantField_4 = normalFormalParameter_metadata, - _variantField_6 = simpleFormalParameter_type, - _variantField_15 = simpleFormalParameter_keyword, - _variantField_19 = normalFormalParameter_covariantKeyword, - _variantField_24 = simpleFormalParameter_type2, - _variantField_27 = normalFormalParameter_isCovariant, - _variantField_12 = normalFormalParameter_identifier, - _variantField_34 = codeLength, - _variantField_33 = codeOffset, - _variantField_26 = formalParameter_kind, - _variantField_14 = normalFormalParameter_comment; - LinkedNodeBuilder.switchCase({ List<LinkedNodeBuilder> switchMember_statements, LinkedNodeBuilder switchCase_expression, @@ -10761,21 +10762,6 @@ _variantField_15 = awaitExpression_awaitKeyword, _variantField_25 = expression_type; - LinkedNodeBuilder.binaryExpression({ - LinkedNodeBuilder binaryExpression_leftOperand, - int binaryExpression_element, - LinkedNodeBuilder binaryExpression_rightOperand, - int binaryExpression_operator, - LinkedNodeTypeBuilder binaryExpression_invokeType, - LinkedNodeTypeBuilder expression_type, - }) : _kind = idl.LinkedNodeKind.binaryExpression, - _variantField_6 = binaryExpression_leftOperand, - _variantField_15 = binaryExpression_element, - _variantField_7 = binaryExpression_rightOperand, - _variantField_16 = binaryExpression_operator, - _variantField_24 = binaryExpression_invokeType, - _variantField_25 = expression_type; - LinkedNodeBuilder.blockFunctionBody({ LinkedNodeBuilder blockFunctionBody_block, int blockFunctionBody_keyword, @@ -11016,47 +11002,6 @@ }) : _kind = idl.LinkedNodeKind.functionDeclarationStatement, _variantField_6 = functionDeclarationStatement_functionDeclaration; - LinkedNodeBuilder.functionExpression({ - LinkedNodeBuilder functionExpression_body, - LinkedNodeBuilder functionExpression_formalParameters, - LinkedNodeBuilder functionExpression_typeParameters, - LinkedNodeTypeBuilder functionDeclaration_returnType2, - }) : _kind = idl.LinkedNodeKind.functionExpression, - _variantField_6 = functionExpression_body, - _variantField_7 = functionExpression_formalParameters, - _variantField_8 = functionExpression_typeParameters, - _variantField_24 = functionDeclaration_returnType2; - - LinkedNodeBuilder.functionExpressionInvocation({ - LinkedNodeBuilder functionExpressionInvocation_function, - LinkedNodeTypeBuilder invocationExpression_invokeType, - LinkedNodeBuilder invocationExpression_typeArguments, - LinkedNodeTypeBuilder expression_type, - LinkedNodeBuilder invocationExpression_arguments, - }) : _kind = idl.LinkedNodeKind.functionExpressionInvocation, - _variantField_6 = functionExpressionInvocation_function, - _variantField_24 = invocationExpression_invokeType, - _variantField_12 = invocationExpression_typeArguments, - _variantField_25 = expression_type, - _variantField_14 = invocationExpression_arguments; - - LinkedNodeBuilder.genericFunctionType({ - LinkedNodeBuilder genericFunctionType_typeParameters, - int genericFunctionType_functionKeyword, - LinkedNodeBuilder genericFunctionType_returnType, - LinkedNodeBuilder genericFunctionType_formalParameters, - int genericFunctionType_question, - LinkedNodeTypeBuilder genericFunctionType_returnType2, - LinkedNodeTypeBuilder genericFunctionType_type, - }) : _kind = idl.LinkedNodeKind.genericFunctionType, - _variantField_6 = genericFunctionType_typeParameters, - _variantField_15 = genericFunctionType_functionKeyword, - _variantField_7 = genericFunctionType_returnType, - _variantField_8 = genericFunctionType_formalParameters, - _variantField_16 = genericFunctionType_question, - _variantField_24 = genericFunctionType_returnType2, - _variantField_25 = genericFunctionType_type; - LinkedNodeBuilder.ifElement({ LinkedNodeBuilder ifMixin_condition, int ifMixin_elseKeyword, @@ -11159,23 +11104,6 @@ _variantField_15 = mapLiteralEntry_separator, _variantField_7 = mapLiteralEntry_value; - LinkedNodeBuilder.methodInvocation({ - LinkedNodeBuilder methodInvocation_methodName, - int methodInvocation_operator, - LinkedNodeBuilder methodInvocation_target, - LinkedNodeTypeBuilder invocationExpression_invokeType, - LinkedNodeBuilder invocationExpression_typeArguments, - LinkedNodeTypeBuilder expression_type, - LinkedNodeBuilder invocationExpression_arguments, - }) : _kind = idl.LinkedNodeKind.methodInvocation, - _variantField_6 = methodInvocation_methodName, - _variantField_15 = methodInvocation_operator, - _variantField_7 = methodInvocation_target, - _variantField_24 = invocationExpression_invokeType, - _variantField_12 = invocationExpression_typeArguments, - _variantField_25 = expression_type, - _variantField_14 = invocationExpression_arguments; - LinkedNodeBuilder.namedExpression({ LinkedNodeBuilder namedExpression_expression, LinkedNodeBuilder namedExpression_name, @@ -11307,17 +11235,6 @@ _variantField_15 = throwExpression_throwKeyword, _variantField_25 = expression_type; - LinkedNodeBuilder.typeName({ - LinkedNodeBuilder typeName_name, - int typeName_question, - LinkedNodeBuilder typeName_typeArguments, - LinkedNodeTypeBuilder typeName_type, - }) : _kind = idl.LinkedNodeKind.typeName, - _variantField_6 = typeName_name, - _variantField_15 = typeName_question, - _variantField_7 = typeName_typeArguments, - _variantField_24 = typeName_type; - LinkedNodeBuilder.variableDeclarationStatement({ LinkedNodeBuilder variableDeclarationStatement_variables, int variableDeclarationStatement_semicolon, @@ -11460,17 +11377,15 @@ _variantField_28 = comment_tokens, _variantField_29 = comment_type; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { + _variantField_24?.flushInformative(); _variantField_2?.forEach((b) => b.flushInformative()); _variantField_11?.flushInformative(); _variantField_4?.forEach((b) => b.flushInformative()); _variantField_6?.flushInformative(); _variantField_7?.flushInformative(); _variantField_8?.flushInformative(); - _variantField_24?.flushInformative(); _variantField_9?.flushInformative(); _variantField_12?.flushInformative(); _variantField_5?.forEach((b) => b.flushInformative()); @@ -11482,9 +11397,7 @@ _variantField_32?.flushInformative(); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addInt(this._kind == null ? 0 : this._kind.index); signature.addBool(this._isSynthetic == true); @@ -11573,13 +11486,13 @@ } fb.Offset finish(fb.Builder fbBuilder) { + fb.Offset offset_variantField_24; fb.Offset offset_variantField_2; fb.Offset offset_variantField_11; fb.Offset offset_variantField_4; fb.Offset offset_variantField_6; fb.Offset offset_variantField_7; fb.Offset offset_variantField_8; - fb.Offset offset_variantField_24; fb.Offset offset_variantField_9; fb.Offset offset_variantField_12; fb.Offset offset_variantField_5; @@ -11594,6 +11507,9 @@ fb.Offset offset_variantField_20; fb.Offset offset_variantField_22; fb.Offset offset_variantField_32; + if (_variantField_24 != null) { + offset_variantField_24 = _variantField_24.finish(fbBuilder); + } if (!(_variantField_2 == null || _variantField_2.isEmpty)) { offset_variantField_2 = fbBuilder .writeList(_variantField_2.map((b) => b.finish(fbBuilder)).toList()); @@ -11614,9 +11530,6 @@ if (_variantField_8 != null) { offset_variantField_8 = _variantField_8.finish(fbBuilder); } - if (_variantField_24 != null) { - offset_variantField_24 = _variantField_24.finish(fbBuilder); - } if (_variantField_9 != null) { offset_variantField_9 = _variantField_9.finish(fbBuilder); } @@ -11662,6 +11575,9 @@ offset_variantField_32 = _variantField_32.finish(fbBuilder); } fbBuilder.startTable(); + if (offset_variantField_24 != null) { + fbBuilder.addOffset(24, offset_variantField_24); + } if (offset_variantField_2 != null) { fbBuilder.addOffset(2, offset_variantField_2); } @@ -11695,9 +11611,6 @@ if (_variantField_19 != null && _variantField_19 != 0) { fbBuilder.addUint32(19, _variantField_19); } - if (offset_variantField_24 != null) { - fbBuilder.addOffset(24, offset_variantField_24); - } if (_variantField_27 == true) { fbBuilder.addBool(27, true); } @@ -11789,6 +11702,7 @@ _LinkedNodeImpl(this._bc, this._bcOffset); + idl.LinkedNodeType _variantField_24; List<idl.LinkedNode> _variantField_2; idl.LinkedNode _variantField_11; List<idl.LinkedNode> _variantField_4; @@ -11800,7 +11714,6 @@ int _variantField_17; int _variantField_18; int _variantField_19; - idl.LinkedNodeType _variantField_24; bool _variantField_27; idl.LinkedNode _variantField_9; idl.LinkedNode _variantField_12; @@ -11826,6 +11739,54 @@ idl.LinkedNodeVariablesDeclaration _variantField_32; @override + idl.LinkedNodeType get actualReturnType { + assert(kind == idl.LinkedNodeKind.functionDeclaration || + kind == idl.LinkedNodeKind.functionExpression || + kind == idl.LinkedNodeKind.functionTypeAlias || + kind == idl.LinkedNodeKind.genericFunctionType || + kind == idl.LinkedNodeKind.methodDeclaration); + _variantField_24 ??= + const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null); + return _variantField_24; + } + + @override + idl.LinkedNodeType get actualType { + assert(kind == idl.LinkedNodeKind.fieldFormalParameter || + kind == idl.LinkedNodeKind.functionTypedFormalParameter || + kind == idl.LinkedNodeKind.simpleFormalParameter || + kind == idl.LinkedNodeKind.variableDeclaration); + _variantField_24 ??= + const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null); + return _variantField_24; + } + + @override + idl.LinkedNodeType get binaryExpression_invokeType { + assert(kind == idl.LinkedNodeKind.binaryExpression); + _variantField_24 ??= + const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null); + return _variantField_24; + } + + @override + idl.LinkedNodeType get invocationExpression_invokeType { + assert(kind == idl.LinkedNodeKind.functionExpressionInvocation || + kind == idl.LinkedNodeKind.methodInvocation); + _variantField_24 ??= + const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null); + return _variantField_24; + } + + @override + idl.LinkedNodeType get typeName_type { + assert(kind == idl.LinkedNodeKind.typeName); + _variantField_24 ??= + const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null); + return _variantField_24; + } + + @override List<idl.LinkedNode> get adjacentStrings_strings { assert(kind == idl.LinkedNodeKind.adjacentStrings); _variantField_2 ??= @@ -14867,96 +14828,6 @@ } @override - idl.LinkedNodeType get binaryExpression_invokeType { - assert(kind == idl.LinkedNodeKind.binaryExpression); - _variantField_24 ??= - const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null); - return _variantField_24; - } - - @override - idl.LinkedNodeType get fieldFormalParameter_type2 { - assert(kind == idl.LinkedNodeKind.fieldFormalParameter); - _variantField_24 ??= - const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null); - return _variantField_24; - } - - @override - idl.LinkedNodeType get functionDeclaration_returnType2 { - assert(kind == idl.LinkedNodeKind.functionDeclaration || - kind == idl.LinkedNodeKind.functionExpression); - _variantField_24 ??= - const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null); - return _variantField_24; - } - - @override - idl.LinkedNodeType get functionTypeAlias_returnType2 { - assert(kind == idl.LinkedNodeKind.functionTypeAlias); - _variantField_24 ??= - const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null); - return _variantField_24; - } - - @override - idl.LinkedNodeType get functionTypedFormalParameter_type2 { - assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter); - _variantField_24 ??= - const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null); - return _variantField_24; - } - - @override - idl.LinkedNodeType get genericFunctionType_returnType2 { - assert(kind == idl.LinkedNodeKind.genericFunctionType); - _variantField_24 ??= - const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null); - return _variantField_24; - } - - @override - idl.LinkedNodeType get invocationExpression_invokeType { - assert(kind == idl.LinkedNodeKind.functionExpressionInvocation || - kind == idl.LinkedNodeKind.methodInvocation); - _variantField_24 ??= - const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null); - return _variantField_24; - } - - @override - idl.LinkedNodeType get methodDeclaration_returnType2 { - assert(kind == idl.LinkedNodeKind.methodDeclaration); - _variantField_24 ??= - const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null); - return _variantField_24; - } - - @override - idl.LinkedNodeType get simpleFormalParameter_type2 { - assert(kind == idl.LinkedNodeKind.simpleFormalParameter); - _variantField_24 ??= - const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null); - return _variantField_24; - } - - @override - idl.LinkedNodeType get typeName_type { - assert(kind == idl.LinkedNodeKind.typeName); - _variantField_24 ??= - const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null); - return _variantField_24; - } - - @override - idl.LinkedNodeType get variableDeclaration_type2 { - assert(kind == idl.LinkedNodeKind.variableDeclaration); - _variantField_24 ??= - const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null); - return _variantField_24; - } - - @override bool get booleanLiteral_value { assert(kind == idl.LinkedNodeKind.booleanLiteral); _variantField_27 ??= @@ -15378,6 +15249,18 @@ } @override + bool get simplyBoundable_isSimplyBounded { + assert(kind == idl.LinkedNodeKind.classDeclaration || + kind == idl.LinkedNodeKind.classTypeAlias || + kind == idl.LinkedNodeKind.functionTypeAlias || + kind == idl.LinkedNodeKind.genericTypeAlias || + kind == idl.LinkedNodeKind.mixinDeclaration); + _variantField_31 ??= + const fb.BoolReader().vTableGet(_bc, _bcOffset, 31, false); + return _variantField_31; + } + + @override String get simpleStringLiteral_value { assert(kind == idl.LinkedNodeKind.simpleStringLiteral); _variantField_20 ??= @@ -15411,6 +15294,322 @@ if (isSynthetic != false) _result["isSynthetic"] = isSynthetic; if (kind != idl.LinkedNodeKind.adjacentStrings) _result["kind"] = kind.toString().split('.')[1]; + if (kind == idl.LinkedNodeKind.functionDeclaration) { + if (actualReturnType != null) + _result["actualReturnType"] = actualReturnType.toJson(); + if (annotatedNode_comment != null) + _result["annotatedNode_comment"] = annotatedNode_comment.toJson(); + if (annotatedNode_metadata.isNotEmpty) + _result["annotatedNode_metadata"] = + annotatedNode_metadata.map((_value) => _value.toJson()).toList(); + if (functionDeclaration_functionExpression != null) + _result["functionDeclaration_functionExpression"] = + functionDeclaration_functionExpression.toJson(); + if (functionDeclaration_externalKeyword != 0) + _result["functionDeclaration_externalKeyword"] = + functionDeclaration_externalKeyword; + if (functionDeclaration_returnType != null) + _result["functionDeclaration_returnType"] = + functionDeclaration_returnType.toJson(); + if (functionDeclaration_propertyKeyword != 0) + _result["functionDeclaration_propertyKeyword"] = + functionDeclaration_propertyKeyword; + if (codeLength != 0) _result["codeLength"] = codeLength; + if (codeOffset != 0) _result["codeOffset"] = codeOffset; + if (namedCompilationUnitMember_name != null) + _result["namedCompilationUnitMember_name"] = + namedCompilationUnitMember_name.toJson(); + } + if (kind == idl.LinkedNodeKind.functionExpression) { + if (actualReturnType != null) + _result["actualReturnType"] = actualReturnType.toJson(); + if (functionExpression_body != null) + _result["functionExpression_body"] = functionExpression_body.toJson(); + if (functionExpression_formalParameters != null) + _result["functionExpression_formalParameters"] = + functionExpression_formalParameters.toJson(); + if (functionExpression_typeParameters != null) + _result["functionExpression_typeParameters"] = + functionExpression_typeParameters.toJson(); + } + if (kind == idl.LinkedNodeKind.functionTypeAlias) { + if (actualReturnType != null) + _result["actualReturnType"] = actualReturnType.toJson(); + if (annotatedNode_comment != null) + _result["annotatedNode_comment"] = annotatedNode_comment.toJson(); + if (annotatedNode_metadata.isNotEmpty) + _result["annotatedNode_metadata"] = + annotatedNode_metadata.map((_value) => _value.toJson()).toList(); + if (functionTypeAlias_formalParameters != null) + _result["functionTypeAlias_formalParameters"] = + functionTypeAlias_formalParameters.toJson(); + if (functionTypeAlias_returnType != null) + _result["functionTypeAlias_returnType"] = + functionTypeAlias_returnType.toJson(); + if (functionTypeAlias_typeParameters != null) + _result["functionTypeAlias_typeParameters"] = + functionTypeAlias_typeParameters.toJson(); + if (typeAlias_typedefKeyword != 0) + _result["typeAlias_typedefKeyword"] = typeAlias_typedefKeyword; + if (typeAlias_semicolon != 0) + _result["typeAlias_semicolon"] = typeAlias_semicolon; + if (codeLength != 0) _result["codeLength"] = codeLength; + if (codeOffset != 0) _result["codeOffset"] = codeOffset; + if (namedCompilationUnitMember_name != null) + _result["namedCompilationUnitMember_name"] = + namedCompilationUnitMember_name.toJson(); + if (simplyBoundable_isSimplyBounded != false) + _result["simplyBoundable_isSimplyBounded"] = + simplyBoundable_isSimplyBounded; + } + if (kind == idl.LinkedNodeKind.genericFunctionType) { + if (actualReturnType != null) + _result["actualReturnType"] = actualReturnType.toJson(); + if (genericFunctionType_typeParameters != null) + _result["genericFunctionType_typeParameters"] = + genericFunctionType_typeParameters.toJson(); + if (genericFunctionType_functionKeyword != 0) + _result["genericFunctionType_functionKeyword"] = + genericFunctionType_functionKeyword; + if (genericFunctionType_returnType != null) + _result["genericFunctionType_returnType"] = + genericFunctionType_returnType.toJson(); + if (genericFunctionType_formalParameters != null) + _result["genericFunctionType_formalParameters"] = + genericFunctionType_formalParameters.toJson(); + if (genericFunctionType_question != 0) + _result["genericFunctionType_question"] = genericFunctionType_question; + if (genericFunctionType_type != null) + _result["genericFunctionType_type"] = genericFunctionType_type.toJson(); + } + if (kind == idl.LinkedNodeKind.methodDeclaration) { + if (actualReturnType != null) + _result["actualReturnType"] = actualReturnType.toJson(); + if (annotatedNode_comment != null) + _result["annotatedNode_comment"] = annotatedNode_comment.toJson(); + if (annotatedNode_metadata.isNotEmpty) + _result["annotatedNode_metadata"] = + annotatedNode_metadata.map((_value) => _value.toJson()).toList(); + if (methodDeclaration_body != null) + _result["methodDeclaration_body"] = methodDeclaration_body.toJson(); + if (methodDeclaration_externalKeyword != 0) + _result["methodDeclaration_externalKeyword"] = + methodDeclaration_externalKeyword; + if (methodDeclaration_formalParameters != null) + _result["methodDeclaration_formalParameters"] = + methodDeclaration_formalParameters.toJson(); + if (methodDeclaration_returnType != null) + _result["methodDeclaration_returnType"] = + methodDeclaration_returnType.toJson(); + if (methodDeclaration_modifierKeyword != 0) + _result["methodDeclaration_modifierKeyword"] = + methodDeclaration_modifierKeyword; + if (methodDeclaration_operatorKeyword != 0) + _result["methodDeclaration_operatorKeyword"] = + methodDeclaration_operatorKeyword; + if (methodDeclaration_propertyKeyword != 0) + _result["methodDeclaration_propertyKeyword"] = + methodDeclaration_propertyKeyword; + if (methodDeclaration_actualProperty != 0) + _result["methodDeclaration_actualProperty"] = + methodDeclaration_actualProperty; + if (methodDeclaration_typeParameters != null) + _result["methodDeclaration_typeParameters"] = + methodDeclaration_typeParameters.toJson(); + if (codeLength != 0) _result["codeLength"] = codeLength; + if (codeOffset != 0) _result["codeOffset"] = codeOffset; + if (methodDeclaration_name != null) + _result["methodDeclaration_name"] = methodDeclaration_name.toJson(); + } + if (kind == idl.LinkedNodeKind.fieldFormalParameter) { + if (actualType != null) _result["actualType"] = actualType.toJson(); + if (normalFormalParameter_metadata.isNotEmpty) + _result["normalFormalParameter_metadata"] = + normalFormalParameter_metadata + .map((_value) => _value.toJson()) + .toList(); + if (fieldFormalParameter_type != null) + _result["fieldFormalParameter_type"] = + fieldFormalParameter_type.toJson(); + if (fieldFormalParameter_keyword != 0) + _result["fieldFormalParameter_keyword"] = fieldFormalParameter_keyword; + if (fieldFormalParameter_typeParameters != null) + _result["fieldFormalParameter_typeParameters"] = + fieldFormalParameter_typeParameters.toJson(); + if (fieldFormalParameter_formalParameters != null) + _result["fieldFormalParameter_formalParameters"] = + fieldFormalParameter_formalParameters.toJson(); + if (fieldFormalParameter_period != 0) + _result["fieldFormalParameter_period"] = fieldFormalParameter_period; + if (fieldFormalParameter_thisKeyword != 0) + _result["fieldFormalParameter_thisKeyword"] = + fieldFormalParameter_thisKeyword; + if (normalFormalParameter_covariantKeyword != 0) + _result["normalFormalParameter_covariantKeyword"] = + normalFormalParameter_covariantKeyword; + if (normalFormalParameter_isCovariant != false) + _result["normalFormalParameter_isCovariant"] = + normalFormalParameter_isCovariant; + if (normalFormalParameter_identifier != null) + _result["normalFormalParameter_identifier"] = + normalFormalParameter_identifier.toJson(); + if (codeLength != 0) _result["codeLength"] = codeLength; + if (codeOffset != 0) _result["codeOffset"] = codeOffset; + if (formalParameter_kind != idl.LinkedNodeFormalParameterKind.required) + _result["formalParameter_kind"] = + formalParameter_kind.toString().split('.')[1]; + if (normalFormalParameter_comment != null) + _result["normalFormalParameter_comment"] = + normalFormalParameter_comment.toJson(); + } + if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) { + if (actualType != null) _result["actualType"] = actualType.toJson(); + if (normalFormalParameter_metadata.isNotEmpty) + _result["normalFormalParameter_metadata"] = + normalFormalParameter_metadata + .map((_value) => _value.toJson()) + .toList(); + if (functionTypedFormalParameter_formalParameters != null) + _result["functionTypedFormalParameter_formalParameters"] = + functionTypedFormalParameter_formalParameters.toJson(); + if (functionTypedFormalParameter_returnType != null) + _result["functionTypedFormalParameter_returnType"] = + functionTypedFormalParameter_returnType.toJson(); + if (functionTypedFormalParameter_typeParameters != null) + _result["functionTypedFormalParameter_typeParameters"] = + functionTypedFormalParameter_typeParameters.toJson(); + if (normalFormalParameter_covariantKeyword != 0) + _result["normalFormalParameter_covariantKeyword"] = + normalFormalParameter_covariantKeyword; + if (normalFormalParameter_isCovariant != false) + _result["normalFormalParameter_isCovariant"] = + normalFormalParameter_isCovariant; + if (normalFormalParameter_identifier != null) + _result["normalFormalParameter_identifier"] = + normalFormalParameter_identifier.toJson(); + if (codeLength != 0) _result["codeLength"] = codeLength; + if (codeOffset != 0) _result["codeOffset"] = codeOffset; + if (formalParameter_kind != idl.LinkedNodeFormalParameterKind.required) + _result["formalParameter_kind"] = + formalParameter_kind.toString().split('.')[1]; + if (normalFormalParameter_comment != null) + _result["normalFormalParameter_comment"] = + normalFormalParameter_comment.toJson(); + } + if (kind == idl.LinkedNodeKind.simpleFormalParameter) { + if (actualType != null) _result["actualType"] = actualType.toJson(); + if (normalFormalParameter_metadata.isNotEmpty) + _result["normalFormalParameter_metadata"] = + normalFormalParameter_metadata + .map((_value) => _value.toJson()) + .toList(); + if (simpleFormalParameter_type != null) + _result["simpleFormalParameter_type"] = + simpleFormalParameter_type.toJson(); + if (simpleFormalParameter_keyword != 0) + _result["simpleFormalParameter_keyword"] = + simpleFormalParameter_keyword; + if (normalFormalParameter_covariantKeyword != 0) + _result["normalFormalParameter_covariantKeyword"] = + normalFormalParameter_covariantKeyword; + if (normalFormalParameter_isCovariant != false) + _result["normalFormalParameter_isCovariant"] = + normalFormalParameter_isCovariant; + if (normalFormalParameter_identifier != null) + _result["normalFormalParameter_identifier"] = + normalFormalParameter_identifier.toJson(); + if (codeLength != 0) _result["codeLength"] = codeLength; + if (codeOffset != 0) _result["codeOffset"] = codeOffset; + if (formalParameter_kind != idl.LinkedNodeFormalParameterKind.required) + _result["formalParameter_kind"] = + formalParameter_kind.toString().split('.')[1]; + if (normalFormalParameter_comment != null) + _result["normalFormalParameter_comment"] = + normalFormalParameter_comment.toJson(); + } + if (kind == idl.LinkedNodeKind.variableDeclaration) { + if (actualType != null) _result["actualType"] = actualType.toJson(); + if (annotatedNode_comment != null) + _result["annotatedNode_comment"] = annotatedNode_comment.toJson(); + if (annotatedNode_metadata.isNotEmpty) + _result["annotatedNode_metadata"] = + annotatedNode_metadata.map((_value) => _value.toJson()).toList(); + if (variableDeclaration_initializer != null) + _result["variableDeclaration_initializer"] = + variableDeclaration_initializer.toJson(); + if (variableDeclaration_equals != 0) + _result["variableDeclaration_equals"] = variableDeclaration_equals; + if (variableDeclaration_name != null) + _result["variableDeclaration_name"] = variableDeclaration_name.toJson(); + if (codeLength != 0) _result["codeLength"] = codeLength; + if (codeOffset != 0) _result["codeOffset"] = codeOffset; + if (variableDeclaration_declaration != null) + _result["variableDeclaration_declaration"] = + variableDeclaration_declaration.toJson(); + } + if (kind == idl.LinkedNodeKind.binaryExpression) { + if (binaryExpression_invokeType != null) + _result["binaryExpression_invokeType"] = + binaryExpression_invokeType.toJson(); + if (binaryExpression_leftOperand != null) + _result["binaryExpression_leftOperand"] = + binaryExpression_leftOperand.toJson(); + if (binaryExpression_element != 0) + _result["binaryExpression_element"] = binaryExpression_element; + if (binaryExpression_rightOperand != null) + _result["binaryExpression_rightOperand"] = + binaryExpression_rightOperand.toJson(); + if (binaryExpression_operator != 0) + _result["binaryExpression_operator"] = binaryExpression_operator; + if (expression_type != null) + _result["expression_type"] = expression_type.toJson(); + } + if (kind == idl.LinkedNodeKind.functionExpressionInvocation) { + if (invocationExpression_invokeType != null) + _result["invocationExpression_invokeType"] = + invocationExpression_invokeType.toJson(); + if (functionExpressionInvocation_function != null) + _result["functionExpressionInvocation_function"] = + functionExpressionInvocation_function.toJson(); + if (invocationExpression_typeArguments != null) + _result["invocationExpression_typeArguments"] = + invocationExpression_typeArguments.toJson(); + if (expression_type != null) + _result["expression_type"] = expression_type.toJson(); + if (invocationExpression_arguments != null) + _result["invocationExpression_arguments"] = + invocationExpression_arguments.toJson(); + } + if (kind == idl.LinkedNodeKind.methodInvocation) { + if (invocationExpression_invokeType != null) + _result["invocationExpression_invokeType"] = + invocationExpression_invokeType.toJson(); + if (methodInvocation_methodName != null) + _result["methodInvocation_methodName"] = + methodInvocation_methodName.toJson(); + if (methodInvocation_operator != 0) + _result["methodInvocation_operator"] = methodInvocation_operator; + if (methodInvocation_target != null) + _result["methodInvocation_target"] = methodInvocation_target.toJson(); + if (invocationExpression_typeArguments != null) + _result["invocationExpression_typeArguments"] = + invocationExpression_typeArguments.toJson(); + if (expression_type != null) + _result["expression_type"] = expression_type.toJson(); + if (invocationExpression_arguments != null) + _result["invocationExpression_arguments"] = + invocationExpression_arguments.toJson(); + } + if (kind == idl.LinkedNodeKind.typeName) { + if (typeName_type != null) + _result["typeName_type"] = typeName_type.toJson(); + if (typeName_name != null) + _result["typeName_name"] = typeName_name.toJson(); + if (typeName_question != 0) + _result["typeName_question"] = typeName_question; + if (typeName_typeArguments != null) + _result["typeName_typeArguments"] = typeName_typeArguments.toJson(); + } if (kind == idl.LinkedNodeKind.adjacentStrings) { if (adjacentStrings_strings.isNotEmpty) _result["adjacentStrings_strings"] = @@ -15841,6 +16040,9 @@ if (namedCompilationUnitMember_name != null) _result["namedCompilationUnitMember_name"] = namedCompilationUnitMember_name.toJson(); + if (simplyBoundable_isSimplyBounded != false) + _result["simplyBoundable_isSimplyBounded"] = + simplyBoundable_isSimplyBounded; } if (kind == idl.LinkedNodeKind.classTypeAlias) { if (annotatedNode_comment != null) @@ -15874,6 +16076,9 @@ if (namedCompilationUnitMember_name != null) _result["namedCompilationUnitMember_name"] = namedCompilationUnitMember_name.toJson(); + if (simplyBoundable_isSimplyBounded != false) + _result["simplyBoundable_isSimplyBounded"] = + simplyBoundable_isSimplyBounded; } if (kind == idl.LinkedNodeKind.declaredIdentifier) { if (annotatedNode_comment != null) @@ -15916,61 +16121,6 @@ _result["fieldDeclaration_staticKeyword"] = fieldDeclaration_staticKeyword; } - if (kind == idl.LinkedNodeKind.functionDeclaration) { - if (annotatedNode_comment != null) - _result["annotatedNode_comment"] = annotatedNode_comment.toJson(); - if (annotatedNode_metadata.isNotEmpty) - _result["annotatedNode_metadata"] = - annotatedNode_metadata.map((_value) => _value.toJson()).toList(); - if (functionDeclaration_functionExpression != null) - _result["functionDeclaration_functionExpression"] = - functionDeclaration_functionExpression.toJson(); - if (functionDeclaration_externalKeyword != 0) - _result["functionDeclaration_externalKeyword"] = - functionDeclaration_externalKeyword; - if (functionDeclaration_returnType != null) - _result["functionDeclaration_returnType"] = - functionDeclaration_returnType.toJson(); - if (functionDeclaration_propertyKeyword != 0) - _result["functionDeclaration_propertyKeyword"] = - functionDeclaration_propertyKeyword; - if (functionDeclaration_returnType2 != null) - _result["functionDeclaration_returnType2"] = - functionDeclaration_returnType2.toJson(); - if (codeLength != 0) _result["codeLength"] = codeLength; - if (codeOffset != 0) _result["codeOffset"] = codeOffset; - if (namedCompilationUnitMember_name != null) - _result["namedCompilationUnitMember_name"] = - namedCompilationUnitMember_name.toJson(); - } - if (kind == idl.LinkedNodeKind.functionTypeAlias) { - if (annotatedNode_comment != null) - _result["annotatedNode_comment"] = annotatedNode_comment.toJson(); - if (annotatedNode_metadata.isNotEmpty) - _result["annotatedNode_metadata"] = - annotatedNode_metadata.map((_value) => _value.toJson()).toList(); - if (functionTypeAlias_formalParameters != null) - _result["functionTypeAlias_formalParameters"] = - functionTypeAlias_formalParameters.toJson(); - if (functionTypeAlias_returnType != null) - _result["functionTypeAlias_returnType"] = - functionTypeAlias_returnType.toJson(); - if (functionTypeAlias_typeParameters != null) - _result["functionTypeAlias_typeParameters"] = - functionTypeAlias_typeParameters.toJson(); - if (typeAlias_typedefKeyword != 0) - _result["typeAlias_typedefKeyword"] = typeAlias_typedefKeyword; - if (typeAlias_semicolon != 0) - _result["typeAlias_semicolon"] = typeAlias_semicolon; - if (functionTypeAlias_returnType2 != null) - _result["functionTypeAlias_returnType2"] = - functionTypeAlias_returnType2.toJson(); - if (codeLength != 0) _result["codeLength"] = codeLength; - if (codeOffset != 0) _result["codeOffset"] = codeOffset; - if (namedCompilationUnitMember_name != null) - _result["namedCompilationUnitMember_name"] = - namedCompilationUnitMember_name.toJson(); - } if (kind == idl.LinkedNodeKind.genericTypeAlias) { if (annotatedNode_comment != null) _result["annotatedNode_comment"] = annotatedNode_comment.toJson(); @@ -15994,6 +16144,9 @@ if (namedCompilationUnitMember_name != null) _result["namedCompilationUnitMember_name"] = namedCompilationUnitMember_name.toJson(); + if (simplyBoundable_isSimplyBounded != false) + _result["simplyBoundable_isSimplyBounded"] = + simplyBoundable_isSimplyBounded; } if (kind == idl.LinkedNodeKind.libraryDirective) { if (annotatedNode_comment != null) @@ -16008,46 +16161,6 @@ if (directive_semicolon != 0) _result["directive_semicolon"] = directive_semicolon; } - if (kind == idl.LinkedNodeKind.methodDeclaration) { - if (annotatedNode_comment != null) - _result["annotatedNode_comment"] = annotatedNode_comment.toJson(); - if (annotatedNode_metadata.isNotEmpty) - _result["annotatedNode_metadata"] = - annotatedNode_metadata.map((_value) => _value.toJson()).toList(); - if (methodDeclaration_body != null) - _result["methodDeclaration_body"] = methodDeclaration_body.toJson(); - if (methodDeclaration_externalKeyword != 0) - _result["methodDeclaration_externalKeyword"] = - methodDeclaration_externalKeyword; - if (methodDeclaration_formalParameters != null) - _result["methodDeclaration_formalParameters"] = - methodDeclaration_formalParameters.toJson(); - if (methodDeclaration_returnType != null) - _result["methodDeclaration_returnType"] = - methodDeclaration_returnType.toJson(); - if (methodDeclaration_modifierKeyword != 0) - _result["methodDeclaration_modifierKeyword"] = - methodDeclaration_modifierKeyword; - if (methodDeclaration_operatorKeyword != 0) - _result["methodDeclaration_operatorKeyword"] = - methodDeclaration_operatorKeyword; - if (methodDeclaration_propertyKeyword != 0) - _result["methodDeclaration_propertyKeyword"] = - methodDeclaration_propertyKeyword; - if (methodDeclaration_actualProperty != 0) - _result["methodDeclaration_actualProperty"] = - methodDeclaration_actualProperty; - if (methodDeclaration_returnType2 != null) - _result["methodDeclaration_returnType2"] = - methodDeclaration_returnType2.toJson(); - if (methodDeclaration_typeParameters != null) - _result["methodDeclaration_typeParameters"] = - methodDeclaration_typeParameters.toJson(); - if (codeLength != 0) _result["codeLength"] = codeLength; - if (codeOffset != 0) _result["codeOffset"] = codeOffset; - if (methodDeclaration_name != null) - _result["methodDeclaration_name"] = methodDeclaration_name.toJson(); - } if (kind == idl.LinkedNodeKind.mixinDeclaration) { if (annotatedNode_comment != null) _result["annotatedNode_comment"] = annotatedNode_comment.toJson(); @@ -16082,6 +16195,9 @@ if (namedCompilationUnitMember_name != null) _result["namedCompilationUnitMember_name"] = namedCompilationUnitMember_name.toJson(); + if (simplyBoundable_isSimplyBounded != false) + _result["simplyBoundable_isSimplyBounded"] = + simplyBoundable_isSimplyBounded; } if (kind == idl.LinkedNodeKind.partDirective) { if (annotatedNode_comment != null) @@ -16152,140 +16268,6 @@ if (codeLength != 0) _result["codeLength"] = codeLength; if (codeOffset != 0) _result["codeOffset"] = codeOffset; } - if (kind == idl.LinkedNodeKind.variableDeclaration) { - if (annotatedNode_comment != null) - _result["annotatedNode_comment"] = annotatedNode_comment.toJson(); - if (annotatedNode_metadata.isNotEmpty) - _result["annotatedNode_metadata"] = - annotatedNode_metadata.map((_value) => _value.toJson()).toList(); - if (variableDeclaration_initializer != null) - _result["variableDeclaration_initializer"] = - variableDeclaration_initializer.toJson(); - if (variableDeclaration_equals != 0) - _result["variableDeclaration_equals"] = variableDeclaration_equals; - if (variableDeclaration_name != null) - _result["variableDeclaration_name"] = variableDeclaration_name.toJson(); - if (variableDeclaration_type2 != null) - _result["variableDeclaration_type2"] = - variableDeclaration_type2.toJson(); - if (codeLength != 0) _result["codeLength"] = codeLength; - if (codeOffset != 0) _result["codeOffset"] = codeOffset; - if (variableDeclaration_declaration != null) - _result["variableDeclaration_declaration"] = - variableDeclaration_declaration.toJson(); - } - if (kind == idl.LinkedNodeKind.fieldFormalParameter) { - if (normalFormalParameter_metadata.isNotEmpty) - _result["normalFormalParameter_metadata"] = - normalFormalParameter_metadata - .map((_value) => _value.toJson()) - .toList(); - if (fieldFormalParameter_type != null) - _result["fieldFormalParameter_type"] = - fieldFormalParameter_type.toJson(); - if (fieldFormalParameter_keyword != 0) - _result["fieldFormalParameter_keyword"] = fieldFormalParameter_keyword; - if (fieldFormalParameter_typeParameters != null) - _result["fieldFormalParameter_typeParameters"] = - fieldFormalParameter_typeParameters.toJson(); - if (fieldFormalParameter_formalParameters != null) - _result["fieldFormalParameter_formalParameters"] = - fieldFormalParameter_formalParameters.toJson(); - if (fieldFormalParameter_period != 0) - _result["fieldFormalParameter_period"] = fieldFormalParameter_period; - if (fieldFormalParameter_thisKeyword != 0) - _result["fieldFormalParameter_thisKeyword"] = - fieldFormalParameter_thisKeyword; - if (normalFormalParameter_covariantKeyword != 0) - _result["normalFormalParameter_covariantKeyword"] = - normalFormalParameter_covariantKeyword; - if (fieldFormalParameter_type2 != null) - _result["fieldFormalParameter_type2"] = - fieldFormalParameter_type2.toJson(); - if (normalFormalParameter_isCovariant != false) - _result["normalFormalParameter_isCovariant"] = - normalFormalParameter_isCovariant; - if (normalFormalParameter_identifier != null) - _result["normalFormalParameter_identifier"] = - normalFormalParameter_identifier.toJson(); - if (codeLength != 0) _result["codeLength"] = codeLength; - if (codeOffset != 0) _result["codeOffset"] = codeOffset; - if (formalParameter_kind != idl.LinkedNodeFormalParameterKind.required) - _result["formalParameter_kind"] = - formalParameter_kind.toString().split('.')[1]; - if (normalFormalParameter_comment != null) - _result["normalFormalParameter_comment"] = - normalFormalParameter_comment.toJson(); - } - if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) { - if (normalFormalParameter_metadata.isNotEmpty) - _result["normalFormalParameter_metadata"] = - normalFormalParameter_metadata - .map((_value) => _value.toJson()) - .toList(); - if (functionTypedFormalParameter_formalParameters != null) - _result["functionTypedFormalParameter_formalParameters"] = - functionTypedFormalParameter_formalParameters.toJson(); - if (functionTypedFormalParameter_returnType != null) - _result["functionTypedFormalParameter_returnType"] = - functionTypedFormalParameter_returnType.toJson(); - if (functionTypedFormalParameter_typeParameters != null) - _result["functionTypedFormalParameter_typeParameters"] = - functionTypedFormalParameter_typeParameters.toJson(); - if (normalFormalParameter_covariantKeyword != 0) - _result["normalFormalParameter_covariantKeyword"] = - normalFormalParameter_covariantKeyword; - if (functionTypedFormalParameter_type2 != null) - _result["functionTypedFormalParameter_type2"] = - functionTypedFormalParameter_type2.toJson(); - if (normalFormalParameter_isCovariant != false) - _result["normalFormalParameter_isCovariant"] = - normalFormalParameter_isCovariant; - if (normalFormalParameter_identifier != null) - _result["normalFormalParameter_identifier"] = - normalFormalParameter_identifier.toJson(); - if (codeLength != 0) _result["codeLength"] = codeLength; - if (codeOffset != 0) _result["codeOffset"] = codeOffset; - if (formalParameter_kind != idl.LinkedNodeFormalParameterKind.required) - _result["formalParameter_kind"] = - formalParameter_kind.toString().split('.')[1]; - if (normalFormalParameter_comment != null) - _result["normalFormalParameter_comment"] = - normalFormalParameter_comment.toJson(); - } - if (kind == idl.LinkedNodeKind.simpleFormalParameter) { - if (normalFormalParameter_metadata.isNotEmpty) - _result["normalFormalParameter_metadata"] = - normalFormalParameter_metadata - .map((_value) => _value.toJson()) - .toList(); - if (simpleFormalParameter_type != null) - _result["simpleFormalParameter_type"] = - simpleFormalParameter_type.toJson(); - if (simpleFormalParameter_keyword != 0) - _result["simpleFormalParameter_keyword"] = - simpleFormalParameter_keyword; - if (normalFormalParameter_covariantKeyword != 0) - _result["normalFormalParameter_covariantKeyword"] = - normalFormalParameter_covariantKeyword; - if (simpleFormalParameter_type2 != null) - _result["simpleFormalParameter_type2"] = - simpleFormalParameter_type2.toJson(); - if (normalFormalParameter_isCovariant != false) - _result["normalFormalParameter_isCovariant"] = - normalFormalParameter_isCovariant; - if (normalFormalParameter_identifier != null) - _result["normalFormalParameter_identifier"] = - normalFormalParameter_identifier.toJson(); - if (codeLength != 0) _result["codeLength"] = codeLength; - if (codeOffset != 0) _result["codeOffset"] = codeOffset; - if (formalParameter_kind != idl.LinkedNodeFormalParameterKind.required) - _result["formalParameter_kind"] = - formalParameter_kind.toString().split('.')[1]; - if (normalFormalParameter_comment != null) - _result["normalFormalParameter_comment"] = - normalFormalParameter_comment.toJson(); - } if (kind == idl.LinkedNodeKind.switchCase) { if (switchMember_statements.isNotEmpty) _result["switchMember_statements"] = @@ -16398,23 +16380,6 @@ if (expression_type != null) _result["expression_type"] = expression_type.toJson(); } - if (kind == idl.LinkedNodeKind.binaryExpression) { - if (binaryExpression_leftOperand != null) - _result["binaryExpression_leftOperand"] = - binaryExpression_leftOperand.toJson(); - if (binaryExpression_element != 0) - _result["binaryExpression_element"] = binaryExpression_element; - if (binaryExpression_rightOperand != null) - _result["binaryExpression_rightOperand"] = - binaryExpression_rightOperand.toJson(); - if (binaryExpression_operator != 0) - _result["binaryExpression_operator"] = binaryExpression_operator; - if (binaryExpression_invokeType != null) - _result["binaryExpression_invokeType"] = - binaryExpression_invokeType.toJson(); - if (expression_type != null) - _result["expression_type"] = expression_type.toJson(); - } if (kind == idl.LinkedNodeKind.blockFunctionBody) { if (blockFunctionBody_block != null) _result["blockFunctionBody_block"] = blockFunctionBody_block.toJson(); @@ -16664,56 +16629,6 @@ _result["functionDeclarationStatement_functionDeclaration"] = functionDeclarationStatement_functionDeclaration.toJson(); } - if (kind == idl.LinkedNodeKind.functionExpression) { - if (functionExpression_body != null) - _result["functionExpression_body"] = functionExpression_body.toJson(); - if (functionExpression_formalParameters != null) - _result["functionExpression_formalParameters"] = - functionExpression_formalParameters.toJson(); - if (functionExpression_typeParameters != null) - _result["functionExpression_typeParameters"] = - functionExpression_typeParameters.toJson(); - if (functionDeclaration_returnType2 != null) - _result["functionDeclaration_returnType2"] = - functionDeclaration_returnType2.toJson(); - } - if (kind == idl.LinkedNodeKind.functionExpressionInvocation) { - if (functionExpressionInvocation_function != null) - _result["functionExpressionInvocation_function"] = - functionExpressionInvocation_function.toJson(); - if (invocationExpression_invokeType != null) - _result["invocationExpression_invokeType"] = - invocationExpression_invokeType.toJson(); - if (invocationExpression_typeArguments != null) - _result["invocationExpression_typeArguments"] = - invocationExpression_typeArguments.toJson(); - if (expression_type != null) - _result["expression_type"] = expression_type.toJson(); - if (invocationExpression_arguments != null) - _result["invocationExpression_arguments"] = - invocationExpression_arguments.toJson(); - } - if (kind == idl.LinkedNodeKind.genericFunctionType) { - if (genericFunctionType_typeParameters != null) - _result["genericFunctionType_typeParameters"] = - genericFunctionType_typeParameters.toJson(); - if (genericFunctionType_functionKeyword != 0) - _result["genericFunctionType_functionKeyword"] = - genericFunctionType_functionKeyword; - if (genericFunctionType_returnType != null) - _result["genericFunctionType_returnType"] = - genericFunctionType_returnType.toJson(); - if (genericFunctionType_formalParameters != null) - _result["genericFunctionType_formalParameters"] = - genericFunctionType_formalParameters.toJson(); - if (genericFunctionType_question != 0) - _result["genericFunctionType_question"] = genericFunctionType_question; - if (genericFunctionType_returnType2 != null) - _result["genericFunctionType_returnType2"] = - genericFunctionType_returnType2.toJson(); - if (genericFunctionType_type != null) - _result["genericFunctionType_type"] = genericFunctionType_type.toJson(); - } if (kind == idl.LinkedNodeKind.ifElement) { if (ifMixin_condition != null) _result["ifMixin_condition"] = ifMixin_condition.toJson(); @@ -16815,26 +16730,6 @@ if (mapLiteralEntry_value != null) _result["mapLiteralEntry_value"] = mapLiteralEntry_value.toJson(); } - if (kind == idl.LinkedNodeKind.methodInvocation) { - if (methodInvocation_methodName != null) - _result["methodInvocation_methodName"] = - methodInvocation_methodName.toJson(); - if (methodInvocation_operator != 0) - _result["methodInvocation_operator"] = methodInvocation_operator; - if (methodInvocation_target != null) - _result["methodInvocation_target"] = methodInvocation_target.toJson(); - if (invocationExpression_invokeType != null) - _result["invocationExpression_invokeType"] = - invocationExpression_invokeType.toJson(); - if (invocationExpression_typeArguments != null) - _result["invocationExpression_typeArguments"] = - invocationExpression_typeArguments.toJson(); - if (expression_type != null) - _result["expression_type"] = expression_type.toJson(); - if (invocationExpression_arguments != null) - _result["invocationExpression_arguments"] = - invocationExpression_arguments.toJson(); - } if (kind == idl.LinkedNodeKind.namedExpression) { if (namedExpression_expression != null) _result["namedExpression_expression"] = @@ -16976,16 +16871,6 @@ if (expression_type != null) _result["expression_type"] = expression_type.toJson(); } - if (kind == idl.LinkedNodeKind.typeName) { - if (typeName_name != null) - _result["typeName_name"] = typeName_name.toJson(); - if (typeName_question != 0) - _result["typeName_question"] = typeName_question; - if (typeName_typeArguments != null) - _result["typeName_typeArguments"] = typeName_typeArguments.toJson(); - if (typeName_type != null) - _result["typeName_type"] = typeName_type.toJson(); - } if (kind == idl.LinkedNodeKind.variableDeclarationStatement) { if (variableDeclarationStatement_variables != null) _result["variableDeclarationStatement_variables"] = @@ -17122,6 +17007,221 @@ @override Map<String, Object> toMap() { + if (kind == idl.LinkedNodeKind.functionDeclaration) { + return { + "actualReturnType": actualReturnType, + "annotatedNode_comment": annotatedNode_comment, + "annotatedNode_metadata": annotatedNode_metadata, + "functionDeclaration_functionExpression": + functionDeclaration_functionExpression, + "functionDeclaration_externalKeyword": + functionDeclaration_externalKeyword, + "functionDeclaration_returnType": functionDeclaration_returnType, + "functionDeclaration_propertyKeyword": + functionDeclaration_propertyKeyword, + "codeLength": codeLength, + "codeOffset": codeOffset, + "namedCompilationUnitMember_name": namedCompilationUnitMember_name, + "isSynthetic": isSynthetic, + "kind": kind, + }; + } + if (kind == idl.LinkedNodeKind.functionExpression) { + return { + "actualReturnType": actualReturnType, + "functionExpression_body": functionExpression_body, + "functionExpression_formalParameters": + functionExpression_formalParameters, + "functionExpression_typeParameters": functionExpression_typeParameters, + "isSynthetic": isSynthetic, + "kind": kind, + }; + } + if (kind == idl.LinkedNodeKind.functionTypeAlias) { + return { + "actualReturnType": actualReturnType, + "annotatedNode_comment": annotatedNode_comment, + "annotatedNode_metadata": annotatedNode_metadata, + "functionTypeAlias_formalParameters": + functionTypeAlias_formalParameters, + "functionTypeAlias_returnType": functionTypeAlias_returnType, + "functionTypeAlias_typeParameters": functionTypeAlias_typeParameters, + "typeAlias_typedefKeyword": typeAlias_typedefKeyword, + "typeAlias_semicolon": typeAlias_semicolon, + "codeLength": codeLength, + "codeOffset": codeOffset, + "namedCompilationUnitMember_name": namedCompilationUnitMember_name, + "isSynthetic": isSynthetic, + "kind": kind, + "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded, + }; + } + if (kind == idl.LinkedNodeKind.genericFunctionType) { + return { + "actualReturnType": actualReturnType, + "genericFunctionType_typeParameters": + genericFunctionType_typeParameters, + "genericFunctionType_functionKeyword": + genericFunctionType_functionKeyword, + "genericFunctionType_returnType": genericFunctionType_returnType, + "genericFunctionType_formalParameters": + genericFunctionType_formalParameters, + "genericFunctionType_question": genericFunctionType_question, + "genericFunctionType_type": genericFunctionType_type, + "isSynthetic": isSynthetic, + "kind": kind, + }; + } + if (kind == idl.LinkedNodeKind.methodDeclaration) { + return { + "actualReturnType": actualReturnType, + "annotatedNode_comment": annotatedNode_comment, + "annotatedNode_metadata": annotatedNode_metadata, + "methodDeclaration_body": methodDeclaration_body, + "methodDeclaration_externalKeyword": methodDeclaration_externalKeyword, + "methodDeclaration_formalParameters": + methodDeclaration_formalParameters, + "methodDeclaration_returnType": methodDeclaration_returnType, + "methodDeclaration_modifierKeyword": methodDeclaration_modifierKeyword, + "methodDeclaration_operatorKeyword": methodDeclaration_operatorKeyword, + "methodDeclaration_propertyKeyword": methodDeclaration_propertyKeyword, + "methodDeclaration_actualProperty": methodDeclaration_actualProperty, + "methodDeclaration_typeParameters": methodDeclaration_typeParameters, + "codeLength": codeLength, + "codeOffset": codeOffset, + "methodDeclaration_name": methodDeclaration_name, + "isSynthetic": isSynthetic, + "kind": kind, + }; + } + if (kind == idl.LinkedNodeKind.fieldFormalParameter) { + return { + "actualType": actualType, + "normalFormalParameter_metadata": normalFormalParameter_metadata, + "fieldFormalParameter_type": fieldFormalParameter_type, + "fieldFormalParameter_keyword": fieldFormalParameter_keyword, + "fieldFormalParameter_typeParameters": + fieldFormalParameter_typeParameters, + "fieldFormalParameter_formalParameters": + fieldFormalParameter_formalParameters, + "fieldFormalParameter_period": fieldFormalParameter_period, + "fieldFormalParameter_thisKeyword": fieldFormalParameter_thisKeyword, + "normalFormalParameter_covariantKeyword": + normalFormalParameter_covariantKeyword, + "normalFormalParameter_isCovariant": normalFormalParameter_isCovariant, + "normalFormalParameter_identifier": normalFormalParameter_identifier, + "codeLength": codeLength, + "codeOffset": codeOffset, + "formalParameter_kind": formalParameter_kind, + "normalFormalParameter_comment": normalFormalParameter_comment, + "isSynthetic": isSynthetic, + "kind": kind, + }; + } + if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) { + return { + "actualType": actualType, + "normalFormalParameter_metadata": normalFormalParameter_metadata, + "functionTypedFormalParameter_formalParameters": + functionTypedFormalParameter_formalParameters, + "functionTypedFormalParameter_returnType": + functionTypedFormalParameter_returnType, + "functionTypedFormalParameter_typeParameters": + functionTypedFormalParameter_typeParameters, + "normalFormalParameter_covariantKeyword": + normalFormalParameter_covariantKeyword, + "normalFormalParameter_isCovariant": normalFormalParameter_isCovariant, + "normalFormalParameter_identifier": normalFormalParameter_identifier, + "codeLength": codeLength, + "codeOffset": codeOffset, + "formalParameter_kind": formalParameter_kind, + "normalFormalParameter_comment": normalFormalParameter_comment, + "isSynthetic": isSynthetic, + "kind": kind, + }; + } + if (kind == idl.LinkedNodeKind.simpleFormalParameter) { + return { + "actualType": actualType, + "normalFormalParameter_metadata": normalFormalParameter_metadata, + "simpleFormalParameter_type": simpleFormalParameter_type, + "simpleFormalParameter_keyword": simpleFormalParameter_keyword, + "normalFormalParameter_covariantKeyword": + normalFormalParameter_covariantKeyword, + "normalFormalParameter_isCovariant": normalFormalParameter_isCovariant, + "normalFormalParameter_identifier": normalFormalParameter_identifier, + "codeLength": codeLength, + "codeOffset": codeOffset, + "formalParameter_kind": formalParameter_kind, + "normalFormalParameter_comment": normalFormalParameter_comment, + "isSynthetic": isSynthetic, + "kind": kind, + }; + } + if (kind == idl.LinkedNodeKind.variableDeclaration) { + return { + "actualType": actualType, + "annotatedNode_comment": annotatedNode_comment, + "annotatedNode_metadata": annotatedNode_metadata, + "variableDeclaration_initializer": variableDeclaration_initializer, + "variableDeclaration_equals": variableDeclaration_equals, + "variableDeclaration_name": variableDeclaration_name, + "codeLength": codeLength, + "codeOffset": codeOffset, + "isSynthetic": isSynthetic, + "kind": kind, + "variableDeclaration_declaration": variableDeclaration_declaration, + }; + } + if (kind == idl.LinkedNodeKind.binaryExpression) { + return { + "binaryExpression_invokeType": binaryExpression_invokeType, + "binaryExpression_leftOperand": binaryExpression_leftOperand, + "binaryExpression_element": binaryExpression_element, + "binaryExpression_rightOperand": binaryExpression_rightOperand, + "binaryExpression_operator": binaryExpression_operator, + "expression_type": expression_type, + "isSynthetic": isSynthetic, + "kind": kind, + }; + } + if (kind == idl.LinkedNodeKind.functionExpressionInvocation) { + return { + "invocationExpression_invokeType": invocationExpression_invokeType, + "functionExpressionInvocation_function": + functionExpressionInvocation_function, + "invocationExpression_typeArguments": + invocationExpression_typeArguments, + "expression_type": expression_type, + "invocationExpression_arguments": invocationExpression_arguments, + "isSynthetic": isSynthetic, + "kind": kind, + }; + } + if (kind == idl.LinkedNodeKind.methodInvocation) { + return { + "invocationExpression_invokeType": invocationExpression_invokeType, + "methodInvocation_methodName": methodInvocation_methodName, + "methodInvocation_operator": methodInvocation_operator, + "methodInvocation_target": methodInvocation_target, + "invocationExpression_typeArguments": + invocationExpression_typeArguments, + "expression_type": expression_type, + "invocationExpression_arguments": invocationExpression_arguments, + "isSynthetic": isSynthetic, + "kind": kind, + }; + } + if (kind == idl.LinkedNodeKind.typeName) { + return { + "typeName_type": typeName_type, + "typeName_name": typeName_name, + "typeName_question": typeName_question, + "typeName_typeArguments": typeName_typeArguments, + "isSynthetic": isSynthetic, + "kind": kind, + }; + } if (kind == idl.LinkedNodeKind.adjacentStrings) { return { "adjacentStrings_strings": adjacentStrings_strings, @@ -17434,6 +17534,7 @@ "namedCompilationUnitMember_name": namedCompilationUnitMember_name, "isSynthetic": isSynthetic, "kind": kind, + "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded, }; } if (kind == idl.LinkedNodeKind.classTypeAlias) { @@ -17453,6 +17554,7 @@ "namedCompilationUnitMember_name": namedCompilationUnitMember_name, "isSynthetic": isSynthetic, "kind": kind, + "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded, }; } if (kind == idl.LinkedNodeKind.declaredIdentifier) { @@ -17487,43 +17589,6 @@ "kind": kind, }; } - if (kind == idl.LinkedNodeKind.functionDeclaration) { - return { - "annotatedNode_comment": annotatedNode_comment, - "annotatedNode_metadata": annotatedNode_metadata, - "functionDeclaration_functionExpression": - functionDeclaration_functionExpression, - "functionDeclaration_externalKeyword": - functionDeclaration_externalKeyword, - "functionDeclaration_returnType": functionDeclaration_returnType, - "functionDeclaration_propertyKeyword": - functionDeclaration_propertyKeyword, - "functionDeclaration_returnType2": functionDeclaration_returnType2, - "codeLength": codeLength, - "codeOffset": codeOffset, - "namedCompilationUnitMember_name": namedCompilationUnitMember_name, - "isSynthetic": isSynthetic, - "kind": kind, - }; - } - if (kind == idl.LinkedNodeKind.functionTypeAlias) { - return { - "annotatedNode_comment": annotatedNode_comment, - "annotatedNode_metadata": annotatedNode_metadata, - "functionTypeAlias_formalParameters": - functionTypeAlias_formalParameters, - "functionTypeAlias_returnType": functionTypeAlias_returnType, - "functionTypeAlias_typeParameters": functionTypeAlias_typeParameters, - "typeAlias_typedefKeyword": typeAlias_typedefKeyword, - "typeAlias_semicolon": typeAlias_semicolon, - "functionTypeAlias_returnType2": functionTypeAlias_returnType2, - "codeLength": codeLength, - "codeOffset": codeOffset, - "namedCompilationUnitMember_name": namedCompilationUnitMember_name, - "isSynthetic": isSynthetic, - "kind": kind, - }; - } if (kind == idl.LinkedNodeKind.genericTypeAlias) { return { "annotatedNode_comment": annotatedNode_comment, @@ -17538,6 +17603,7 @@ "namedCompilationUnitMember_name": namedCompilationUnitMember_name, "isSynthetic": isSynthetic, "kind": kind, + "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded, }; } if (kind == idl.LinkedNodeKind.libraryDirective) { @@ -17551,28 +17617,6 @@ "kind": kind, }; } - if (kind == idl.LinkedNodeKind.methodDeclaration) { - return { - "annotatedNode_comment": annotatedNode_comment, - "annotatedNode_metadata": annotatedNode_metadata, - "methodDeclaration_body": methodDeclaration_body, - "methodDeclaration_externalKeyword": methodDeclaration_externalKeyword, - "methodDeclaration_formalParameters": - methodDeclaration_formalParameters, - "methodDeclaration_returnType": methodDeclaration_returnType, - "methodDeclaration_modifierKeyword": methodDeclaration_modifierKeyword, - "methodDeclaration_operatorKeyword": methodDeclaration_operatorKeyword, - "methodDeclaration_propertyKeyword": methodDeclaration_propertyKeyword, - "methodDeclaration_actualProperty": methodDeclaration_actualProperty, - "methodDeclaration_returnType2": methodDeclaration_returnType2, - "methodDeclaration_typeParameters": methodDeclaration_typeParameters, - "codeLength": codeLength, - "codeOffset": codeOffset, - "methodDeclaration_name": methodDeclaration_name, - "isSynthetic": isSynthetic, - "kind": kind, - }; - } if (kind == idl.LinkedNodeKind.mixinDeclaration) { return { "annotatedNode_comment": annotatedNode_comment, @@ -17593,6 +17637,7 @@ "namedCompilationUnitMember_name": namedCompilationUnitMember_name, "isSynthetic": isSynthetic, "kind": kind, + "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded, }; } if (kind == idl.LinkedNodeKind.partDirective) { @@ -17650,86 +17695,6 @@ "kind": kind, }; } - if (kind == idl.LinkedNodeKind.variableDeclaration) { - return { - "annotatedNode_comment": annotatedNode_comment, - "annotatedNode_metadata": annotatedNode_metadata, - "variableDeclaration_initializer": variableDeclaration_initializer, - "variableDeclaration_equals": variableDeclaration_equals, - "variableDeclaration_name": variableDeclaration_name, - "variableDeclaration_type2": variableDeclaration_type2, - "codeLength": codeLength, - "codeOffset": codeOffset, - "isSynthetic": isSynthetic, - "kind": kind, - "variableDeclaration_declaration": variableDeclaration_declaration, - }; - } - if (kind == idl.LinkedNodeKind.fieldFormalParameter) { - return { - "normalFormalParameter_metadata": normalFormalParameter_metadata, - "fieldFormalParameter_type": fieldFormalParameter_type, - "fieldFormalParameter_keyword": fieldFormalParameter_keyword, - "fieldFormalParameter_typeParameters": - fieldFormalParameter_typeParameters, - "fieldFormalParameter_formalParameters": - fieldFormalParameter_formalParameters, - "fieldFormalParameter_period": fieldFormalParameter_period, - "fieldFormalParameter_thisKeyword": fieldFormalParameter_thisKeyword, - "normalFormalParameter_covariantKeyword": - normalFormalParameter_covariantKeyword, - "fieldFormalParameter_type2": fieldFormalParameter_type2, - "normalFormalParameter_isCovariant": normalFormalParameter_isCovariant, - "normalFormalParameter_identifier": normalFormalParameter_identifier, - "codeLength": codeLength, - "codeOffset": codeOffset, - "formalParameter_kind": formalParameter_kind, - "normalFormalParameter_comment": normalFormalParameter_comment, - "isSynthetic": isSynthetic, - "kind": kind, - }; - } - if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) { - return { - "normalFormalParameter_metadata": normalFormalParameter_metadata, - "functionTypedFormalParameter_formalParameters": - functionTypedFormalParameter_formalParameters, - "functionTypedFormalParameter_returnType": - functionTypedFormalParameter_returnType, - "functionTypedFormalParameter_typeParameters": - functionTypedFormalParameter_typeParameters, - "normalFormalParameter_covariantKeyword": - normalFormalParameter_covariantKeyword, - "functionTypedFormalParameter_type2": - functionTypedFormalParameter_type2, - "normalFormalParameter_isCovariant": normalFormalParameter_isCovariant, - "normalFormalParameter_identifier": normalFormalParameter_identifier, - "codeLength": codeLength, - "codeOffset": codeOffset, - "formalParameter_kind": formalParameter_kind, - "normalFormalParameter_comment": normalFormalParameter_comment, - "isSynthetic": isSynthetic, - "kind": kind, - }; - } - if (kind == idl.LinkedNodeKind.simpleFormalParameter) { - return { - "normalFormalParameter_metadata": normalFormalParameter_metadata, - "simpleFormalParameter_type": simpleFormalParameter_type, - "simpleFormalParameter_keyword": simpleFormalParameter_keyword, - "normalFormalParameter_covariantKeyword": - normalFormalParameter_covariantKeyword, - "simpleFormalParameter_type2": simpleFormalParameter_type2, - "normalFormalParameter_isCovariant": normalFormalParameter_isCovariant, - "normalFormalParameter_identifier": normalFormalParameter_identifier, - "codeLength": codeLength, - "codeOffset": codeOffset, - "formalParameter_kind": formalParameter_kind, - "normalFormalParameter_comment": normalFormalParameter_comment, - "isSynthetic": isSynthetic, - "kind": kind, - }; - } if (kind == idl.LinkedNodeKind.switchCase) { return { "switchMember_statements": switchMember_statements, @@ -17819,18 +17784,6 @@ "kind": kind, }; } - if (kind == idl.LinkedNodeKind.binaryExpression) { - return { - "binaryExpression_leftOperand": binaryExpression_leftOperand, - "binaryExpression_element": binaryExpression_element, - "binaryExpression_rightOperand": binaryExpression_rightOperand, - "binaryExpression_operator": binaryExpression_operator, - "binaryExpression_invokeType": binaryExpression_invokeType, - "expression_type": expression_type, - "isSynthetic": isSynthetic, - "kind": kind, - }; - } if (kind == idl.LinkedNodeKind.blockFunctionBody) { return { "blockFunctionBody_block": blockFunctionBody_block, @@ -18054,46 +18007,6 @@ "kind": kind, }; } - if (kind == idl.LinkedNodeKind.functionExpression) { - return { - "functionExpression_body": functionExpression_body, - "functionExpression_formalParameters": - functionExpression_formalParameters, - "functionExpression_typeParameters": functionExpression_typeParameters, - "functionDeclaration_returnType2": functionDeclaration_returnType2, - "isSynthetic": isSynthetic, - "kind": kind, - }; - } - if (kind == idl.LinkedNodeKind.functionExpressionInvocation) { - return { - "functionExpressionInvocation_function": - functionExpressionInvocation_function, - "invocationExpression_invokeType": invocationExpression_invokeType, - "invocationExpression_typeArguments": - invocationExpression_typeArguments, - "expression_type": expression_type, - "invocationExpression_arguments": invocationExpression_arguments, - "isSynthetic": isSynthetic, - "kind": kind, - }; - } - if (kind == idl.LinkedNodeKind.genericFunctionType) { - return { - "genericFunctionType_typeParameters": - genericFunctionType_typeParameters, - "genericFunctionType_functionKeyword": - genericFunctionType_functionKeyword, - "genericFunctionType_returnType": genericFunctionType_returnType, - "genericFunctionType_formalParameters": - genericFunctionType_formalParameters, - "genericFunctionType_question": genericFunctionType_question, - "genericFunctionType_returnType2": genericFunctionType_returnType2, - "genericFunctionType_type": genericFunctionType_type, - "isSynthetic": isSynthetic, - "kind": kind, - }; - } if (kind == idl.LinkedNodeKind.ifElement) { return { "ifMixin_condition": ifMixin_condition, @@ -18188,20 +18101,6 @@ "kind": kind, }; } - if (kind == idl.LinkedNodeKind.methodInvocation) { - return { - "methodInvocation_methodName": methodInvocation_methodName, - "methodInvocation_operator": methodInvocation_operator, - "methodInvocation_target": methodInvocation_target, - "invocationExpression_invokeType": invocationExpression_invokeType, - "invocationExpression_typeArguments": - invocationExpression_typeArguments, - "expression_type": expression_type, - "invocationExpression_arguments": invocationExpression_arguments, - "isSynthetic": isSynthetic, - "kind": kind, - }; - } if (kind == idl.LinkedNodeKind.namedExpression) { return { "namedExpression_expression": namedExpression_expression, @@ -18338,16 +18237,6 @@ "kind": kind, }; } - if (kind == idl.LinkedNodeKind.typeName) { - return { - "typeName_name": typeName_name, - "typeName_question": typeName_question, - "typeName_typeArguments": typeName_typeArguments, - "typeName_type": typeName_type, - "isSynthetic": isSynthetic, - "kind": kind, - }; - } if (kind == idl.LinkedNodeKind.variableDeclarationStatement) { return { "variableDeclarationStatement_variables": @@ -18519,7 +18408,7 @@ List<LinkedNodeLibraryBuilder> get libraries => _libraries ??= <LinkedNodeLibraryBuilder>[]; - void set libraries(List<LinkedNodeLibraryBuilder> value) { + set libraries(List<LinkedNodeLibraryBuilder> value) { this._libraries = value; } @@ -18527,7 +18416,7 @@ LinkedNodeReferencesBuilder get references => _references; /// The shared list of references used in the [libraries]. - void set references(LinkedNodeReferencesBuilder value) { + set references(LinkedNodeReferencesBuilder value) { this._references = value; } @@ -18537,17 +18426,13 @@ : _libraries = libraries, _references = references; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _libraries?.forEach((b) => b.flushInformative()); _references?.flushInformative(); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addBool(this._references != null); this._references?.collectApiSignature(signature); @@ -18661,7 +18546,7 @@ @override List<int> get exports => _exports ??= <int>[]; - void set exports(List<int> value) { + set exports(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._exports = value; } @@ -18669,14 +18554,14 @@ @override String get name => _name ??= ''; - void set name(String value) { + set name(String value) { this._name = value; } @override int get nameLength => _nameLength ??= 0; - void set nameLength(int value) { + set nameLength(int value) { assert(value == null || value >= 0); this._nameLength = value; } @@ -18684,7 +18569,7 @@ @override int get nameOffset => _nameOffset ??= 0; - void set nameOffset(int value) { + set nameOffset(int value) { assert(value == null || value >= 0); this._nameOffset = value; } @@ -18692,14 +18577,14 @@ @override List<LinkedNodeUnitBuilder> get units => _units ??= <LinkedNodeUnitBuilder>[]; - void set units(List<LinkedNodeUnitBuilder> value) { + set units(List<LinkedNodeUnitBuilder> value) { this._units = value; } @override String get uriStr => _uriStr ??= ''; - void set uriStr(String value) { + set uriStr(String value) { this._uriStr = value; } @@ -18717,16 +18602,12 @@ _units = units, _uriStr = uriStr; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _units?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._uriStr ?? ''); if (this._units == null) { @@ -18891,14 +18772,14 @@ @override List<String> get name => _name ??= <String>[]; - void set name(List<String> value) { + set name(List<String> value) { this._name = value; } @override List<int> get parent => _parent ??= <int>[]; - void set parent(List<int> value) { + set parent(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._parent = value; } @@ -18907,14 +18788,10 @@ : _name = name, _parent = parent; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() {} - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._parent == null) { signature.addInt(0); @@ -19026,7 +18903,7 @@ List<LinkedNodeTypeFormalParameterBuilder> get functionFormalParameters => _functionFormalParameters ??= <LinkedNodeTypeFormalParameterBuilder>[]; - void set functionFormalParameters( + set functionFormalParameters( List<LinkedNodeTypeFormalParameterBuilder> value) { this._functionFormalParameters = value; } @@ -19034,7 +18911,7 @@ @override LinkedNodeTypeBuilder get functionReturnType => _functionReturnType; - void set functionReturnType(LinkedNodeTypeBuilder value) { + set functionReturnType(LinkedNodeTypeBuilder value) { this._functionReturnType = value; } @@ -19042,7 +18919,7 @@ List<int> get functionTypeParameters => _functionTypeParameters ??= <int>[]; /// References to [LinkedNodeReferences]. - void set functionTypeParameters(List<int> value) { + set functionTypeParameters(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._functionTypeParameters = value; } @@ -19050,7 +18927,7 @@ @override int get genericTypeAliasReference => _genericTypeAliasReference ??= 0; - void set genericTypeAliasReference(int value) { + set genericTypeAliasReference(int value) { assert(value == null || value >= 0); this._genericTypeAliasReference = value; } @@ -19059,7 +18936,7 @@ List<LinkedNodeTypeBuilder> get genericTypeAliasTypeArguments => _genericTypeAliasTypeArguments ??= <LinkedNodeTypeBuilder>[]; - void set genericTypeAliasTypeArguments(List<LinkedNodeTypeBuilder> value) { + set genericTypeAliasTypeArguments(List<LinkedNodeTypeBuilder> value) { this._genericTypeAliasTypeArguments = value; } @@ -19067,7 +18944,7 @@ int get interfaceClass => _interfaceClass ??= 0; /// Reference to a [LinkedNodeReferences]. - void set interfaceClass(int value) { + set interfaceClass(int value) { assert(value == null || value >= 0); this._interfaceClass = value; } @@ -19076,14 +18953,14 @@ List<LinkedNodeTypeBuilder> get interfaceTypeArguments => _interfaceTypeArguments ??= <LinkedNodeTypeBuilder>[]; - void set interfaceTypeArguments(List<LinkedNodeTypeBuilder> value) { + set interfaceTypeArguments(List<LinkedNodeTypeBuilder> value) { this._interfaceTypeArguments = value; } @override idl.LinkedNodeTypeKind get kind => _kind ??= idl.LinkedNodeTypeKind.bottom; - void set kind(idl.LinkedNodeTypeKind value) { + set kind(idl.LinkedNodeTypeKind value) { this._kind = value; } @@ -19091,7 +18968,7 @@ int get typeParameterParameter => _typeParameterParameter ??= 0; /// Reference to a [LinkedNodeReferences]. - void set typeParameterParameter(int value) { + set typeParameterParameter(int value) { assert(value == null || value >= 0); this._typeParameterParameter = value; } @@ -19116,9 +18993,7 @@ _kind = kind, _typeParameterParameter = typeParameterParameter; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _functionFormalParameters?.forEach((b) => b.flushInformative()); _functionReturnType?.flushInformative(); @@ -19126,9 +19001,7 @@ _interfaceTypeArguments?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._functionFormalParameters == null) { signature.addInt(0); @@ -19381,21 +19254,21 @@ idl.LinkedNodeFormalParameterKind get kind => _kind ??= idl.LinkedNodeFormalParameterKind.required; - void set kind(idl.LinkedNodeFormalParameterKind value) { + set kind(idl.LinkedNodeFormalParameterKind value) { this._kind = value; } @override String get name => _name ??= ''; - void set name(String value) { + set name(String value) { this._name = value; } @override LinkedNodeTypeBuilder get type => _type; - void set type(LinkedNodeTypeBuilder value) { + set type(LinkedNodeTypeBuilder value) { this._type = value; } @@ -19407,16 +19280,12 @@ _name = name, _type = type; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _type?.flushInformative(); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addInt(this._kind == null ? 0 : this._kind.index); signature.addString(this._name ?? ''); @@ -19522,21 +19391,21 @@ @override LinkedNodeBuilder get node => _node; - void set node(LinkedNodeBuilder value) { + set node(LinkedNodeBuilder value) { this._node = value; } @override UnlinkedTokensBuilder get tokens => _tokens; - void set tokens(UnlinkedTokensBuilder value) { + set tokens(UnlinkedTokensBuilder value) { this._tokens = value; } @override String get uriStr => _uriStr ??= ''; - void set uriStr(String value) { + set uriStr(String value) { this._uriStr = value; } @@ -19546,17 +19415,13 @@ _tokens = tokens, _uriStr = uriStr; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _node?.flushInformative(); _tokens?.flushInformative(); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._uriStr ?? ''); signature.addBool(this._tokens != null); @@ -19665,35 +19530,35 @@ @override LinkedNodeBuilder get comment => _comment; - void set comment(LinkedNodeBuilder value) { + set comment(LinkedNodeBuilder value) { this._comment = value; } @override bool get isConst => _isConst ??= false; - void set isConst(bool value) { + set isConst(bool value) { this._isConst = value; } @override bool get isCovariant => _isCovariant ??= false; - void set isCovariant(bool value) { + set isCovariant(bool value) { this._isCovariant = value; } @override bool get isFinal => _isFinal ??= false; - void set isFinal(bool value) { + set isFinal(bool value) { this._isFinal = value; } @override bool get isStatic => _isStatic ??= false; - void set isStatic(bool value) { + set isStatic(bool value) { this._isStatic = value; } @@ -19709,16 +19574,12 @@ _isFinal = isFinal, _isStatic = isStatic; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _comment?.flushInformative(); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addBool(this._comment != null); this._comment?.collectApiSignature(signature); @@ -19856,7 +19717,7 @@ /// Containing references must always point backward; that is, for all i, if /// LinkedUnit.references[i].containingReference != 0, then /// LinkedUnit.references[i].containingReference < i. - void set containingReference(int value) { + set containingReference(int value) { assert(value == null || value >= 0); this._containingReference = value; } @@ -19869,7 +19730,7 @@ /// /// Zero if this entity is contained within another entity (e.g. a class /// member), or if [kind] is [ReferenceKind.prefix]. - void set dependency(int value) { + set dependency(int value) { assert(value == null || value >= 0); this._dependency = value; } @@ -19879,7 +19740,7 @@ /// The kind of the entity being referred to. For the pseudo-types `dynamic` /// and `void`, the kind is [ReferenceKind.classOrEnum]. - void set kind(idl.ReferenceKind value) { + set kind(idl.ReferenceKind value) { this._kind = value; } @@ -19893,7 +19754,7 @@ /// If this [LinkedReference] doesn't have an associated [UnlinkedReference], /// name of the entity being referred to. For the pseudo-type `dynamic`, the /// string is "dynamic". For the pseudo-type `void`, the string is "void". - void set name(String value) { + set name(String value) { this._name = value; } @@ -19903,7 +19764,7 @@ /// If the entity being referred to is generic, the number of type parameters /// it declares (does not include type parameters of enclosing entities). /// Otherwise zero. - void set numTypeParameters(int value) { + set numTypeParameters(int value) { assert(value == null || value >= 0); this._numTypeParameters = value; } @@ -19918,7 +19779,7 @@ /// /// Zero if this entity is contained within another entity (e.g. a class /// member). - void set unit(int value) { + set unit(int value) { assert(value == null || value >= 0); this._unit = value; } @@ -19937,14 +19798,10 @@ _numTypeParameters = numTypeParameters, _unit = unit; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() {} - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addInt(this._unit ?? 0); signature.addInt(this._dependency ?? 0); @@ -20094,7 +19951,7 @@ /// List of slot ids (referring to [UnlinkedExecutable.constCycleSlot]) /// corresponding to const constructors that are part of cycles. - void set constCycles(List<int> value) { + set constCycles(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._constCycles = value; } @@ -20105,7 +19962,7 @@ /// List of slot ids (referring to [UnlinkedClass.notSimplyBoundedSlot] or /// [UnlinkedTypedef.notSimplyBoundedSlot]) corresponding to classes and /// typedefs that are not simply bounded. - void set notSimplyBounded(List<int> value) { + set notSimplyBounded(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._notSimplyBounded = value; } @@ -20117,7 +19974,7 @@ /// List of slot ids (referring to [UnlinkedParam.inheritsCovariantSlot] or /// [UnlinkedVariable.inheritsCovariantSlot]) corresponding to parameters /// that inherit `@covariant` behavior from a base class. - void set parametersInheritingCovariant(List<int> value) { + set parametersInheritingCovariant(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._parametersInheritingCovariant = value; } @@ -20132,7 +19989,7 @@ /// elements beyond the number of elements in [UnlinkedUnit.references], those /// additional elements are references that are only referred to implicitly /// (e.g. elements involved in inferred or propagated types). - void set references(List<LinkedReferenceBuilder> value) { + set references(List<LinkedReferenceBuilder> value) { this._references = value; } @@ -20141,7 +19998,7 @@ _topLevelInferenceErrors ??= <TopLevelInferenceErrorBuilder>[]; /// The list of type inference errors. - void set topLevelInferenceErrors(List<TopLevelInferenceErrorBuilder> value) { + set topLevelInferenceErrors(List<TopLevelInferenceErrorBuilder> value) { this._topLevelInferenceErrors = value; } @@ -20150,7 +20007,7 @@ /// List associating slot ids found inside the unlinked summary for the /// compilation unit with propagated and inferred types. - void set types(List<EntityRefBuilder> value) { + set types(List<EntityRefBuilder> value) { this._types = value; } @@ -20168,18 +20025,14 @@ _topLevelInferenceErrors = topLevelInferenceErrors, _types = types; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _references?.forEach((b) => b.flushInformative()); _topLevelInferenceErrors?.forEach((b) => b.flushInformative()); _types?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._references == null) { signature.addInt(0); @@ -20411,7 +20264,7 @@ _linkedLibraries ??= <LinkedLibraryBuilder>[]; /// Linked libraries. - void set linkedLibraries(List<LinkedLibraryBuilder> value) { + set linkedLibraries(List<LinkedLibraryBuilder> value) { this._linkedLibraries = value; } @@ -20420,7 +20273,7 @@ /// The list of URIs of items in [linkedLibraries], e.g. `dart:core` or /// `package:foo/bar.dart`. - void set linkedLibraryUris(List<String> value) { + set linkedLibraryUris(List<String> value) { this._linkedLibraryUris = value; } @@ -20429,7 +20282,7 @@ /// Major version of the summary format. See /// [PackageBundleAssembler.currentMajorVersion]. - void set majorVersion(int value) { + set majorVersion(int value) { assert(value == null || value >= 0); this._majorVersion = value; } @@ -20439,7 +20292,7 @@ /// Minor version of the summary format. See /// [PackageBundleAssembler.currentMinorVersion]. - void set minorVersion(int value) { + set minorVersion(int value) { assert(value == null || value >= 0); this._minorVersion = value; } @@ -20453,7 +20306,7 @@ _unlinkedUnits ??= <UnlinkedUnitBuilder>[]; /// Unlinked information for the compilation units constituting the package. - void set unlinkedUnits(List<UnlinkedUnitBuilder> value) { + set unlinkedUnits(List<UnlinkedUnitBuilder> value) { this._unlinkedUnits = value; } @@ -20461,7 +20314,7 @@ List<String> get unlinkedUnitUris => _unlinkedUnitUris ??= <String>[]; /// The list of URIs of items in [unlinkedUnits], e.g. `dart:core/bool.dart`. - void set unlinkedUnitUris(List<String> value) { + set unlinkedUnitUris(List<String> value) { this._unlinkedUnitUris = value; } @@ -20479,17 +20332,13 @@ _unlinkedUnits = unlinkedUnits, _unlinkedUnitUris = unlinkedUnitUris; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _linkedLibraries?.forEach((b) => b.flushInformative()); _unlinkedUnits?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._linkedLibraries == null) { signature.addInt(0); @@ -20711,7 +20560,7 @@ /// Each item of this list corresponds to a unique referenced element. It is /// the kind of the synthetic element. - void set elementKinds(List<idl.IndexSyntheticElementKind> value) { + set elementKinds(List<idl.IndexSyntheticElementKind> value) { this._elementKinds = value; } @@ -20724,7 +20573,7 @@ /// is a top-level element. The list is sorted in ascending order, so that /// the client can quickly check whether an element is referenced in this /// [PackageIndex]. - void set elementNameClassMemberIds(List<int> value) { + set elementNameClassMemberIds(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._elementNameClassMemberIds = value; } @@ -20737,7 +20586,7 @@ /// not a named parameter. The list is sorted in ascending order, so that the /// client can quickly check whether an element is referenced in this /// [PackageIndex]. - void set elementNameParameterIds(List<int> value) { + set elementNameParameterIds(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._elementNameParameterIds = value; } @@ -20750,7 +20599,7 @@ /// the identifier of the top-level element name, or `null` if the element is /// the unit. The list is sorted in ascending order, so that the client can /// quickly check whether an element is referenced in this [PackageIndex]. - void set elementNameUnitMemberIds(List<int> value) { + set elementNameUnitMemberIds(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._elementNameUnitMemberIds = value; } @@ -20761,7 +20610,7 @@ /// Each item of this list corresponds to a unique referenced element. It is /// the index into [unitLibraryUris] and [unitUnitUris] for the library /// specific unit where the element is declared. - void set elementUnits(List<int> value) { + set elementUnits(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._elementUnits = value; } @@ -20772,7 +20621,7 @@ /// List of unique element strings used in this [PackageIndex]. The list is /// sorted in ascending order, so that the client can quickly check the /// presence of a string in this [PackageIndex]. - void set strings(List<String> value) { + set strings(List<String> value) { this._strings = value; } @@ -20782,7 +20631,7 @@ /// Each item of this list corresponds to the library URI of a unique library /// specific unit referenced in the [PackageIndex]. It is an index into /// [strings] list. - void set unitLibraryUris(List<int> value) { + set unitLibraryUris(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._unitLibraryUris = value; } @@ -20791,7 +20640,7 @@ List<UnitIndexBuilder> get units => _units ??= <UnitIndexBuilder>[]; /// List of indexes of each unit in this [PackageIndex]. - void set units(List<UnitIndexBuilder> value) { + set units(List<UnitIndexBuilder> value) { this._units = value; } @@ -20801,7 +20650,7 @@ /// Each item of this list corresponds to the unit URI of a unique library /// specific unit referenced in the [PackageIndex]. It is an index into /// [strings] list. - void set unitUnitUris(List<int> value) { + set unitUnitUris(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._unitUnitUris = value; } @@ -20826,16 +20675,12 @@ _units = units, _unitUnitUris = unitUnitUris; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _units?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._elementUnits == null) { signature.addInt(0); @@ -21142,7 +20987,7 @@ List<String> get arguments => _arguments ??= <String>[]; /// The [kind] specific arguments. - void set arguments(List<String> value) { + set arguments(List<String> value) { this._arguments = value; } @@ -21151,7 +20996,7 @@ _kind ??= idl.TopLevelInferenceErrorKind.assignment; /// The kind of the error. - void set kind(idl.TopLevelInferenceErrorKind value) { + set kind(idl.TopLevelInferenceErrorKind value) { this._kind = value; } @@ -21161,7 +21006,7 @@ /// The slot id (which is unique within the compilation unit) identifying the /// target of type inference with which this [TopLevelInferenceError] is /// associated. - void set slot(int value) { + set slot(int value) { assert(value == null || value >= 0); this._slot = value; } @@ -21172,14 +21017,10 @@ _kind = kind, _slot = slot; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() {} - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addInt(this._slot ?? 0); signature.addInt(this._kind == null ? 0 : this._kind.index); @@ -21300,7 +21141,7 @@ _definedNameKinds ??= <idl.IndexNameKind>[]; /// Each item of this list is the kind of an element defined in this unit. - void set definedNameKinds(List<idl.IndexNameKind> value) { + set definedNameKinds(List<idl.IndexNameKind> value) { this._definedNameKinds = value; } @@ -21309,7 +21150,7 @@ /// Each item of this list is the name offset of an element defined in this /// unit relative to the beginning of the file. - void set definedNameOffsets(List<int> value) { + set definedNameOffsets(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._definedNameOffsets = value; } @@ -21321,7 +21162,7 @@ /// is an index into [PackageIndex.strings] list. The list is sorted in /// ascending order, so that the client can quickly find name definitions in /// this [UnitIndex]. - void set definedNames(List<int> value) { + set definedNames(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._definedNames = value; } @@ -21331,7 +21172,7 @@ /// Index into [PackageIndex.unitLibraryUris] and [PackageIndex.unitUnitUris] /// for the library specific unit that corresponds to this [UnitIndex]. - void set unit(int value) { + set unit(int value) { assert(value == null || value >= 0); this._unit = value; } @@ -21342,7 +21183,7 @@ /// Each item of this list is the `true` if the corresponding element usage /// is qualified with some prefix. - void set usedElementIsQualifiedFlags(List<bool> value) { + set usedElementIsQualifiedFlags(List<bool> value) { this._usedElementIsQualifiedFlags = value; } @@ -21351,7 +21192,7 @@ _usedElementKinds ??= <idl.IndexRelationKind>[]; /// Each item of this list is the kind of the element usage. - void set usedElementKinds(List<idl.IndexRelationKind> value) { + set usedElementKinds(List<idl.IndexRelationKind> value) { this._usedElementKinds = value; } @@ -21359,7 +21200,7 @@ List<int> get usedElementLengths => _usedElementLengths ??= <int>[]; /// Each item of this list is the length of the element usage. - void set usedElementLengths(List<int> value) { + set usedElementLengths(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._usedElementLengths = value; } @@ -21369,7 +21210,7 @@ /// Each item of this list is the offset of the element usage relative to the /// beginning of the file. - void set usedElementOffsets(List<int> value) { + set usedElementOffsets(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._usedElementOffsets = value; } @@ -21380,7 +21221,7 @@ /// Each item of this list is the index into [PackageIndex.elementUnits] and /// [PackageIndex.elementOffsets]. The list is sorted in ascending order, so /// that the client can quickly find element references in this [UnitIndex]. - void set usedElements(List<int> value) { + set usedElements(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._usedElements = value; } @@ -21391,7 +21232,7 @@ /// Each item of this list is the `true` if the corresponding name usage /// is qualified with some prefix. - void set usedNameIsQualifiedFlags(List<bool> value) { + set usedNameIsQualifiedFlags(List<bool> value) { this._usedNameIsQualifiedFlags = value; } @@ -21400,7 +21241,7 @@ _usedNameKinds ??= <idl.IndexRelationKind>[]; /// Each item of this list is the kind of the name usage. - void set usedNameKinds(List<idl.IndexRelationKind> value) { + set usedNameKinds(List<idl.IndexRelationKind> value) { this._usedNameKinds = value; } @@ -21409,7 +21250,7 @@ /// Each item of this list is the offset of the name usage relative to the /// beginning of the file. - void set usedNameOffsets(List<int> value) { + set usedNameOffsets(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._usedNameOffsets = value; } @@ -21420,7 +21261,7 @@ /// Each item of this list is the index into [PackageIndex.strings] for a /// used name. The list is sorted in ascending order, so that the client can /// quickly find name uses in this [UnitIndex]. - void set usedNames(List<int> value) { + set usedNames(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._usedNames = value; } @@ -21453,14 +21294,10 @@ _usedNameOffsets = usedNameOffsets, _usedNames = usedNames; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() {} - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addInt(this._unit ?? 0); if (this._usedElementLengths == null) { @@ -21870,7 +21707,7 @@ _annotations ??= <UnlinkedExprBuilder>[]; /// Annotations for this class. - void set annotations(List<UnlinkedExprBuilder> value) { + set annotations(List<UnlinkedExprBuilder> value) { this._annotations = value; } @@ -21878,7 +21715,7 @@ CodeRangeBuilder get codeRange => _codeRange; /// Code range of the class. - void set codeRange(CodeRangeBuilder value) { + set codeRange(CodeRangeBuilder value) { this._codeRange = value; } @@ -21888,7 +21725,7 @@ /// Documentation comment for the class, or `null` if there is no /// documentation comment. - void set documentationComment(UnlinkedDocumentationCommentBuilder value) { + set documentationComment(UnlinkedDocumentationCommentBuilder value) { this._documentationComment = value; } @@ -21897,7 +21734,7 @@ _executables ??= <UnlinkedExecutableBuilder>[]; /// Executable objects (methods, getters, and setters) contained in the class. - void set executables(List<UnlinkedExecutableBuilder> value) { + set executables(List<UnlinkedExecutableBuilder> value) { this._executables = value; } @@ -21906,7 +21743,7 @@ _fields ??= <UnlinkedVariableBuilder>[]; /// Field declarations contained in the class. - void set fields(List<UnlinkedVariableBuilder> value) { + set fields(List<UnlinkedVariableBuilder> value) { this._fields = value; } @@ -21915,7 +21752,7 @@ /// Indicates whether this class is the core "Object" class (and hence has no /// supertype) - void set hasNoSupertype(bool value) { + set hasNoSupertype(bool value) { this._hasNoSupertype = value; } @@ -21923,7 +21760,7 @@ List<EntityRefBuilder> get interfaces => _interfaces ??= <EntityRefBuilder>[]; /// Interfaces appearing in an `implements` clause, if any. - void set interfaces(List<EntityRefBuilder> value) { + set interfaces(List<EntityRefBuilder> value) { this._interfaces = value; } @@ -21931,7 +21768,7 @@ bool get isAbstract => _isAbstract ??= false; /// Indicates whether the class is declared with the `abstract` keyword. - void set isAbstract(bool value) { + set isAbstract(bool value) { this._isAbstract = value; } @@ -21939,7 +21776,7 @@ bool get isMixinApplication => _isMixinApplication ??= false; /// Indicates whether the class is declared using mixin application syntax. - void set isMixinApplication(bool value) { + set isMixinApplication(bool value) { this._isMixinApplication = value; } @@ -21947,7 +21784,7 @@ List<EntityRefBuilder> get mixins => _mixins ??= <EntityRefBuilder>[]; /// Mixins appearing in a `with` clause, if any. - void set mixins(List<EntityRefBuilder> value) { + set mixins(List<EntityRefBuilder> value) { this._mixins = value; } @@ -21955,7 +21792,7 @@ String get name => _name ??= ''; /// Name of the class. - void set name(String value) { + set name(String value) { this._name = value; } @@ -21963,7 +21800,7 @@ int get nameOffset => _nameOffset ??= 0; /// Offset of the class name relative to the beginning of the file. - void set nameOffset(int value) { + set nameOffset(int value) { assert(value == null || value >= 0); this._nameOffset = value; } @@ -21978,7 +21815,7 @@ /// type when specifying the bound of a type parameter. /// /// Otherwise, zero. - void set notSimplyBoundedSlot(int value) { + set notSimplyBoundedSlot(int value) { assert(value == null || value >= 0); this._notSimplyBoundedSlot = value; } @@ -21990,7 +21827,7 @@ /// Superclass constraints for this mixin declaration. The list will be empty /// if this class is not a mixin declaration, or if the declaration does not /// have an `on` clause (in which case the type `Object` is implied). - void set superclassConstraints(List<EntityRefBuilder> value) { + set superclassConstraints(List<EntityRefBuilder> value) { this._superclassConstraints = value; } @@ -22000,7 +21837,7 @@ /// Names of methods, getters, setters, and operators that this mixin /// declaration super-invokes. For setters this includes the trailing "=". /// The list will be empty if this class is not a mixin declaration. - void set superInvokedNames(List<String> value) { + set superInvokedNames(List<String> value) { this._superInvokedNames = value; } @@ -22010,7 +21847,7 @@ /// Supertype of the class, or `null` if either (a) the class doesn't /// explicitly declare a supertype (and hence has supertype `Object`), or (b) /// the class *is* `Object` (and hence has no supertype). - void set supertype(EntityRefBuilder value) { + set supertype(EntityRefBuilder value) { this._supertype = value; } @@ -22019,7 +21856,7 @@ _typeParameters ??= <UnlinkedTypeParamBuilder>[]; /// Type parameters of the class, if any. - void set typeParameters(List<UnlinkedTypeParamBuilder> value) { + set typeParameters(List<UnlinkedTypeParamBuilder> value) { this._typeParameters = value; } @@ -22059,9 +21896,7 @@ _supertype = supertype, _typeParameters = typeParameters; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _annotations?.forEach((b) => b.flushInformative()); _codeRange = null; @@ -22076,9 +21911,7 @@ _typeParameters?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._name ?? ''); if (this._executables == null) { @@ -22498,7 +22331,7 @@ /// If this is a `show` combinator, offset of the end of the list of shown /// names. Otherwise zero. - void set end(int value) { + set end(int value) { assert(value == null || value >= 0); this._end = value; } @@ -22507,7 +22340,7 @@ List<String> get hides => _hides ??= <String>[]; /// List of names which are hidden. Empty if this is a `show` combinator. - void set hides(List<String> value) { + set hides(List<String> value) { this._hides = value; } @@ -22516,7 +22349,7 @@ /// If this is a `show` combinator, offset of the `show` keyword. Otherwise /// zero. - void set offset(int value) { + set offset(int value) { assert(value == null || value >= 0); this._offset = value; } @@ -22525,7 +22358,7 @@ List<String> get shows => _shows ??= <String>[]; /// List of names which are shown. Empty if this is a `hide` combinator. - void set shows(List<String> value) { + set shows(List<String> value) { this._shows = value; } @@ -22536,17 +22369,13 @@ _offset = offset, _shows = shows; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _end = null; _offset = null; } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._shows == null) { signature.addInt(0); @@ -22678,7 +22507,7 @@ /// The name of the declared variable whose value is being used in the /// condition. - void set name(String value) { + set name(String value) { this._name = value; } @@ -22686,7 +22515,7 @@ String get uri => _uri ??= ''; /// The URI of the implementation library to be used if the condition is true. - void set uri(String value) { + set uri(String value) { this._uri = value; } @@ -22695,7 +22524,7 @@ /// The value to which the value of the declared variable will be compared, /// or `true` if the condition does not include an equality test. - void set value(String value) { + set value(String value) { this._value = value; } @@ -22704,14 +22533,10 @@ _uri = uri, _value = value; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() {} - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._name ?? ''); signature.addString(this._value ?? ''); @@ -22822,7 +22647,7 @@ /// If there are `m` [arguments] and `n` [argumentNames], then each argument /// from [arguments] with index `i` such that `n + i - m >= 0`, should be used /// with the name at `n + i - m`. - void set argumentNames(List<String> value) { + set argumentNames(List<String> value) { this._argumentNames = value; } @@ -22832,7 +22657,7 @@ /// If [kind] is `thisInvocation` or `superInvocation`, the arguments of the /// invocation. Otherwise empty. - void set arguments(List<UnlinkedExprBuilder> value) { + set arguments(List<UnlinkedExprBuilder> value) { this._arguments = value; } @@ -22841,7 +22666,7 @@ /// If [kind] is `field`, the expression of the field initializer. /// Otherwise `null`. - void set expression(UnlinkedExprBuilder value) { + set expression(UnlinkedExprBuilder value) { this._expression = value; } @@ -22850,7 +22675,7 @@ _kind ??= idl.UnlinkedConstructorInitializerKind.field; /// The kind of the constructor initializer (field, redirect, super). - void set kind(idl.UnlinkedConstructorInitializerKind value) { + set kind(idl.UnlinkedConstructorInitializerKind value) { this._kind = value; } @@ -22861,7 +22686,7 @@ /// [kind] is `thisInvocation`, the name of the constructor, declared in this /// class, to redirect to. If [kind] is `superInvocation`, the name of the /// constructor, declared in the superclass, to invoke. - void set name(String value) { + set name(String value) { this._name = value; } @@ -22877,17 +22702,13 @@ _kind = kind, _name = name; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _arguments?.forEach((b) => b.flushInformative()); _expression?.flushInformative(); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._name ?? ''); signature.addBool(this._expression != null); @@ -23060,20 +22881,16 @@ /// /// References appearing within the doc comment in square brackets are not /// specially encoded. - void set text(String value) { + set text(String value) { this._text = value; } UnlinkedDocumentationCommentBuilder({String text}) : _text = text; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() {} - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._text ?? ''); } @@ -23159,7 +22976,7 @@ _annotations ??= <UnlinkedExprBuilder>[]; /// Annotations for this enum. - void set annotations(List<UnlinkedExprBuilder> value) { + set annotations(List<UnlinkedExprBuilder> value) { this._annotations = value; } @@ -23167,7 +22984,7 @@ CodeRangeBuilder get codeRange => _codeRange; /// Code range of the enum. - void set codeRange(CodeRangeBuilder value) { + set codeRange(CodeRangeBuilder value) { this._codeRange = value; } @@ -23177,7 +22994,7 @@ /// Documentation comment for the enum, or `null` if there is no documentation /// comment. - void set documentationComment(UnlinkedDocumentationCommentBuilder value) { + set documentationComment(UnlinkedDocumentationCommentBuilder value) { this._documentationComment = value; } @@ -23185,7 +23002,7 @@ String get name => _name ??= ''; /// Name of the enum type. - void set name(String value) { + set name(String value) { this._name = value; } @@ -23193,7 +23010,7 @@ int get nameOffset => _nameOffset ??= 0; /// Offset of the enum name relative to the beginning of the file. - void set nameOffset(int value) { + set nameOffset(int value) { assert(value == null || value >= 0); this._nameOffset = value; } @@ -23203,7 +23020,7 @@ _values ??= <UnlinkedEnumValueBuilder>[]; /// Values listed in the enum declaration, in declaration order. - void set values(List<UnlinkedEnumValueBuilder> value) { + set values(List<UnlinkedEnumValueBuilder> value) { this._values = value; } @@ -23221,9 +23038,7 @@ _nameOffset = nameOffset, _values = values; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _annotations?.forEach((b) => b.flushInformative()); _codeRange = null; @@ -23232,9 +23047,7 @@ _values?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._name ?? ''); if (this._values == null) { @@ -23410,7 +23223,7 @@ _annotations ??= <UnlinkedExprBuilder>[]; /// Annotations for this value. - void set annotations(List<UnlinkedExprBuilder> value) { + set annotations(List<UnlinkedExprBuilder> value) { this._annotations = value; } @@ -23420,7 +23233,7 @@ /// Documentation comment for the enum value, or `null` if there is no /// documentation comment. - void set documentationComment(UnlinkedDocumentationCommentBuilder value) { + set documentationComment(UnlinkedDocumentationCommentBuilder value) { this._documentationComment = value; } @@ -23428,7 +23241,7 @@ String get name => _name ??= ''; /// Name of the enumerated value. - void set name(String value) { + set name(String value) { this._name = value; } @@ -23436,7 +23249,7 @@ int get nameOffset => _nameOffset ??= 0; /// Offset of the enum value name relative to the beginning of the file. - void set nameOffset(int value) { + set nameOffset(int value) { assert(value == null || value >= 0); this._nameOffset = value; } @@ -23451,18 +23264,14 @@ _name = name, _nameOffset = nameOffset; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _annotations?.forEach((b) => b.flushInformative()); _documentationComment = null; _nameOffset = null; } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._name ?? ''); if (this._annotations == null) { @@ -23618,7 +23427,7 @@ _annotations ??= <UnlinkedExprBuilder>[]; /// Annotations for this executable. - void set annotations(List<UnlinkedExprBuilder> value) { + set annotations(List<UnlinkedExprBuilder> value) { this._annotations = value; } @@ -23628,7 +23437,7 @@ /// If this executable's function body is declared using `=>`, the expression /// to the right of the `=>`. May be omitted if neither type inference nor /// constant evaluation depends on the function body. - void set bodyExpr(UnlinkedExprBuilder value) { + set bodyExpr(UnlinkedExprBuilder value) { this._bodyExpr = value; } @@ -23636,7 +23445,7 @@ CodeRangeBuilder get codeRange => _codeRange; /// Code range of the executable. - void set codeRange(CodeRangeBuilder value) { + set codeRange(CodeRangeBuilder value) { this._codeRange = value; } @@ -23646,8 +23455,7 @@ /// If a constant [UnlinkedExecutableKind.constructor], the constructor /// initializers. Otherwise empty. - void set constantInitializers( - List<UnlinkedConstructorInitializerBuilder> value) { + set constantInitializers(List<UnlinkedConstructorInitializerBuilder> value) { this._constantInitializers = value; } @@ -23660,7 +23468,7 @@ /// a cycle. /// /// Otherwise, zero. - void set constCycleSlot(int value) { + set constCycleSlot(int value) { assert(value == null || value >= 0); this._constCycleSlot = value; } @@ -23671,7 +23479,7 @@ /// Documentation comment for the executable, or `null` if there is no /// documentation comment. - void set documentationComment(UnlinkedDocumentationCommentBuilder value) { + set documentationComment(UnlinkedDocumentationCommentBuilder value) { this._documentationComment = value; } @@ -23683,7 +23491,7 @@ /// return type. If there is no matching entry in [LinkedUnit.types], then /// no return type was inferred for this variable, so its static type is /// `dynamic`. - void set inferredReturnTypeSlot(int value) { + set inferredReturnTypeSlot(int value) { assert(value == null || value >= 0); this._inferredReturnTypeSlot = value; } @@ -23692,7 +23500,7 @@ bool get isAbstract => _isAbstract ??= false; /// Indicates whether the executable is declared using the `abstract` keyword. - void set isAbstract(bool value) { + set isAbstract(bool value) { this._isAbstract = value; } @@ -23700,7 +23508,7 @@ bool get isAsynchronous => _isAsynchronous ??= false; /// Indicates whether the executable has body marked as being asynchronous. - void set isAsynchronous(bool value) { + set isAsynchronous(bool value) { this._isAsynchronous = value; } @@ -23708,7 +23516,7 @@ bool get isConst => _isConst ??= false; /// Indicates whether the executable is declared using the `const` keyword. - void set isConst(bool value) { + set isConst(bool value) { this._isConst = value; } @@ -23716,7 +23524,7 @@ bool get isExternal => _isExternal ??= false; /// Indicates whether the executable is declared using the `external` keyword. - void set isExternal(bool value) { + set isExternal(bool value) { this._isExternal = value; } @@ -23724,7 +23532,7 @@ bool get isFactory => _isFactory ??= false; /// Indicates whether the executable is declared using the `factory` keyword. - void set isFactory(bool value) { + set isFactory(bool value) { this._isFactory = value; } @@ -23732,7 +23540,7 @@ bool get isGenerator => _isGenerator ??= false; /// Indicates whether the executable has body marked as being a generator. - void set isGenerator(bool value) { + set isGenerator(bool value) { this._isGenerator = value; } @@ -23740,7 +23548,7 @@ bool get isRedirectedConstructor => _isRedirectedConstructor ??= false; /// Indicates whether the executable is a redirected constructor. - void set isRedirectedConstructor(bool value) { + set isRedirectedConstructor(bool value) { this._isRedirectedConstructor = value; } @@ -23752,7 +23560,7 @@ /// Note that for top level executables, this flag is false, since they are /// not declared using the `static` keyword (even though they are considered /// static for semantic purposes). - void set isStatic(bool value) { + set isStatic(bool value) { this._isStatic = value; } @@ -23762,7 +23570,7 @@ /// The kind of the executable (function/method, getter, setter, or /// constructor). - void set kind(idl.UnlinkedExecutableKind value) { + set kind(idl.UnlinkedExecutableKind value) { this._kind = value; } @@ -23771,7 +23579,7 @@ _localFunctions ??= <UnlinkedExecutableBuilder>[]; /// The list of local functions. - void set localFunctions(List<UnlinkedExecutableBuilder> value) { + set localFunctions(List<UnlinkedExecutableBuilder> value) { this._localFunctions = value; } @@ -23789,7 +23597,7 @@ /// Name of the executable. For setters, this includes the trailing "=". For /// named constructors, this excludes the class name and excludes the ".". /// For unnamed constructors, this is the empty string. - void set name(String value) { + set name(String value) { this._name = value; } @@ -23798,7 +23606,7 @@ /// If [kind] is [UnlinkedExecutableKind.constructor] and [name] is not empty, /// the offset of the end of the constructor name. Otherwise zero. - void set nameEnd(int value) { + set nameEnd(int value) { assert(value == null || value >= 0); this._nameEnd = value; } @@ -23810,7 +23618,7 @@ /// named constructors, this excludes the class name and excludes the ".". /// For unnamed constructors, this is the offset of the class name (i.e. the /// offset of the second "C" in "class C { C(); }"). - void set nameOffset(int value) { + set nameOffset(int value) { assert(value == null || value >= 0); this._nameOffset = value; } @@ -23822,7 +23630,7 @@ /// Parameters of the executable, if any. Note that getters have no /// parameters (hence this will be the empty list), and setters have a single /// parameter. - void set parameters(List<UnlinkedParamBuilder> value) { + set parameters(List<UnlinkedParamBuilder> value) { this._parameters = value; } @@ -23831,7 +23639,7 @@ /// If [kind] is [UnlinkedExecutableKind.constructor] and [name] is not empty, /// the offset of the period before the constructor name. Otherwise zero. - void set periodOffset(int value) { + set periodOffset(int value) { assert(value == null || value >= 0); this._periodOffset = value; } @@ -23841,7 +23649,7 @@ /// If [isRedirectedConstructor] and [isFactory] are both `true`, the /// constructor to which this constructor redirects; otherwise empty. - void set redirectedConstructor(EntityRefBuilder value) { + set redirectedConstructor(EntityRefBuilder value) { this._redirectedConstructor = value; } @@ -23851,7 +23659,7 @@ /// If [isRedirectedConstructor] is `true` and [isFactory] is `false`, the /// name of the constructor that this constructor redirects to; otherwise /// empty. - void set redirectedConstructorName(String value) { + set redirectedConstructorName(String value) { this._redirectedConstructorName = value; } @@ -23863,7 +23671,7 @@ /// associated with variable initializers and closures, since these /// executables may have return types that are not accessible via direct /// imports. - void set returnType(EntityRefBuilder value) { + set returnType(EntityRefBuilder value) { this._returnType = value; } @@ -23873,7 +23681,7 @@ /// Type parameters of the executable, if any. Empty if support for generic /// method syntax is disabled. - void set typeParameters(List<UnlinkedTypeParamBuilder> value) { + set typeParameters(List<UnlinkedTypeParamBuilder> value) { this._typeParameters = value; } @@ -23881,7 +23689,7 @@ int get visibleLength => _visibleLength ??= 0; /// If a local function, the length of the visible range; zero otherwise. - void set visibleLength(int value) { + set visibleLength(int value) { assert(value == null || value >= 0); this._visibleLength = value; } @@ -23890,7 +23698,7 @@ int get visibleOffset => _visibleOffset ??= 0; /// If a local function, the beginning of the visible range; zero otherwise. - void set visibleOffset(int value) { + set visibleOffset(int value) { assert(value == null || value >= 0); this._visibleOffset = value; } @@ -23953,9 +23761,7 @@ _visibleLength = visibleLength, _visibleOffset = visibleOffset; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _annotations?.forEach((b) => b.flushInformative()); _bodyExpr?.flushInformative(); @@ -23976,9 +23782,7 @@ _visibleOffset = null; } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._name ?? ''); if (this._parameters == null) { @@ -24527,7 +24331,7 @@ _annotations ??= <UnlinkedExprBuilder>[]; /// Annotations for this export directive. - void set annotations(List<UnlinkedExprBuilder> value) { + set annotations(List<UnlinkedExprBuilder> value) { this._annotations = value; } @@ -24535,7 +24339,7 @@ int get offset => _offset ??= 0; /// Offset of the "export" keyword. - void set offset(int value) { + set offset(int value) { assert(value == null || value >= 0); this._offset = value; } @@ -24545,7 +24349,7 @@ /// End of the URI string (including quotes) relative to the beginning of the /// file. - void set uriEnd(int value) { + set uriEnd(int value) { assert(value == null || value >= 0); this._uriEnd = value; } @@ -24555,7 +24359,7 @@ /// Offset of the URI string (including quotes) relative to the beginning of /// the file. - void set uriOffset(int value) { + set uriOffset(int value) { assert(value == null || value >= 0); this._uriOffset = value; } @@ -24570,9 +24374,7 @@ _uriEnd = uriEnd, _uriOffset = uriOffset; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _annotations?.forEach((b) => b.flushInformative()); _offset = null; @@ -24580,9 +24382,7 @@ _uriOffset = null; } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._annotations == null) { signature.addInt(0); @@ -24704,7 +24504,7 @@ _combinators ??= <UnlinkedCombinatorBuilder>[]; /// Combinators contained in this export declaration. - void set combinators(List<UnlinkedCombinatorBuilder> value) { + set combinators(List<UnlinkedCombinatorBuilder> value) { this._combinators = value; } @@ -24714,7 +24514,7 @@ /// Configurations used to control which library will actually be loaded at /// run-time. - void set configurations(List<UnlinkedConfigurationBuilder> value) { + set configurations(List<UnlinkedConfigurationBuilder> value) { this._configurations = value; } @@ -24722,7 +24522,7 @@ String get uri => _uri ??= ''; /// URI used in the source code to reference the exported library. - void set uri(String value) { + set uri(String value) { this._uri = value; } @@ -24734,17 +24534,13 @@ _configurations = configurations, _uri = uri; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _combinators?.forEach((b) => b.flushInformative()); _configurations?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._uri ?? ''); if (this._combinators == null) { @@ -24880,7 +24676,7 @@ _assignmentOperators ??= <idl.UnlinkedExprAssignOperator>[]; /// Sequence of operators used by assignment operations. - void set assignmentOperators(List<idl.UnlinkedExprAssignOperator> value) { + set assignmentOperators(List<idl.UnlinkedExprAssignOperator> value) { this._assignmentOperators = value; } @@ -24888,7 +24684,7 @@ List<double> get doubles => _doubles ??= <double>[]; /// Sequence of 64-bit doubles consumed by the operation `pushDouble`. - void set doubles(List<double> value) { + set doubles(List<double> value) { this._doubles = value; } @@ -24898,7 +24694,7 @@ /// Sequence of unsigned 32-bit integers consumed by the operations /// `pushArgument`, `pushInt`, `shiftOr`, `concatenate`, `invokeConstructor`, /// `makeList`, and `makeMap`. - void set ints(List<int> value) { + set ints(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._ints = value; } @@ -24908,7 +24704,7 @@ /// Indicates whether the expression is a valid potentially constant /// expression. - void set isValidConst(bool value) { + set isValidConst(bool value) { this._isValidConst = value; } @@ -24918,7 +24714,7 @@ /// Sequence of operations to execute (starting with an empty stack) to form /// the constant value. - void set operations(List<idl.UnlinkedExprOperation> value) { + set operations(List<idl.UnlinkedExprOperation> value) { this._operations = value; } @@ -24929,7 +24725,7 @@ /// `pushReference`, `invokeConstructor`, `makeList`, and `makeMap`. Note /// that in the case of `pushReference` (and sometimes `invokeConstructor` the /// actual entity being referred to may be something other than a type. - void set references(List<EntityRefBuilder> value) { + set references(List<EntityRefBuilder> value) { this._references = value; } @@ -24938,7 +24734,7 @@ /// String representation of the expression in a form suitable to be tokenized /// and parsed. - void set sourceRepresentation(String value) { + set sourceRepresentation(String value) { this._sourceRepresentation = value; } @@ -24947,7 +24743,7 @@ /// Sequence of strings consumed by the operations `pushString` and /// `invokeConstructor`. - void set strings(List<String> value) { + set strings(List<String> value) { this._strings = value; } @@ -24969,16 +24765,12 @@ _sourceRepresentation = sourceRepresentation, _strings = strings; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _references?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._operations == null) { signature.addInt(0); @@ -25242,7 +25034,7 @@ _annotations ??= <UnlinkedExprBuilder>[]; /// Annotations for this import declaration. - void set annotations(List<UnlinkedExprBuilder> value) { + set annotations(List<UnlinkedExprBuilder> value) { this._annotations = value; } @@ -25251,7 +25043,7 @@ _combinators ??= <UnlinkedCombinatorBuilder>[]; /// Combinators contained in this import declaration. - void set combinators(List<UnlinkedCombinatorBuilder> value) { + set combinators(List<UnlinkedCombinatorBuilder> value) { this._combinators = value; } @@ -25261,7 +25053,7 @@ /// Configurations used to control which library will actually be loaded at /// run-time. - void set configurations(List<UnlinkedConfigurationBuilder> value) { + set configurations(List<UnlinkedConfigurationBuilder> value) { this._configurations = value; } @@ -25269,7 +25061,7 @@ bool get isDeferred => _isDeferred ??= false; /// Indicates whether the import declaration uses the `deferred` keyword. - void set isDeferred(bool value) { + set isDeferred(bool value) { this._isDeferred = value; } @@ -25277,7 +25069,7 @@ bool get isImplicit => _isImplicit ??= false; /// Indicates whether the import declaration is implicit. - void set isImplicit(bool value) { + set isImplicit(bool value) { this._isImplicit = value; } @@ -25286,7 +25078,7 @@ /// If [isImplicit] is false, offset of the "import" keyword. If [isImplicit] /// is true, zero. - void set offset(int value) { + set offset(int value) { assert(value == null || value >= 0); this._offset = value; } @@ -25296,7 +25088,7 @@ /// Offset of the prefix name relative to the beginning of the file, or zero /// if there is no prefix. - void set prefixOffset(int value) { + set prefixOffset(int value) { assert(value == null || value >= 0); this._prefixOffset = value; } @@ -25308,7 +25100,7 @@ /// import declaration, or zero if this import declaration declares no prefix. /// /// Note that multiple imports can declare the same prefix. - void set prefixReference(int value) { + set prefixReference(int value) { assert(value == null || value >= 0); this._prefixReference = value; } @@ -25317,7 +25109,7 @@ String get uri => _uri ??= ''; /// URI used in the source code to reference the imported library. - void set uri(String value) { + set uri(String value) { this._uri = value; } @@ -25326,7 +25118,7 @@ /// End of the URI string (including quotes) relative to the beginning of the /// file. If [isImplicit] is true, zero. - void set uriEnd(int value) { + set uriEnd(int value) { assert(value == null || value >= 0); this._uriEnd = value; } @@ -25336,7 +25128,7 @@ /// Offset of the URI string (including quotes) relative to the beginning of /// the file. If [isImplicit] is true, zero. - void set uriOffset(int value) { + set uriOffset(int value) { assert(value == null || value >= 0); this._uriOffset = value; } @@ -25365,9 +25157,7 @@ _uriEnd = uriEnd, _uriOffset = uriOffset; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _annotations?.forEach((b) => b.flushInformative()); _combinators?.forEach((b) => b.flushInformative()); @@ -25378,9 +25168,7 @@ _uriOffset = null; } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._uri ?? ''); if (this._combinators == null) { @@ -25641,7 +25429,7 @@ _annotations ??= <UnlinkedExprBuilder>[]; /// Annotations for this parameter. - void set annotations(List<UnlinkedExprBuilder> value) { + set annotations(List<UnlinkedExprBuilder> value) { this._annotations = value; } @@ -25649,7 +25437,7 @@ CodeRangeBuilder get codeRange => _codeRange; /// Code range of the parameter. - void set codeRange(CodeRangeBuilder value) { + set codeRange(CodeRangeBuilder value) { this._codeRange = value; } @@ -25658,7 +25446,7 @@ /// If the parameter has a default value, the source text of the constant /// expression in the default value. Otherwise the empty string. - void set defaultValueCode(String value) { + set defaultValueCode(String value) { this._defaultValueCode = value; } @@ -25674,7 +25462,7 @@ /// inferable, they are not marked as such in the summary; if their type is /// not specified, they always inherit the static type of the corresponding /// field. - void set inferredTypeSlot(int value) { + set inferredTypeSlot(int value) { assert(value == null || value >= 0); this._inferredTypeSlot = value; } @@ -25688,7 +25476,7 @@ /// `@covariant` behavior from a base class. /// /// Otherwise, zero. - void set inheritsCovariantSlot(int value) { + set inheritsCovariantSlot(int value) { assert(value == null || value >= 0); this._inheritsCovariantSlot = value; } @@ -25698,7 +25486,7 @@ /// The synthetic initializer function of the parameter. Absent if the /// variable does not have an initializer. - void set initializer(UnlinkedExecutableBuilder value) { + set initializer(UnlinkedExecutableBuilder value) { this._initializer = value; } @@ -25706,7 +25494,7 @@ bool get isExplicitlyCovariant => _isExplicitlyCovariant ??= false; /// Indicates whether this parameter is explicitly marked as being covariant. - void set isExplicitlyCovariant(bool value) { + set isExplicitlyCovariant(bool value) { this._isExplicitlyCovariant = value; } @@ -25714,7 +25502,7 @@ bool get isFinal => _isFinal ??= false; /// Indicates whether the parameter is declared using the `final` keyword. - void set isFinal(bool value) { + set isFinal(bool value) { this._isFinal = value; } @@ -25729,7 +25517,7 @@ /// ``` /// but is not function-typed if it does not, even if the type of the /// parameter is a function type. - void set isFunctionTyped(bool value) { + set isFunctionTyped(bool value) { this._isFunctionTyped = value; } @@ -25738,7 +25526,7 @@ /// Indicates whether this is an initializing formal parameter (i.e. it is /// declared using `this.` syntax). - void set isInitializingFormal(bool value) { + set isInitializingFormal(bool value) { this._isInitializingFormal = value; } @@ -25746,7 +25534,7 @@ idl.UnlinkedParamKind get kind => _kind ??= idl.UnlinkedParamKind.required; /// Kind of the parameter. - void set kind(idl.UnlinkedParamKind value) { + set kind(idl.UnlinkedParamKind value) { this._kind = value; } @@ -25754,7 +25542,7 @@ String get name => _name ??= ''; /// Name of the parameter. - void set name(String value) { + set name(String value) { this._name = value; } @@ -25762,7 +25550,7 @@ int get nameOffset => _nameOffset ??= 0; /// Offset of the parameter name relative to the beginning of the file. - void set nameOffset(int value) { + set nameOffset(int value) { assert(value == null || value >= 0); this._nameOffset = value; } @@ -25772,7 +25560,7 @@ _parameters ??= <UnlinkedParamBuilder>[]; /// If [isFunctionTyped] is `true`, the parameters of the function type. - void set parameters(List<UnlinkedParamBuilder> value) { + set parameters(List<UnlinkedParamBuilder> value) { this._parameters = value; } @@ -25782,7 +25570,7 @@ /// If [isFunctionTyped] is `true`, the declared return type. If /// [isFunctionTyped] is `false`, the declared type. Absent if the type is /// implicit. - void set type(EntityRefBuilder value) { + set type(EntityRefBuilder value) { this._type = value; } @@ -25790,7 +25578,7 @@ int get visibleLength => _visibleLength ??= 0; /// The length of the visible range. - void set visibleLength(int value) { + set visibleLength(int value) { assert(value == null || value >= 0); this._visibleLength = value; } @@ -25799,7 +25587,7 @@ int get visibleOffset => _visibleOffset ??= 0; /// The beginning of the visible range. - void set visibleOffset(int value) { + set visibleOffset(int value) { assert(value == null || value >= 0); this._visibleOffset = value; } @@ -25840,9 +25628,7 @@ _visibleLength = visibleLength, _visibleOffset = visibleOffset; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _annotations?.forEach((b) => b.flushInformative()); _codeRange = null; @@ -25855,9 +25641,7 @@ _visibleOffset = null; } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._name ?? ''); signature.addInt(this._inferredTypeSlot ?? 0); @@ -26194,7 +25978,7 @@ _annotations ??= <UnlinkedExprBuilder>[]; /// Annotations for this part declaration. - void set annotations(List<UnlinkedExprBuilder> value) { + set annotations(List<UnlinkedExprBuilder> value) { this._annotations = value; } @@ -26203,7 +25987,7 @@ /// End of the URI string (including quotes) relative to the beginning of the /// file. - void set uriEnd(int value) { + set uriEnd(int value) { assert(value == null || value >= 0); this._uriEnd = value; } @@ -26213,7 +25997,7 @@ /// Offset of the URI string (including quotes) relative to the beginning of /// the file. - void set uriOffset(int value) { + set uriOffset(int value) { assert(value == null || value >= 0); this._uriOffset = value; } @@ -26224,18 +26008,14 @@ _uriEnd = uriEnd, _uriOffset = uriOffset; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _annotations?.forEach((b) => b.flushInformative()); _uriEnd = null; _uriOffset = null; } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._annotations == null) { signature.addInt(0); @@ -26343,7 +26123,7 @@ idl.ReferenceKind get kind => _kind ??= idl.ReferenceKind.classOrEnum; /// The kind of object referred to by the name. - void set kind(idl.ReferenceKind value) { + set kind(idl.ReferenceKind value) { this._kind = value; } @@ -26357,7 +26137,7 @@ /// /// Unnamed constructors are not included since they do not constitute a /// separate name added to any namespace. - void set members(List<UnlinkedPublicNameBuilder> value) { + set members(List<UnlinkedPublicNameBuilder> value) { this._members = value; } @@ -26365,7 +26145,7 @@ String get name => _name ??= ''; /// The name itself. - void set name(String value) { + set name(String value) { this._name = value; } @@ -26374,7 +26154,7 @@ /// If the entity being referred to is generic, the number of type parameters /// it accepts. Otherwise zero. - void set numTypeParameters(int value) { + set numTypeParameters(int value) { assert(value == null || value >= 0); this._numTypeParameters = value; } @@ -26389,16 +26169,12 @@ _name = name, _numTypeParameters = numTypeParameters; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _members?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._name ?? ''); signature.addInt(this._kind == null ? 0 : this._kind.index); @@ -26529,7 +26305,7 @@ _exports ??= <UnlinkedExportPublicBuilder>[]; /// Export declarations in the compilation unit. - void set exports(List<UnlinkedExportPublicBuilder> value) { + set exports(List<UnlinkedExportPublicBuilder> value) { this._exports = value; } @@ -26541,7 +26317,7 @@ /// /// TODO(paulberry): consider sorting these names to reduce unnecessary /// relinking. - void set names(List<UnlinkedPublicNameBuilder> value) { + set names(List<UnlinkedPublicNameBuilder> value) { this._names = value; } @@ -26549,7 +26325,7 @@ List<String> get parts => _parts ??= <String>[]; /// URIs referenced by part declarations in the compilation unit. - void set parts(List<String> value) { + set parts(List<String> value) { this._parts = value; } @@ -26561,17 +26337,13 @@ _names = names, _parts = parts; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _exports?.forEach((b) => b.flushInformative()); _names?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._names == null) { signature.addInt(0); @@ -26720,7 +26492,7 @@ /// Name of the entity being referred to. For the pseudo-type `dynamic`, the /// string is "dynamic". For the pseudo-type `void`, the string is "void". /// For the pseudo-type `bottom`, the string is "*bottom*". - void set name(String value) { + set name(String value) { this._name = value; } @@ -26733,7 +26505,7 @@ /// Prefix references must always point backward; that is, for all i, if /// UnlinkedUnit.references[i].prefixReference != 0, then /// UnlinkedUnit.references[i].prefixReference < i. - void set prefixReference(int value) { + set prefixReference(int value) { assert(value == null || value >= 0); this._prefixReference = value; } @@ -26742,14 +26514,10 @@ : _name = name, _prefixReference = prefixReference; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() {} - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._name ?? ''); signature.addInt(this._prefixReference ?? 0); @@ -26841,7 +26609,7 @@ /// The token that corresponds to this token, or `0` if this token is not /// the first of a pair of matching tokens (such as parentheses). - void set endGroup(List<int> value) { + set endGroup(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._endGroup = value; } @@ -26852,21 +26620,21 @@ /// Return `true` if this token is a synthetic token. A synthetic token is a /// token that was introduced by the parser in order to recover from an error /// in the code. - void set isSynthetic(List<bool> value) { + set isSynthetic(List<bool> value) { this._isSynthetic = value; } @override List<idl.UnlinkedTokenKind> get kind => _kind ??= <idl.UnlinkedTokenKind>[]; - void set kind(List<idl.UnlinkedTokenKind> value) { + set kind(List<idl.UnlinkedTokenKind> value) { this._kind = value; } @override List<int> get length => _length ??= <int>[]; - void set length(List<int> value) { + set length(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._length = value; } @@ -26874,7 +26642,7 @@ @override List<String> get lexeme => _lexeme ??= <String>[]; - void set lexeme(List<String> value) { + set lexeme(List<String> value) { this._lexeme = value; } @@ -26883,7 +26651,7 @@ /// The next token in the token stream, `0` for [UnlinkedTokenType.EOF] or /// the last comment token. - void set next(List<int> value) { + set next(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._next = value; } @@ -26891,7 +26659,7 @@ @override List<int> get offset => _offset ??= <int>[]; - void set offset(List<int> value) { + set offset(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._offset = value; } @@ -26903,7 +26671,7 @@ /// or `0` if there are no comments preceding this token. Additional comments /// can be reached by following the token stream using [next] until `0` is /// reached. - void set precedingComment(List<int> value) { + set precedingComment(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._precedingComment = value; } @@ -26911,7 +26679,7 @@ @override List<idl.UnlinkedTokenType> get type => _type ??= <idl.UnlinkedTokenType>[]; - void set type(List<idl.UnlinkedTokenType> value) { + set type(List<idl.UnlinkedTokenType> value) { this._type = value; } @@ -26935,14 +26703,10 @@ _precedingComment = precedingComment, _type = type; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() {} - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { if (this._endGroup == null) { signature.addInt(0); @@ -27239,7 +27003,7 @@ _annotations ??= <UnlinkedExprBuilder>[]; /// Annotations for this typedef. - void set annotations(List<UnlinkedExprBuilder> value) { + set annotations(List<UnlinkedExprBuilder> value) { this._annotations = value; } @@ -27247,7 +27011,7 @@ CodeRangeBuilder get codeRange => _codeRange; /// Code range of the typedef. - void set codeRange(CodeRangeBuilder value) { + set codeRange(CodeRangeBuilder value) { this._codeRange = value; } @@ -27257,7 +27021,7 @@ /// Documentation comment for the typedef, or `null` if there is no /// documentation comment. - void set documentationComment(UnlinkedDocumentationCommentBuilder value) { + set documentationComment(UnlinkedDocumentationCommentBuilder value) { this._documentationComment = value; } @@ -27265,7 +27029,7 @@ String get name => _name ??= ''; /// Name of the typedef. - void set name(String value) { + set name(String value) { this._name = value; } @@ -27273,7 +27037,7 @@ int get nameOffset => _nameOffset ??= 0; /// Offset of the typedef name relative to the beginning of the file. - void set nameOffset(int value) { + set nameOffset(int value) { assert(value == null || value >= 0); this._nameOffset = value; } @@ -27288,7 +27052,7 @@ /// raw type when specifying the bound of a type parameter. /// /// Otherwise, zero. - void set notSimplyBoundedSlot(int value) { + set notSimplyBoundedSlot(int value) { assert(value == null || value >= 0); this._notSimplyBoundedSlot = value; } @@ -27298,7 +27062,7 @@ _parameters ??= <UnlinkedParamBuilder>[]; /// Parameters of the executable, if any. - void set parameters(List<UnlinkedParamBuilder> value) { + set parameters(List<UnlinkedParamBuilder> value) { this._parameters = value; } @@ -27308,7 +27072,7 @@ /// If [style] is [TypedefStyle.functionType], the return type of the typedef. /// If [style] is [TypedefStyle.genericFunctionType], the function type being /// defined. - void set returnType(EntityRefBuilder value) { + set returnType(EntityRefBuilder value) { this._returnType = value; } @@ -27316,7 +27080,7 @@ idl.TypedefStyle get style => _style ??= idl.TypedefStyle.functionType; /// The style of the typedef. - void set style(idl.TypedefStyle value) { + set style(idl.TypedefStyle value) { this._style = value; } @@ -27325,7 +27089,7 @@ _typeParameters ??= <UnlinkedTypeParamBuilder>[]; /// Type parameters of the typedef, if any. - void set typeParameters(List<UnlinkedTypeParamBuilder> value) { + set typeParameters(List<UnlinkedTypeParamBuilder> value) { this._typeParameters = value; } @@ -27351,9 +27115,7 @@ _style = style, _typeParameters = typeParameters; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _annotations?.forEach((b) => b.flushInformative()); _codeRange = null; @@ -27364,9 +27126,7 @@ _typeParameters?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._name ?? ''); signature.addBool(this._returnType != null); @@ -27621,7 +27381,7 @@ _annotations ??= <UnlinkedExprBuilder>[]; /// Annotations for this type parameter. - void set annotations(List<UnlinkedExprBuilder> value) { + set annotations(List<UnlinkedExprBuilder> value) { this._annotations = value; } @@ -27630,7 +27390,7 @@ /// Bound of the type parameter, if a bound is explicitly declared. Otherwise /// null. - void set bound(EntityRefBuilder value) { + set bound(EntityRefBuilder value) { this._bound = value; } @@ -27638,7 +27398,7 @@ CodeRangeBuilder get codeRange => _codeRange; /// Code range of the type parameter. - void set codeRange(CodeRangeBuilder value) { + set codeRange(CodeRangeBuilder value) { this._codeRange = value; } @@ -27646,7 +27406,7 @@ String get name => _name ??= ''; /// Name of the type parameter. - void set name(String value) { + set name(String value) { this._name = value; } @@ -27654,7 +27414,7 @@ int get nameOffset => _nameOffset ??= 0; /// Offset of the type parameter name relative to the beginning of the file. - void set nameOffset(int value) { + set nameOffset(int value) { assert(value == null || value >= 0); this._nameOffset = value; } @@ -27671,9 +27431,7 @@ _name = name, _nameOffset = nameOffset; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _annotations?.forEach((b) => b.flushInformative()); _bound?.flushInformative(); @@ -27681,9 +27439,7 @@ _nameOffset = null; } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._name ?? ''); signature.addBool(this._bound != null); @@ -27848,7 +27604,7 @@ /// MD5 hash of the non-informative fields of the [UnlinkedUnit] (not /// including this one) as 16 unsigned 8-bit integer values. This can be used /// to identify when the API of a unit may have changed. - void set apiSignature(List<int> value) { + set apiSignature(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._apiSignature = value; } @@ -27858,7 +27614,7 @@ _classes ??= <UnlinkedClassBuilder>[]; /// Classes declared in the compilation unit. - void set classes(List<UnlinkedClassBuilder> value) { + set classes(List<UnlinkedClassBuilder> value) { this._classes = value; } @@ -27866,7 +27622,7 @@ CodeRangeBuilder get codeRange => _codeRange; /// Code range of the unit. - void set codeRange(CodeRangeBuilder value) { + set codeRange(CodeRangeBuilder value) { this._codeRange = value; } @@ -27874,7 +27630,7 @@ List<UnlinkedEnumBuilder> get enums => _enums ??= <UnlinkedEnumBuilder>[]; /// Enums declared in the compilation unit. - void set enums(List<UnlinkedEnumBuilder> value) { + set enums(List<UnlinkedEnumBuilder> value) { this._enums = value; } @@ -27884,7 +27640,7 @@ /// Top level executable objects (functions, getters, and setters) declared in /// the compilation unit. - void set executables(List<UnlinkedExecutableBuilder> value) { + set executables(List<UnlinkedExecutableBuilder> value) { this._executables = value; } @@ -27893,7 +27649,7 @@ _exports ??= <UnlinkedExportNonPublicBuilder>[]; /// Export declarations in the compilation unit. - void set exports(List<UnlinkedExportNonPublicBuilder> value) { + set exports(List<UnlinkedExportNonPublicBuilder> value) { this._exports = value; } @@ -27906,7 +27662,7 @@ _imports ??= <UnlinkedImportBuilder>[]; /// Import declarations in the compilation unit. - void set imports(List<UnlinkedImportBuilder> value) { + set imports(List<UnlinkedImportBuilder> value) { this._imports = value; } @@ -27914,7 +27670,7 @@ bool get isPartOf => _isPartOf ??= false; /// Indicates whether the unit contains a "part of" declaration. - void set isPartOf(bool value) { + set isPartOf(bool value) { this._isPartOf = value; } @@ -27924,7 +27680,7 @@ /// Annotations for the library declaration, or the empty list if there is no /// library declaration. - void set libraryAnnotations(List<UnlinkedExprBuilder> value) { + set libraryAnnotations(List<UnlinkedExprBuilder> value) { this._libraryAnnotations = value; } @@ -27934,8 +27690,7 @@ /// Documentation comment for the library, or `null` if there is no /// documentation comment. - void set libraryDocumentationComment( - UnlinkedDocumentationCommentBuilder value) { + set libraryDocumentationComment(UnlinkedDocumentationCommentBuilder value) { this._libraryDocumentationComment = value; } @@ -27943,7 +27698,7 @@ String get libraryName => _libraryName ??= ''; /// Name of the library (from a "library" declaration, if present). - void set libraryName(String value) { + set libraryName(String value) { this._libraryName = value; } @@ -27952,7 +27707,7 @@ /// Length of the library name as it appears in the source code (or 0 if the /// library has no name). - void set libraryNameLength(int value) { + set libraryNameLength(int value) { assert(value == null || value >= 0); this._libraryNameLength = value; } @@ -27962,7 +27717,7 @@ /// Offset of the library name relative to the beginning of the file (or 0 if /// the library has no name). - void set libraryNameOffset(int value) { + set libraryNameOffset(int value) { assert(value == null || value >= 0); this._libraryNameOffset = value; } @@ -27971,7 +27726,7 @@ List<int> get lineStarts => _lineStarts ??= <int>[]; /// Offsets of the first character of each line in the source code. - void set lineStarts(List<int> value) { + set lineStarts(List<int> value) { assert(value == null || value.every((e) => e >= 0)); this._lineStarts = value; } @@ -27980,7 +27735,7 @@ List<UnlinkedClassBuilder> get mixins => _mixins ??= <UnlinkedClassBuilder>[]; /// Mixins declared in the compilation unit. - void set mixins(List<UnlinkedClassBuilder> value) { + set mixins(List<UnlinkedClassBuilder> value) { this._mixins = value; } @@ -27988,7 +27743,7 @@ List<UnlinkedPartBuilder> get parts => _parts ??= <UnlinkedPartBuilder>[]; /// Part declarations in the compilation unit. - void set parts(List<UnlinkedPartBuilder> value) { + set parts(List<UnlinkedPartBuilder> value) { this._parts = value; } @@ -27996,7 +27751,7 @@ UnlinkedPublicNamespaceBuilder get publicNamespace => _publicNamespace; /// Unlinked public namespace of this compilation unit. - void set publicNamespace(UnlinkedPublicNamespaceBuilder value) { + set publicNamespace(UnlinkedPublicNamespaceBuilder value) { this._publicNamespace = value; } @@ -28009,7 +27764,7 @@ /// the absence of a reference in places where a reference is optional (for /// example [UnlinkedReference.prefixReference or /// UnlinkedImport.prefixReference]). - void set references(List<UnlinkedReferenceBuilder> value) { + set references(List<UnlinkedReferenceBuilder> value) { this._references = value; } @@ -28018,7 +27773,7 @@ _typedefs ??= <UnlinkedTypedefBuilder>[]; /// Typedefs declared in the compilation unit. - void set typedefs(List<UnlinkedTypedefBuilder> value) { + set typedefs(List<UnlinkedTypedefBuilder> value) { this._typedefs = value; } @@ -28027,7 +27782,7 @@ _variables ??= <UnlinkedVariableBuilder>[]; /// Top level variables declared in the compilation unit. - void set variables(List<UnlinkedVariableBuilder> value) { + set variables(List<UnlinkedVariableBuilder> value) { this._variables = value; } @@ -28073,9 +27828,7 @@ _typedefs = typedefs, _variables = variables; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _classes?.forEach((b) => b.flushInformative()); _codeRange = null; @@ -28096,9 +27849,7 @@ _variables?.forEach((b) => b.flushInformative()); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addBool(this._publicNamespace != null); this._publicNamespace?.collectApiSignature(signature); @@ -28646,7 +28397,7 @@ _annotations ??= <UnlinkedExprBuilder>[]; /// Annotations for this variable. - void set annotations(List<UnlinkedExprBuilder> value) { + set annotations(List<UnlinkedExprBuilder> value) { this._annotations = value; } @@ -28654,7 +28405,7 @@ CodeRangeBuilder get codeRange => _codeRange; /// Code range of the variable. - void set codeRange(CodeRangeBuilder value) { + set codeRange(CodeRangeBuilder value) { this._codeRange = value; } @@ -28664,7 +28415,7 @@ /// Documentation comment for the variable, or `null` if there is no /// documentation comment. - void set documentationComment(UnlinkedDocumentationCommentBuilder value) { + set documentationComment(UnlinkedDocumentationCommentBuilder value) { this._documentationComment = value; } @@ -28675,7 +28426,7 @@ /// [LinkedLibrary.types] contains the inferred type for this variable. If /// there is no matching entry in [LinkedLibrary.types], then no type was /// inferred for this variable, so its static type is `dynamic`. - void set inferredTypeSlot(int value) { + set inferredTypeSlot(int value) { assert(value == null || value >= 0); this._inferredTypeSlot = value; } @@ -28689,7 +28440,7 @@ /// synthetic setter inherits `@covariant` behavior from a base class. /// /// Otherwise, zero. - void set inheritsCovariantSlot(int value) { + set inheritsCovariantSlot(int value) { assert(value == null || value >= 0); this._inheritsCovariantSlot = value; } @@ -28699,7 +28450,7 @@ /// The synthetic initializer function of the variable. Absent if the /// variable does not have an initializer. - void set initializer(UnlinkedExecutableBuilder value) { + set initializer(UnlinkedExecutableBuilder value) { this._initializer = value; } @@ -28707,7 +28458,7 @@ bool get isConst => _isConst ??= false; /// Indicates whether the variable is declared using the `const` keyword. - void set isConst(bool value) { + set isConst(bool value) { this._isConst = value; } @@ -28716,7 +28467,7 @@ /// Indicates whether this variable is declared using the `covariant` keyword. /// This should be false for everything except instance fields. - void set isCovariant(bool value) { + set isCovariant(bool value) { this._isCovariant = value; } @@ -28724,7 +28475,7 @@ bool get isFinal => _isFinal ??= false; /// Indicates whether the variable is declared using the `final` keyword. - void set isFinal(bool value) { + set isFinal(bool value) { this._isFinal = value; } @@ -28736,7 +28487,7 @@ /// Note that for top level variables, this flag is false, since they are not /// declared using the `static` keyword (even though they are considered /// static for semantic purposes). - void set isStatic(bool value) { + set isStatic(bool value) { this._isStatic = value; } @@ -28744,7 +28495,7 @@ String get name => _name ??= ''; /// Name of the variable. - void set name(String value) { + set name(String value) { this._name = value; } @@ -28752,7 +28503,7 @@ int get nameOffset => _nameOffset ??= 0; /// Offset of the variable name relative to the beginning of the file. - void set nameOffset(int value) { + set nameOffset(int value) { assert(value == null || value >= 0); this._nameOffset = value; } @@ -28766,7 +28517,7 @@ /// propagated type is the same as its declared type. /// /// Non-propagable variables have a [propagatedTypeSlot] of zero. - void set propagatedTypeSlot(int value) { + set propagatedTypeSlot(int value) { assert(value == null || value >= 0); this._propagatedTypeSlot = value; } @@ -28775,7 +28526,7 @@ EntityRefBuilder get type => _type; /// Declared type of the variable. Absent if the type is implicit. - void set type(EntityRefBuilder value) { + set type(EntityRefBuilder value) { this._type = value; } @@ -28817,9 +28568,7 @@ _propagatedTypeSlot = propagatedTypeSlot, _type = type; - /** - * Flush [informative] data recursively. - */ + /// Flush [informative] data recursively. void flushInformative() { _annotations?.forEach((b) => b.flushInformative()); _codeRange = null; @@ -28829,9 +28578,7 @@ _type?.flushInformative(); } - /** - * Accumulate non-[informative] data into [signature]. - */ + /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addString(this._name ?? ''); signature.addInt(this._propagatedTypeSlot ?? 0);
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs index bab0ccd..bb86ffb 100644 --- a/pkg/analyzer/lib/src/summary/format.fbs +++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -1547,40 +1547,38 @@ /// Information about a single declaration. table AvailableDeclaration { - defaultArgumentListString:string (id: 0); + children:[AvailableDeclaration] (id: 0); - defaultArgumentListTextRanges:[uint] (id: 1); + defaultArgumentListString:string (id: 1); - docComplete:string (id: 2); + defaultArgumentListTextRanges:[uint] (id: 2); - docSummary:string (id: 3); + docComplete:string (id: 3); - fieldMask:uint (id: 4); + docSummary:string (id: 4); - isAbstract:bool (id: 5); + fieldMask:uint (id: 5); - isConst:bool (id: 6); + isAbstract:bool (id: 6); - isDeprecated:bool (id: 7); + isConst:bool (id: 7); - isFinal:bool (id: 8); + isDeprecated:bool (id: 8); + + isFinal:bool (id: 9); /// The kind of the declaration. - kind:AvailableDeclarationKind (id: 9); + kind:AvailableDeclarationKind (id: 10); - locationOffset:uint (id: 10); + locationOffset:uint (id: 11); - locationStartColumn:uint (id: 11); + locationStartColumn:uint (id: 12); - locationStartLine:uint (id: 12); + locationStartLine:uint (id: 13); /// The first part of the declaration name, usually the only one, for example /// the name of a class like `MyClass`, or a function like `myFunction`. - name:string (id: 13); - - /// The second, optional, part of the declaration name. For example enum - /// constants all have the same [name], but their own [name2]. - name2:string (id: 14); + name:string (id: 14); parameterNames:[string] (id: 15); @@ -1603,12 +1601,12 @@ /// Information about an available, even if not yet imported file. table AvailableFile { - /// The Dartdoc directives in the file. - directiveInfo:DirectiveInfo (id: 5); - /// Declarations of the file. declarations:[AvailableDeclaration] (id: 0); + /// The Dartdoc directives in the file. + directiveInfo:DirectiveInfo (id: 5); + /// Exports directives of the file. exports:[AvailableFileExport] (id: 1); @@ -1838,6 +1836,9 @@ /// Information about a linked AST node. table LinkedNode { + /// The explicit or inferred return type of a function typed node. + variantField_24:LinkedNodeType (id: 24); + variantField_2:[LinkedNode] (id: 2); variantField_11:LinkedNode (id: 11); @@ -1860,8 +1861,6 @@ variantField_19:uint (id: 19); - variantField_24:LinkedNodeType (id: 24); - variantField_27:bool (id: 27); variantField_9:LinkedNode (id: 9);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart index 60284a3..4b897bc 100644 --- a/pkg/analyzer/lib/src/summary/idl.dart +++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -288,54 +288,52 @@ /// Information about a single declaration. abstract class AvailableDeclaration extends base.SummaryClass { @Id(0) - String get defaultArgumentListString; + List<AvailableDeclaration> get children; @Id(1) - List<int> get defaultArgumentListTextRanges; + String get defaultArgumentListString; @Id(2) - String get docComplete; + List<int> get defaultArgumentListTextRanges; @Id(3) - String get docSummary; + String get docComplete; @Id(4) - int get fieldMask; + String get docSummary; @Id(5) - bool get isAbstract; + int get fieldMask; @Id(6) - bool get isConst; + bool get isAbstract; @Id(7) - bool get isDeprecated; + bool get isConst; @Id(8) + bool get isDeprecated; + + @Id(9) bool get isFinal; /// The kind of the declaration. - @Id(9) + @Id(10) AvailableDeclarationKind get kind; - @Id(10) + @Id(11) int get locationOffset; - @Id(11) + @Id(12) int get locationStartColumn; - @Id(12) + @Id(13) int get locationStartLine; /// The first part of the declaration name, usually the only one, for example /// the name of a class like `MyClass`, or a function like `myFunction`. - @Id(13) - String get name; - - /// The second, optional, part of the declaration name. For example enum - /// constants all have the same [name], but their own [name2]. @Id(14) - String get name2; + String get name; @Id(15) List<String> get parameterNames; @@ -384,14 +382,14 @@ factory AvailableFile.fromBuffer(List<int> buffer) => generated.readAvailableFile(buffer); - /// The Dartdoc directives in the file. - @Id(5) - DirectiveInfo get directiveInfo; - /// Declarations of the file. @Id(0) List<AvailableDeclaration> get declarations; + /// The Dartdoc directives in the file. + @Id(5) + DirectiveInfo get directiveInfo; + /// Exports directives of the file. @Id(1) List<AvailableFileExport> get exports; @@ -770,6 +768,25 @@ /// Information about a linked AST node. @Variant('kind') abstract class LinkedNode extends base.SummaryClass { + /// The explicit or inferred return type of a function typed node. + @VariantId(24, variantList: [ + LinkedNodeKind.functionDeclaration, + LinkedNodeKind.functionExpression, + LinkedNodeKind.functionTypeAlias, + LinkedNodeKind.genericFunctionType, + LinkedNodeKind.methodDeclaration, + ]) + LinkedNodeType get actualReturnType; + + /// The explicit or inferred type of a variable. + @VariantId(24, variantList: [ + LinkedNodeKind.fieldFormalParameter, + LinkedNodeKind.functionTypedFormalParameter, + LinkedNodeKind.simpleFormalParameter, + LinkedNodeKind.variableDeclaration, + ]) + LinkedNodeType get actualType; + @VariantId(2, variant: LinkedNodeKind.adjacentStrings) List<LinkedNode> get adjacentStrings_strings; @@ -1407,9 +1424,6 @@ @VariantId(6, variant: LinkedNodeKind.fieldFormalParameter) LinkedNode get fieldFormalParameter_type; - @VariantId(24, variant: LinkedNodeKind.fieldFormalParameter) - LinkedNodeType get fieldFormalParameter_type2; - @VariantId(7, variant: LinkedNodeKind.fieldFormalParameter) LinkedNode get fieldFormalParameter_typeParameters; @@ -1531,12 +1545,6 @@ @VariantId(7, variant: LinkedNodeKind.functionDeclaration) LinkedNode get functionDeclaration_returnType; - @VariantId(24, variantList: [ - LinkedNodeKind.functionDeclaration, - LinkedNodeKind.functionExpression, - ]) - LinkedNodeType get functionDeclaration_returnType2; - @VariantId(6, variant: LinkedNodeKind.functionDeclarationStatement) LinkedNode get functionDeclarationStatement_functionDeclaration; @@ -1558,9 +1566,6 @@ @VariantId(7, variant: LinkedNodeKind.functionTypeAlias) LinkedNode get functionTypeAlias_returnType; - @VariantId(24, variant: LinkedNodeKind.functionTypeAlias) - LinkedNodeType get functionTypeAlias_returnType2; - @VariantId(8, variant: LinkedNodeKind.functionTypeAlias) LinkedNode get functionTypeAlias_typeParameters; @@ -1570,9 +1575,6 @@ @VariantId(7, variant: LinkedNodeKind.functionTypedFormalParameter) LinkedNode get functionTypedFormalParameter_returnType; - @VariantId(24, variant: LinkedNodeKind.functionTypedFormalParameter) - LinkedNodeType get functionTypedFormalParameter_type2; - @VariantId(8, variant: LinkedNodeKind.functionTypedFormalParameter) LinkedNode get functionTypedFormalParameter_typeParameters; @@ -1588,9 +1590,6 @@ @VariantId(7, variant: LinkedNodeKind.genericFunctionType) LinkedNode get genericFunctionType_returnType; - @VariantId(24, variant: LinkedNodeKind.genericFunctionType) - LinkedNodeType get genericFunctionType_returnType2; - @VariantId(25, variant: LinkedNodeKind.genericFunctionType) LinkedNodeType get genericFunctionType_type; @@ -1816,9 +1815,6 @@ @VariantId(8, variant: LinkedNodeKind.methodDeclaration) LinkedNode get methodDeclaration_returnType; - @VariantId(24, variant: LinkedNodeKind.methodDeclaration) - LinkedNodeType get methodDeclaration_returnType2; - @VariantId(9, variant: LinkedNodeKind.methodDeclaration) LinkedNode get methodDeclaration_typeParameters; @@ -2041,9 +2037,6 @@ @VariantId(6, variant: LinkedNodeKind.simpleFormalParameter) LinkedNode get simpleFormalParameter_type; - @VariantId(24, variant: LinkedNodeKind.simpleFormalParameter) - LinkedNodeType get simpleFormalParameter_type2; - @VariantId(15, variant: LinkedNodeKind.simpleIdentifier) int get simpleIdentifier_element; @@ -2056,6 +2049,15 @@ @VariantId(20, variant: LinkedNodeKind.simpleStringLiteral) String get simpleStringLiteral_value; + @VariantId(31, variantList: [ + LinkedNodeKind.classDeclaration, + LinkedNodeKind.classTypeAlias, + LinkedNodeKind.functionTypeAlias, + LinkedNodeKind.genericTypeAlias, + LinkedNodeKind.mixinDeclaration, + ]) + bool get simplyBoundable_isSimplyBounded; + @VariantId(6, variant: LinkedNodeKind.spreadElement) LinkedNode get spreadElement_expression; @@ -2265,9 +2267,6 @@ @VariantId(7, variant: LinkedNodeKind.variableDeclaration) LinkedNode get variableDeclaration_name; - @VariantId(24, variant: LinkedNodeKind.variableDeclaration) - LinkedNodeType get variableDeclaration_type2; - @VariantId(15, variant: LinkedNodeKind.variableDeclarationList) int get variableDeclarationList_keyword;
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart index 5c35451..e08c4f6 100644 --- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart +++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -12,6 +12,7 @@ import 'package:analyzer/src/dart/element/type.dart'; import 'package:analyzer/src/generated/utilities_dart.dart'; import 'package:analyzer/src/summary/idl.dart'; +import 'package:analyzer/src/summary2/lazy_ast.dart'; import 'package:analyzer/src/summary2/linked_unit_context.dart'; import 'package:analyzer/src/summary2/reference.dart'; @@ -24,16 +25,26 @@ int _localRefNextId; List<ParameterElement> _localParameters; + /// Set to `true` when this reader is used to lazily read its unit. + bool isLazy = false; + AstBinaryReader(this._unitContext); AstNode readNode(LinkedNode data) { var node = _readNode(data); if (node == null) return null; - _unitContext.tokensContext.linkTokens(node.beginToken, node.endToken); + if (!isLazy) { + _unitContext.tokensContext.linkTokens(node.beginToken, node.endToken); + } + return node; } + DartType readType(LinkedNodeType data) { + return _readType(data); + } + /// Run [f] that reads nodes with local declarations, making sure that /// [_localRef] is ready for adding local references. T withLocalScope<T>(ElementImpl enclosingElement, T f()) { @@ -223,36 +234,41 @@ } ClassDeclaration _read_classDeclaration(LinkedNode data) { - return astFactory.classDeclaration( - _readNode(data.annotatedNode_comment), - _readNodeList(data.annotatedNode_metadata), + var node = astFactory.classDeclaration( + _readNodeLazy(data.annotatedNode_comment), + _readNodeListLazy(data.annotatedNode_metadata), _getToken(data.classDeclaration_abstractKeyword), _getToken(data.classDeclaration_classKeyword), _readNode(data.namedCompilationUnitMember_name), - _readNode(data.classOrMixinDeclaration_typeParameters), - _readNode(data.classDeclaration_extendsClause), - _readNode(data.classDeclaration_withClause), - _readNode(data.classOrMixinDeclaration_implementsClause), + _readNodeLazy(data.classOrMixinDeclaration_typeParameters), + _readNodeLazy(data.classDeclaration_extendsClause), + _readNodeLazy(data.classDeclaration_withClause), + _readNodeLazy(data.classOrMixinDeclaration_implementsClause), _getToken(data.classOrMixinDeclaration_leftBracket), - _readNodeList(data.classOrMixinDeclaration_members), + _readNodeListLazy(data.classOrMixinDeclaration_members), _getToken(data.classOrMixinDeclaration_rightBracket), - )..nativeClause = _readNode(data.classDeclaration_nativeClause); + ); + node.nativeClause = _readNodeLazy(data.classDeclaration_nativeClause); + LazyClassDeclaration.setData(node, data); + return node; } ClassTypeAlias _read_classTypeAlias(LinkedNode data) { - return astFactory.classTypeAlias( - _readNode(data.annotatedNode_comment), - _readNodeList(data.annotatedNode_metadata), + var node = astFactory.classTypeAlias( + _readNodeLazy(data.annotatedNode_comment), + _readNodeListLazy(data.annotatedNode_metadata), _getToken(data.typeAlias_typedefKeyword), _readNode(data.namedCompilationUnitMember_name), - _readNode(data.classTypeAlias_typeParameters), + _readNodeLazy(data.classTypeAlias_typeParameters), _getToken(data.classTypeAlias_equals), _getToken(data.classTypeAlias_abstractKeyword), - _readNode(data.classTypeAlias_superclass), - _readNode(data.classTypeAlias_withClause), - _readNode(data.classTypeAlias_implementsClause), + _readNodeLazy(data.classTypeAlias_superclass), + _readNodeLazy(data.classTypeAlias_withClause), + _readNodeLazy(data.classTypeAlias_implementsClause), _getToken(data.typeAlias_semicolon), ); + LazyClassTypeAlias.setData(node, data); + return node; } Comment _read_comment(LinkedNode data) { @@ -309,21 +325,23 @@ } ConstructorDeclaration _read_constructorDeclaration(LinkedNode data) { - return astFactory.constructorDeclaration( - _readNode(data.annotatedNode_comment), - _readNodeList(data.annotatedNode_metadata), + var node = astFactory.constructorDeclaration( + _readNodeLazy(data.annotatedNode_comment), + _readNodeListLazy(data.annotatedNode_metadata), _getToken(data.constructorDeclaration_externalKeyword), _getToken(data.constructorDeclaration_constKeyword), _getToken(data.constructorDeclaration_factoryKeyword), _readNode(data.constructorDeclaration_returnType), _getToken(data.constructorDeclaration_period), _readNode(data.constructorDeclaration_name), - _readNode(data.constructorDeclaration_parameters), + _readNodeLazy(data.constructorDeclaration_parameters), _getToken(data.constructorDeclaration_separator), - _readNodeList(data.constructorDeclaration_initializers), - _readNode(data.constructorDeclaration_redirectedConstructor), - _readNode(data.constructorDeclaration_body), + _readNodeListLazy(data.constructorDeclaration_initializers), + _readNodeLazy(data.constructorDeclaration_redirectedConstructor), + _readNodeLazy(data.constructorDeclaration_body), ); + LazyConstructorDeclaration.setData(node, data); + return node; } ConstructorFieldInitializer _read_constructorFieldInitializer( @@ -364,14 +382,16 @@ } DefaultFormalParameter _read_defaultFormalParameter(LinkedNode data) { - return astFactory.defaultFormalParameter( + var node = astFactory.defaultFormalParameter( _readNode(data.defaultFormalParameter_parameter), data.defaultFormalParameter_isNamed ? ParameterKind.NAMED : ParameterKind.POSITIONAL, _getToken(data.defaultFormalParameter_separator), - _readNode(data.defaultFormalParameter_defaultValue), + _readNodeLazy(data.defaultFormalParameter_defaultValue), ); + LazyFormalParameter.setData(node, data); + return node; } DoStatement _read_doStatement(LinkedNode data) { @@ -412,35 +432,41 @@ } EnumConstantDeclaration _read_enumConstantDeclaration(LinkedNode data) { - return astFactory.enumConstantDeclaration( - _readNode(data.annotatedNode_comment), - _readNodeList(data.annotatedNode_metadata), + var node = astFactory.enumConstantDeclaration( + _readNodeLazy(data.annotatedNode_comment), + _readNodeListLazy(data.annotatedNode_metadata), _readNode(data.enumConstantDeclaration_name), ); + LazyEnumConstantDeclaration.setData(node, data); + return node; } EnumDeclaration _read_enumDeclaration(LinkedNode data) { - return astFactory.enumDeclaration( - _readNode(data.annotatedNode_comment), - _readNodeList(data.annotatedNode_metadata), + var node = astFactory.enumDeclaration( + _readNodeLazy(data.annotatedNode_comment), + _readNodeListLazy(data.annotatedNode_metadata), _getToken(data.enumDeclaration_enumKeyword), _readNode(data.namedCompilationUnitMember_name), _getToken(data.enumDeclaration_leftBracket), - _readNodeList(data.enumDeclaration_constants), + _readNodeListLazy(data.enumDeclaration_constants), _getToken(data.enumDeclaration_rightBracket), ); + LazyEnumDeclaration.setData(node, data); + return node; } ExportDirective _read_exportDirective(LinkedNode data) { - return astFactory.exportDirective( + var node = astFactory.exportDirective( _readNode(data.annotatedNode_comment), - _readNodeList(data.annotatedNode_metadata), + _readNodeListLazy(data.annotatedNode_metadata), _getToken(data.directive_keyword), _readNode(data.uriBasedDirective_uri), _readNodeList(data.namespaceDirective_configurations), _readNodeList(data.namespaceDirective_combinators), _getToken(data.directive_semicolon), ); + LazyDirective.setData(node, data); + return node; } ExpressionFunctionBody _read_expressionFunctionBody(LinkedNode data) { @@ -467,18 +493,20 @@ } FieldDeclaration _read_fieldDeclaration(LinkedNode data) { - return astFactory.fieldDeclaration2( - comment: _readNode(data.annotatedNode_comment), + var node = astFactory.fieldDeclaration2( + comment: _readNodeLazy(data.annotatedNode_comment), covariantKeyword: _getToken(data.fieldDeclaration_covariantKeyword), fieldList: _readNode(data.fieldDeclaration_fields), - metadata: _readNodeList(data.annotatedNode_metadata), + metadata: _readNodeListLazy(data.annotatedNode_metadata), semicolon: _getToken(data.fieldDeclaration_semicolon), staticKeyword: _getToken(data.fieldDeclaration_staticKeyword), ); + LazyFieldDeclaration.setData(node, data); + return node; } FieldFormalParameter _read_fieldFormalParameter(LinkedNode data) { - return astFactory.fieldFormalParameter2( + var node = astFactory.fieldFormalParameter2( identifier: _readNode(data.normalFormalParameter_identifier), period: _getToken(data.fieldFormalParameter_period), thisKeyword: _getToken(data.fieldFormalParameter_thisKeyword), @@ -490,6 +518,8 @@ type: _readNode(data.fieldFormalParameter_type), parameters: _readNode(data.fieldFormalParameter_formalParameters), ); + LazyFormalParameter.setData(node, data); + return node; } ForEachPartsWithDeclaration _read_forEachPartsWithDeclaration( @@ -562,15 +592,17 @@ } FunctionDeclaration _read_functionDeclaration(LinkedNode data) { - return astFactory.functionDeclaration( - _readNode(data.annotatedNode_comment), - _readNodeList(data.annotatedNode_metadata), + var node = astFactory.functionDeclaration( + _readNodeLazy(data.annotatedNode_comment), + _readNodeListLazy(data.annotatedNode_metadata), _getToken(data.functionDeclaration_externalKeyword), - _readNode(data.functionDeclaration_returnType), + _readNodeLazy(data.functionDeclaration_returnType), _getToken(data.functionDeclaration_propertyKeyword), _readNode(data.namedCompilationUnitMember_name), - _readNode(data.functionDeclaration_functionExpression), + _readNodeLazy(data.functionDeclaration_functionExpression), ); + LazyFunctionDeclaration.setData(node, data); + return node; } FunctionDeclarationStatement _read_functionDeclarationStatement( @@ -586,31 +618,33 @@ _localParameters = thisLocalParameters; var node = astFactory.functionExpression( - _readNode(data.functionExpression_typeParameters), - _readNode(data.functionExpression_formalParameters), - _readNode(data.functionExpression_body), + _readNodeLazy(data.functionExpression_typeParameters), + _readNodeLazy(data.functionExpression_formalParameters), + _readNodeLazy(data.functionExpression_body), ); _localParameters = prevLocalParameters; if (_localRef != null) { - var element = FunctionElementImpl.forLinkedNode( - _enclosingElement, - _localRef.getChild('${_localRefNextId++}'), - data, - ); - element.parameters = thisLocalParameters; - - var body = node.body; - if (body.isAsynchronous) { - element.asynchronous = true; - } - if (body.isGenerator) { - element.generator = true; - } - - element.type = new FunctionTypeImpl(element); - (node as FunctionExpressionImpl).declaredElement = element; + throw UnimplementedError(); +// var element = FunctionElementImpl.forLinkedNode( +// _enclosingElement, +// _localRef.getChild('${_localRefNextId++}'), +// data, +// ); +// element.parameters = thisLocalParameters; +// +// var body = node.body; +// if (body.isAsynchronous) { +// element.asynchronous = true; +// } +// if (body.isGenerator) { +// element.generator = true; +// } +// +// element.type = new FunctionTypeImpl(element); +// (node as FunctionExpressionImpl).declaredElement = element; } + LazyFunctionExpression.setData(node, data); return node; } @@ -624,16 +658,18 @@ } FunctionTypeAlias _read_functionTypeAlias(LinkedNode data) { - return astFactory.functionTypeAlias( - _readNode(data.annotatedNode_comment), - _readNodeList(data.annotatedNode_metadata), + var node = astFactory.functionTypeAlias( + _readNodeLazy(data.annotatedNode_comment), + _readNodeListLazy(data.annotatedNode_metadata), _getToken(data.typeAlias_typedefKeyword), - _readNode(data.functionTypeAlias_returnType), + _readNodeLazy(data.functionTypeAlias_returnType), _readNode(data.namedCompilationUnitMember_name), - _readNode(data.functionTypeAlias_typeParameters), - _readNode(data.functionTypeAlias_formalParameters), + _readNodeLazy(data.functionTypeAlias_typeParameters), + _readNodeLazy(data.functionTypeAlias_formalParameters), _getToken(data.typeAlias_semicolon), ); + LazyFunctionTypeAlias.setData(node, data); + return node; } FunctionTypedFormalParameter _read_functionTypedFormalParameter( @@ -650,40 +686,47 @@ ); if (_localRef != null) { - var name = node.identifier.name; - var element = ParameterElementImpl.forLinkedNodeFactory( - _enclosingElement, - _localRef.getChild('${_localRefNextId++}').getChild(name), - data, - ); - _localParameters.add(element); - node.identifier.staticElement = element; + throw UnimplementedError(); +// var name = node.identifier.name; +// var element = ParameterElementImpl.forLinkedNodeFactory( +// _enclosingElement, +// _localRef.getChild('${_localRefNextId++}').getChild(name), +// data, +// ); +// _localParameters.add(element); +// node.identifier.staticElement = element; } + LazyFormalParameter.setData(node, data); return node; } GenericFunctionType _read_genericFunctionType(LinkedNode data) { - return astFactory.genericFunctionType( - _readNode(data.genericFunctionType_returnType), + GenericFunctionTypeImpl node = astFactory.genericFunctionType( + _readNodeLazy(data.genericFunctionType_returnType), _getToken(data.genericFunctionType_functionKeyword), - _readNode(data.genericFunctionType_typeParameters), - _readNode(data.genericFunctionType_formalParameters), + _readNodeLazy(data.genericFunctionType_typeParameters), + _readNodeLazy(data.genericFunctionType_formalParameters), question: _getToken(data.genericFunctionType_question), ); + node.type = _readType(data.genericFunctionType_type); + LazyGenericFunctionType.setData(node, data); + return node; } GenericTypeAlias _read_genericTypeAlias(LinkedNode data) { - return astFactory.genericTypeAlias( - _readNode(data.annotatedNode_comment), + var node = astFactory.genericTypeAlias( + _readNodeLazy(data.annotatedNode_comment), _readNodeList(data.annotatedNode_metadata), _getToken(data.typeAlias_typedefKeyword), _readNode(data.namedCompilationUnitMember_name), - _readNode(data.genericTypeAlias_typeParameters), + _readNodeLazy(data.genericTypeAlias_typeParameters), _getToken(data.genericTypeAlias_equals), - _readNode(data.genericTypeAlias_functionType), + _readNodeLazy(data.genericTypeAlias_functionType), _getToken(data.typeAlias_semicolon), ); + LazyGenericTypeAlias.setData(node, data); + return node; } HideCombinator _read_hideCombinator(LinkedNode data) { @@ -725,9 +768,9 @@ } ImportDirective _read_importDirective(LinkedNode data) { - return astFactory.importDirective( + var node = astFactory.importDirective( _readNode(data.annotatedNode_comment), - _readNodeList(data.annotatedNode_metadata), + _readNodeListLazy(data.annotatedNode_metadata), _getToken(data.directive_keyword), _readNode(data.uriBasedDirective_uri), _readNodeList(data.namespaceDirective_configurations), @@ -737,6 +780,8 @@ _readNodeList(data.namespaceDirective_combinators), _getToken(data.directive_semicolon), ); + LazyDirective.setData(node, data); + return node; } IndexExpression _read_indexExpression(LinkedNode data) { @@ -806,13 +851,15 @@ } LibraryDirective _read_libraryDirective(LinkedNode data) { - return astFactory.libraryDirective( + var node = astFactory.libraryDirective( _readNode(data.annotatedNode_comment), - _readNodeList(data.annotatedNode_metadata), + _readNodeListLazy(data.annotatedNode_metadata), _getToken(data.directive_keyword), _readNode(data.libraryDirective_name), _getToken(data.directive_semicolon), ); + LazyDirective.setData(node, data); + return node; } LibraryIdentifier _read_libraryIdentifier(LinkedNode data) { @@ -840,19 +887,21 @@ } MethodDeclaration _read_methodDeclaration(LinkedNode data) { - return astFactory.methodDeclaration( - _readNode(data.annotatedNode_comment), - _readNodeList(data.annotatedNode_metadata), + var node = astFactory.methodDeclaration( + _readNodeLazy(data.annotatedNode_comment), + _readNodeListLazy(data.annotatedNode_metadata), _getToken(data.methodDeclaration_externalKeyword), _getToken(data.methodDeclaration_modifierKeyword), - _readNode(data.methodDeclaration_returnType), + _readNodeLazy(data.methodDeclaration_returnType), _getToken(data.methodDeclaration_propertyKeyword), _getToken(data.methodDeclaration_operatorKeyword), _readNode(data.methodDeclaration_name), - _readNode(data.methodDeclaration_typeParameters), - _readNode(data.methodDeclaration_formalParameters), - _readNode(data.methodDeclaration_body), + _readNodeLazy(data.methodDeclaration_typeParameters), + _readNodeLazy(data.methodDeclaration_formalParameters), + _readNodeLazy(data.methodDeclaration_body), ); + LazyMethodDeclaration.setData(node, data); + return node; } MethodInvocation _read_methodInvocation(LinkedNode data) { @@ -866,18 +915,20 @@ } MixinDeclaration _read_mixinDeclaration(LinkedNode data) { - return astFactory.mixinDeclaration( - _readNode(data.annotatedNode_comment), + var node = astFactory.mixinDeclaration( + _readNodeLazy(data.annotatedNode_comment), _readNodeList(data.annotatedNode_metadata), _getToken(data.mixinDeclaration_mixinKeyword), _readNode(data.namedCompilationUnitMember_name), - _readNode(data.classOrMixinDeclaration_typeParameters), - _readNode(data.mixinDeclaration_onClause), - _readNode(data.classOrMixinDeclaration_implementsClause), + _readNodeLazy(data.classOrMixinDeclaration_typeParameters), + _readNodeLazy(data.mixinDeclaration_onClause), + _readNodeLazy(data.classOrMixinDeclaration_implementsClause), _getToken(data.classOrMixinDeclaration_leftBracket), - _readNodeList(data.classOrMixinDeclaration_members), + _readNodeListLazy(data.classOrMixinDeclaration_members), _getToken(data.classOrMixinDeclaration_rightBracket), ); + LazyMixinDeclaration.setData(node, data); + return node; } NamedExpression _read_namedExpression(LinkedNode data) { @@ -924,17 +975,19 @@ } PartDirective _read_partDirective(LinkedNode data) { - return astFactory.partDirective( + var node = astFactory.partDirective( _readNode(data.annotatedNode_comment), - _readNodeList(data.annotatedNode_metadata), + _readNodeListLazy(data.annotatedNode_metadata), _getToken(data.directive_keyword), _readNode(data.uriBasedDirective_uri), _getToken(data.directive_semicolon), ); + LazyDirective.setData(node, data); + return node; } PartOfDirective _read_partOfDirective(LinkedNode data) { - return astFactory.partOfDirective( + var node = astFactory.partOfDirective( _readNode(data.annotatedNode_comment), _readNodeList(data.annotatedNode_metadata), _getToken(data.directive_keyword), @@ -943,6 +996,8 @@ _readNode(data.partOfDirective_libraryName), _getToken(data.directive_semicolon), ); + LazyDirective.setData(node, data); + return node; } PostfixExpression _read_postfixExpression(LinkedNode data) { @@ -1044,17 +1099,19 @@ ); if (_localRef != null) { - var name = node.identifier.name; - var element = ParameterElementImpl.forLinkedNodeFactory( - _enclosingElement, - _localRef.getChild('${_localRefNextId++}').getChild(name), - data, - ); - _localParameters.add(element); - node.identifier.staticElement = element; - node.declaredElement = element; + throw UnimplementedError(); +// var name = node.identifier.name; +// var element = ParameterElementImpl.forLinkedNodeFactory( +// _enclosingElement, +// _localRef.getChild('${_localRefNextId++}').getChild(name), +// data, +// ); +// _localParameters.add(element); +// node.identifier.staticElement = element; +// node.declaredElement = element; } + LazyFormalParameter.setData(node, data); return node; } @@ -1154,12 +1211,14 @@ TopLevelVariableDeclaration _read_topLevelVariableDeclaration( LinkedNode data) { - return astFactory.topLevelVariableDeclaration( - _readNode(data.annotatedNode_comment), - _readNodeList(data.annotatedNode_metadata), + var node = astFactory.topLevelVariableDeclaration( + _readNodeLazy(data.annotatedNode_comment), + _readNodeListLazy(data.annotatedNode_metadata), _readNode(data.topLevelVariableDeclaration_variableList), _getToken(data.topLevelVariableDeclaration_semicolon), ); + LazyTopLevelVariableDeclaration.setData(node, data); + return node; } TryStatement _read_tryStatement(LinkedNode data) { @@ -1189,13 +1248,15 @@ } TypeParameter _read_typeParameter(LinkedNode data) { - return astFactory.typeParameter( - _readNode(data.annotatedNode_comment), - _readNodeList(data.annotatedNode_metadata), + var node = astFactory.typeParameter( + _readNodeLazy(data.annotatedNode_comment), + _readNodeListLazy(data.annotatedNode_metadata), _readNode(data.typeParameter_name), _getToken(data.typeParameter_extendsKeyword), - _readNode(data.typeParameter_bound), + _readNodeLazy(data.typeParameter_bound), ); + LazyTypeParameter.setData(node, data); + return node; } TypeParameterList _read_typeParameterList(LinkedNode data) { @@ -1207,19 +1268,21 @@ } VariableDeclaration _read_variableDeclaration(LinkedNode data) { - return astFactory.variableDeclaration( + var node = astFactory.variableDeclaration( _readNode(data.variableDeclaration_name), _getToken(data.variableDeclaration_equals), - _readNode(data.variableDeclaration_initializer), + _readNodeLazy(data.variableDeclaration_initializer), ); + LazyVariableDeclaration.setData(node, data); + return node; } VariableDeclarationList _read_variableDeclarationList(LinkedNode data) { return astFactory.variableDeclarationList( - _readNode(data.annotatedNode_comment), - _readNodeList(data.annotatedNode_metadata), + _readNodeLazy(data.annotatedNode_comment), + _readNodeListLazy(data.annotatedNode_metadata), _getToken(data.variableDeclarationList_keyword), - _readNode(data.variableDeclarationList_type), + _readNodeLazy(data.variableDeclarationList_type), _readNodeList(data.variableDeclarationList_variables), ); } @@ -1503,6 +1566,11 @@ } } + AstNode _readNodeLazy(LinkedNode data) { + if (isLazy) return null; + return _readNode(data); + } + List<T> _readNodeList<T>(List<LinkedNode> nodeList) { var result = List<T>.filled(nodeList.length, null); for (var i = 0; i < nodeList.length; ++i) { @@ -1512,6 +1580,13 @@ return result; } + List<T> _readNodeListLazy<T>(List<LinkedNode> nodeList) { + if (isLazy) { + return List<T>.filled(nodeList.length, null); + } + return _readNodeList(nodeList); + } + DartType _readType(LinkedNodeType data) { if (data == null) return null;
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart index 634e7da..0766c24 100644 --- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart +++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -12,6 +12,7 @@ import 'package:analyzer/src/dart/element/member.dart'; import 'package:analyzer/src/summary/format.dart'; import 'package:analyzer/src/summary/idl.dart'; +import 'package:analyzer/src/summary2/lazy_ast.dart'; import 'package:analyzer/src/summary2/linking_bundle_context.dart'; import 'package:analyzer/src/summary2/tokens_context.dart'; @@ -555,6 +556,7 @@ functionDeclaration_returnType: node.returnType?.accept(this), ); _storeNamedCompilationUnitMember(builder, node); + _writeActualReturnType(builder, node); return builder; } @@ -594,6 +596,7 @@ functionTypeAlias_typeParameters: node.typeParameters?.accept(this), ); _storeTypeAlias(builder, node); + _writeActualReturnType(builder, node); return builder; } @@ -613,13 +616,16 @@ @override LinkedNodeBuilder visitGenericFunctionType(GenericFunctionType node) { - return LinkedNodeBuilder.genericFunctionType( + var builder = LinkedNodeBuilder.genericFunctionType( genericFunctionType_formalParameters: node.parameters.accept(this), genericFunctionType_functionKeyword: _getToken(node.functionKeyword), genericFunctionType_question: _getToken(node.question), genericFunctionType_returnType: node.returnType?.accept(this), + genericFunctionType_type: _writeType(node.type), genericFunctionType_typeParameters: node.typeParameters?.accept(this), ); + _writeActualReturnType(builder, node); + return builder; } @override @@ -710,6 +716,7 @@ instanceCreationExpression_keyword: _getToken(node.keyword), instanceCreationExpression_typeArguments: nodeImpl.typeArguments?.accept(this), + expression_type: _writeType(node.staticType), ); } @@ -819,6 +826,7 @@ ); _storeClassMember(builder, node); _storeCodeOffsetLength(builder, node); + _writeActualReturnType(builder, node); return builder; } @@ -1228,12 +1236,14 @@ @override LinkedNodeBuilder visitVariableDeclaration(VariableDeclaration node) { - return LinkedNodeBuilder.variableDeclaration( + var builder = LinkedNodeBuilder.variableDeclaration( variableDeclaration_equals: _getToken(node.equals), variableDeclaration_initializer: node.initializer?.accept(this), variableDeclaration_name: node.name.accept(this), variableDeclaration_declaration: _variablesDeclaration, ); + _writeActualType(builder, node); + return builder; } @override @@ -1409,6 +1419,7 @@ builder.formalParameter_kind = kind; _storeCodeOffsetLength(builder, node); + _writeActualType(builder, node); } void _storeForMixin(LinkedNodeBuilder builder, ForMixin node) { @@ -1509,6 +1520,18 @@ ..uriBasedDirective_uriElement = _getReferenceIndex(node.uriElement); } + void _writeActualReturnType(LinkedNodeBuilder builder, AstNode node) { + var type = LazyAst.getReturnType(node); + // TODO(scheglov) Check for `null` when writing resolved AST. + builder.actualReturnType = _writeType(type); + } + + void _writeActualType(LinkedNodeBuilder builder, AstNode node) { + var type = LazyAst.getType(node); + // TODO(scheglov) Check for `null` when writing resolved AST. + builder.actualType = _writeType(type); + } + List<LinkedNodeBuilder> _writeNodeList(List<AstNode> nodeList) { var result = List<LinkedNodeBuilder>.filled( nodeList.length,
diff --git a/pkg/analyzer/lib/src/summary2/ast_resolver.dart b/pkg/analyzer/lib/src/summary2/ast_resolver.dart index 09f12b4..ab43e11 100644 --- a/pkg/analyzer/lib/src/summary2/ast_resolver.dart +++ b/pkg/analyzer/lib/src/summary2/ast_resolver.dart
@@ -7,10 +7,7 @@ import 'package:analyzer/error/listener.dart'; import 'package:analyzer/src/generated/resolver.dart'; import 'package:analyzer/src/generated/source.dart'; -import 'package:analyzer/src/summary/idl.dart'; -import 'package:analyzer/src/summary2/ast_binary_writer.dart'; import 'package:analyzer/src/summary2/link.dart'; -import 'package:analyzer/src/summary2/linked_unit_context.dart'; /// Used to resolve some AST nodes - variable initializers, and annotations. class AstResolver { @@ -20,8 +17,7 @@ AstResolver(this._linker, this._library, this._nameScope); - LinkedNode resolve( - LinkedUnitContext context, + void resolve( AstNode node, { ClassElement enclosingClassElement, ExecutableElement enclosingExecutableElement, @@ -51,12 +47,6 @@ ); node.accept(resolverVisitor); - - var writer = AstBinaryWriter( - _linker.linkingBundleContext, - context.tokensContext, - ); - return writer.writeNode(node); } }
diff --git a/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart b/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart index 6c2acdc..be3a93a 100644 --- a/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart +++ b/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
@@ -3,69 +3,62 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/dart/ast/ast.dart' as ast; +import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/src/dart/resolver/scope.dart' show LibraryScope; import 'package:analyzer/src/generated/source.dart'; import 'package:analyzer/src/generated/utilities_dart.dart'; import 'package:analyzer/src/summary/format.dart'; import 'package:analyzer/src/summary/idl.dart'; -import 'package:analyzer/src/summary2/ast_binary_writer.dart'; import 'package:analyzer/src/summary2/combinator.dart'; import 'package:analyzer/src/summary2/constructor_initializer_resolver.dart'; +import 'package:analyzer/src/summary2/default_value_resolver.dart'; import 'package:analyzer/src/summary2/export.dart'; import 'package:analyzer/src/summary2/link.dart'; +import 'package:analyzer/src/summary2/linked_bundle_context.dart'; import 'package:analyzer/src/summary2/linked_unit_context.dart'; import 'package:analyzer/src/summary2/metadata_resolver.dart'; import 'package:analyzer/src/summary2/reference.dart'; import 'package:analyzer/src/summary2/reference_resolver.dart'; import 'package:analyzer/src/summary2/scope.dart'; -import 'package:analyzer/src/summary2/tokens_writer.dart'; import 'package:analyzer/src/summary2/top_level_inference.dart'; +import 'package:analyzer/src/summary2/type_builder.dart'; class SourceLibraryBuilder { final Linker linker; final Uri uri; final Reference reference; final LinkedNodeLibraryBuilder node; - final List<UnitBuilder> units = []; - /// The import scope of the library. - final Scope importScope; + LinkedLibraryContext context; - /// Local declarations, enclosed by [importScope]. - final Scope scope; + LibraryElement element; + LibraryScope libraryScope; + + /// Local declarations. + final Scope localScope = Scope.top(); /// The export scope of the library. final Scope exportScope = Scope.top(); final List<Export> exporters = []; - SourceLibraryBuilder(Linker linker, Uri uri, Reference reference, - LinkedNodeLibraryBuilder node) - : this._(linker, uri, reference, node, Scope.top()); - - SourceLibraryBuilder._( - this.linker, this.uri, this.reference, this.node, this.importScope) - : scope = Scope(importScope, <String, Reference>{}); + SourceLibraryBuilder(this.linker, this.uri, this.reference, this.node); void addExporters() { - var unitContext = units[0].context; - for (var directive in units[0].node.compilationUnit_directives) { - if (directive.kind == LinkedNodeKind.exportDirective) { - var relativeUriStr = unitContext.getStringContent( - directive.uriBasedDirective_uri, - ); + var unitContext = context.units[0]; + for (var directive in unitContext.unit_withDirectives.directives) { + if (directive is ast.ExportDirective) { + var relativeUriStr = directive.uri.stringValue; var relativeUri = Uri.parse(relativeUriStr); var uri = resolveRelativeUri(this.uri, relativeUri); var exported = linker.builders[uri]; if (exported != null) { - var combinatorNodeList = directive.namespaceDirective_combinators; - var combinators = combinatorNodeList.map((node) { - if (node.kind == LinkedNodeKind.showCombinator) { - var nodeList = node.showCombinator_shownNames; - var nameList = unitContext.getSimpleNameList(nodeList); + var combinators = directive.combinators.map((node) { + if (node is ast.ShowCombinator) { + var nameList = node.shownNames.map((i) => i.name).toList(); return Combinator.show(nameList); - } else { - var nodeList = node.hideCombinator_hiddenNames; - var nameList = unitContext.getSimpleNameList(nodeList); + } else if (node is ast.HideCombinator) { + var nameList = node.hiddenNames.map((i) => i.name).toList(); return Combinator.hide(nameList); } }).toList(); @@ -76,64 +69,10 @@ } } - void addImportsToScope() { - var hasDartCore = false; - var unitContext = units[0].context; - for (var directive in units[0].node.compilationUnit_directives) { - if (directive.kind == LinkedNodeKind.importDirective) { - var relativeUriStr = unitContext.getStringContent( - directive.uriBasedDirective_uri, - ); - var relativeUri = Uri.parse(relativeUriStr); - var uri = resolveRelativeUri(this.uri, relativeUri); - var builder = linker.builders[uri]; - - Scope targetScope = importScope; - - var prefixNode = directive.importDirective_prefix; - if (prefixNode != null) { - var prefixName = unitContext.getSimpleName(prefixNode); - var prefixContainer = reference.getChild('@prefix'); - var prefixReference = prefixContainer[prefixName]; - - if (prefixReference == null) { - prefixReference = prefixContainer.getChild(prefixName); - prefixReference.prefixScope = Scope.top(); - importScope.declare(prefixName, prefixReference); - } - - targetScope = prefixReference.prefixScope; - } - - if (builder != null) { - builder.exportScope.forEach((name, reference) { - targetScope.declare(name, reference); - }); - } else { - var references = linker.elementFactory.exportsOfLibrary('$uri'); - _declareReferences(targetScope, references); - } - // TODO(scheglov) combinators - } - } - if (!hasDartCore) { - var importDartCore = LinkedNodeBuilder.importDirective( - uriBasedDirective_uri: LinkedNodeBuilder.simpleStringLiteral( - simpleStringLiteral_value: 'dart:core', - ), - )..isSynthetic = true; - units[0].node.compilationUnit_directives.add(importDartCore); - - // TODO(scheglov) This works only when dart:core is linked - var references = linker.elementFactory.exportsOfLibrary('dart:core'); - _declareReferences(importScope, references); - } - } - /// Add top-level declaration of the library units to the local scope. void addLocalDeclarations() { - for (var unit in units) { - var unitRef = reference.getChild('@unit').getChild('${unit.uri}'); + for (var unitContext in context.units) { + var unitRef = reference.getChild('@unit').getChild(unitContext.uriStr); var classRef = unitRef.getChild('@class'); var enumRef = unitRef.getChild('@enum'); var functionRef = unitRef.getChild('@function'); @@ -141,77 +80,155 @@ var getterRef = unitRef.getChild('@getter'); var setterRef = unitRef.getChild('@setter'); var variableRef = unitRef.getChild('@variable'); - for (var node in unit.node.compilationUnit_declarations) { - if (node.kind == LinkedNodeKind.classDeclaration || - node.kind == LinkedNodeKind.classTypeAlias || - node.kind == LinkedNodeKind.mixinDeclaration) { - var name = unit.context.getUnitMemberName(node); + for (var node in unitContext.unit.declarations) { + if (node is ast.ClassDeclaration) { + var name = node.name.name; var reference = classRef.getChild(name); - reference.node = node; - scope.declare(name, reference); - } else if (node.kind == LinkedNodeKind.enumDeclaration) { - var name = unit.context.getUnitMemberName(node); + reference.node2 = node; + localScope.declare(name, reference); + } else if (node is ast.ClassTypeAlias) { + var name = node.name.name; + var reference = classRef.getChild(name); + reference.node2 = node; + localScope.declare(name, reference); + } else if (node is ast.EnumDeclaration) { + var name = node.name.name; var reference = enumRef.getChild(name); - reference.node = node; - scope.declare(name, reference); - } else if (node.kind == LinkedNodeKind.functionDeclaration) { - var name = unit.context.getUnitMemberName(node); + reference.node2 = node; + localScope.declare(name, reference); + } else if (node is ast.FunctionDeclaration) { + var name = node.name.name; Reference containerRef; - if (unit.context.isGetterFunction(node)) { + if (node.isGetter) { containerRef = getterRef; - } else if (unit.context.isSetterFunction(node)) { + } else if (node.isSetter) { containerRef = setterRef; } else { containerRef = functionRef; } var reference = containerRef.getChild(name); - reference.node = node; - - scope.declare(name, reference); - } else if (node.kind == LinkedNodeKind.functionTypeAlias) { - var name = unit.context.getUnitMemberName(node); + reference.node2 = node; + localScope.declare(name, reference); + } else if (node is ast.FunctionTypeAlias) { + var name = node.name.name; var reference = typeAliasRef.getChild(name); - reference.node = node; + reference.node2 = node; - scope.declare(name, reference); - } else if (node.kind == LinkedNodeKind.genericTypeAlias) { - var name = unit.context.getUnitMemberName(node); + localScope.declare(name, reference); + } else if (node is ast.GenericTypeAlias) { + var name = node.name.name; var reference = typeAliasRef.getChild(name); - reference.node = node; + reference.node2 = node; - scope.declare(name, reference); - } else if (node.kind == LinkedNodeKind.topLevelVariableDeclaration) { - var variableList = node.topLevelVariableDeclaration_variableList; - for (var variable in variableList.variableDeclarationList_variables) { - var name = unit.context.getVariableName(variable); + localScope.declare(name, reference); + } else if (node is ast.MixinDeclaration) { + var name = node.name.name; + var reference = classRef.getChild(name); + reference.node2 = node; + localScope.declare(name, reference); + } else if (node is ast.TopLevelVariableDeclaration) { + for (var variable in node.variables.variables) { + var name = variable.name.name; var reference = variableRef.getChild(name); - reference.node = node; + reference.node2 = node; var getter = getterRef.getChild(name); - scope.declare(name, getter); + localScope.declare(name, getter); - if (!unit.context.isConst(variable) && - !unit.context.isFinal(variable)) { + if (!variable.isConst && !variable.isFinal) { var setter = setterRef.getChild(name); - scope.declare('$name=', setter); + localScope.declare('$name=', setter); } } } else { // TODO(scheglov) implement - throw UnimplementedError('${node.kind}'); + throw UnimplementedError('${node.runtimeType}'); } } } +// for (var unit in units) { +// var unitRef = reference.getChild('@unit').getChild('${unit.uri}'); +// var classRef = unitRef.getChild('@class'); +// var enumRef = unitRef.getChild('@enum'); +// var functionRef = unitRef.getChild('@function'); +// var typeAliasRef = unitRef.getChild('@typeAlias'); +// var getterRef = unitRef.getChild('@getter'); +// var setterRef = unitRef.getChild('@setter'); +// var variableRef = unitRef.getChild('@variable'); +// for (var node in unit.node.compilationUnit_declarations) { +// if (node.kind == LinkedNodeKind.classDeclaration || +// node.kind == LinkedNodeKind.classTypeAlias || +// node.kind == LinkedNodeKind.mixinDeclaration) { +// var name = unit.context.getUnitMemberName(node); +// var reference = classRef.getChild(name); +// reference.node = node; +// scope.declare(name, reference); +// } else if (node.kind == LinkedNodeKind.enumDeclaration) { +// var name = unit.context.getUnitMemberName(node); +// var reference = enumRef.getChild(name); +// reference.node = node; +// scope.declare(name, reference); +// } else if (node.kind == LinkedNodeKind.functionDeclaration) { +// var name = unit.context.getUnitMemberName(node); +// +// Reference containerRef; +// if (unit.context.isGetterFunction(node)) { +// containerRef = getterRef; +// } else if (unit.context.isSetterFunction(node)) { +// containerRef = setterRef; +// } else { +// containerRef = functionRef; +// } +// +// var reference = containerRef.getChild(name); +// reference.node = node; +// +// scope.declare(name, reference); +// } else if (node.kind == LinkedNodeKind.functionTypeAlias) { +// var name = unit.context.getUnitMemberName(node); +// var reference = typeAliasRef.getChild(name); +// reference.node = node; +// +// scope.declare(name, reference); +// } else if (node.kind == LinkedNodeKind.genericTypeAlias) { +// var name = unit.context.getUnitMemberName(node); +// var reference = typeAliasRef.getChild(name); +// reference.node = node; +// +// scope.declare(name, reference); +// } else if (node.kind == LinkedNodeKind.topLevelVariableDeclaration) { +// var variableList = node.topLevelVariableDeclaration_variableList; +// for (var variable in variableList.variableDeclarationList_variables) { +// var name = unit.context.getVariableName(variable); +// +// var reference = variableRef.getChild(name); +// reference.node = node; +// +// var getter = getterRef.getChild(name); +// scope.declare(name, getter); +// +// if (!unit.context.isConst(variable) && +// !unit.context.isFinal(variable)) { +// var setter = setterRef.getChild(name); +// scope.declare('$name=', setter); +// } +// } +// } else { +// // TODO(scheglov) implement +// throw UnimplementedError('${node.kind}'); +// } +// } +// } if ('$uri' == 'dart:core') { - scope.declare('dynamic', reference.getChild('dynamic')); + localScope.declare('dynamic', reference.getChild('dynamic')); } } void addSyntheticConstructors() { - for (var reference in scope.map.values) { + for (var reference in localScope.map.values) { var node = reference.node; if (node == null) continue; if (node.kind != LinkedNodeKind.classDeclaration) continue; @@ -247,8 +264,13 @@ return true; } + void buildElement() { + element = linker.elementFactory.libraryOfUri('$uri'); + libraryScope = LibraryScope(element); + } + void buildInitialExportScope() { - scope.forEach((name, reference) { + localScope.forEach((name, reference) { addToExportScope(name, reference); }); } @@ -261,23 +283,29 @@ ConstructorInitializerResolver(linker, reference).resolve(); } + void resolveDefaultValues() { + DefaultValueResolver(linker, reference).resolve(); + } + void resolveMetadata() { - var metadataResolver = MetadataResolver(linker, reference); - for (var unit in units) { - metadataResolver.resolve(unit); + var metadataResolver = MetadataResolver(linker, element); + for (var unitContext in context.units) { + unitContext.unit.accept(metadataResolver); } } - void resolveTypes(TypesToBuild typesToBuild) { - for (var unit in units) { - var unitReference = reference.getChild('@unit').getChild('${unit.uri}'); - ReferenceResolver( - linker.linkingBundleContext, - typesToBuild, - unit, - scope, + void resolveTypes(NodesToBuildType nodesToBuildType) { + for (var unitContext in context.units) { + var unitRef = reference.getChild('@unit'); + var unitReference = unitRef.getChild(unitContext.uriStr); + var resolver = ReferenceResolver( + nodesToBuildType, + linker.elementFactory, + element, unitReference, - ).resolve(); + libraryScope, + ); + unitContext.unit.accept(resolver); } } @@ -306,50 +334,31 @@ libraryReference, libraryNode, ); + linker.builders[builder.uri] = builder; + var unitMap = <String, ast.CompilationUnit>{}; ast.CompilationUnit definingUnit; for (var unitSource in libraryUnits.keys) { var unit = libraryUnits[unitSource]; definingUnit ??= unit; - - var tokensResult = TokensWriter().writeTokens( - unit.beginToken, - unit.endToken, - ); - var tokensContext = tokensResult.toContext(); - - var unitContext = LinkedUnitContext( - linker.bundleContext, - tokensContext, - ); - - var writer = AstBinaryWriter(linker.linkingBundleContext, tokensContext); - var unitNode = writer.writeNode(unit); - - builder.units.add( - UnitBuilder(unitSource.uri, unitContext, unitNode), - ); - - libraryNode.units.add( - LinkedNodeUnitBuilder( - uriStr: '${unitSource.uri}', - tokens: tokensResult.tokens, - node: unitNode, - ), - ); - - if (libraryUriStr == 'dart:core') { - for (var declaration in unitNode.compilationUnit_declarations) { - if (declaration.kind == LinkedNodeKind.classDeclaration) { - var nameNode = declaration.namedCompilationUnitMember_name; - if (unitContext.getSimpleName(nameNode) == 'Object') { - declaration.classDeclaration_isDartObject = true; - } - } - } - } + unitMap['${unitSource.uri}'] = unit; } + builder.context = linker.bundleContext + .addLinkingLibrary(libraryUriStr, libraryNode, unitMap); + +// if (libraryUriStr == 'dart:core') { +// for (var declaration in unitNode.compilationUnit_declarations) { +// if (declaration.kind == LinkedNodeKind.classDeclaration) { +// var nameNode = declaration.namedCompilationUnitMember_name; +// if (unitContext.getSimpleName(nameNode) == 'Object') { +// declaration.classDeclaration_isDartObject = true; +// } +// } +// } +// } +// } + for (var directive in definingUnit.directives) { if (directive is ast.LibraryDirective) { var name = directive.name; @@ -359,16 +368,6 @@ break; } } - - linker.linkingLibraries.add(libraryNode); - linker.builders[builder.uri] = builder; - } - - static void _declareReferences(Scope target, List<Reference> references) { - for (var reference in references) { - var name = reference.name; - target.declare(name, reference); - } } }
diff --git a/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart b/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart index 9c7fc99..a0cc02e 100644 --- a/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart +++ b/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart
@@ -6,8 +6,6 @@ import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/resolver/scope.dart'; import 'package:analyzer/src/summary/format.dart'; -import 'package:analyzer/src/summary/idl.dart'; -import 'package:analyzer/src/summary2/ast_binary_reader.dart'; import 'package:analyzer/src/summary2/ast_resolver.dart'; import 'package:analyzer/src/summary2/link.dart'; import 'package:analyzer/src/summary2/linked_unit_context.dart'; @@ -46,66 +44,70 @@ void _constructor(ConstructorElementImpl constructorElement) { if (constructorElement.isSynthetic) return; - _constructorElement = constructorElement; - _constructorNode = constructorElement.linkedNode; - - var functionScope = FunctionScope(_classScope, constructorElement); - functionScope.defineParameters(); - - var nameScope = ConstructorInitializerScope( - functionScope, - constructorElement, - ); - - _astResolver = AstResolver(_linker, _libraryElement, nameScope); - - _initializers(); - _redirectedConstructor(); +// _constructorElement = constructorElement; +// _constructorNode = constructorElement.linkedNode; +// +// var functionScope = FunctionScope(_classScope, constructorElement); +// functionScope.defineParameters(); +// +// var nameScope = ConstructorInitializerScope( +// functionScope, +// constructorElement, +// ); +// +// _astResolver = AstResolver(_linker, _libraryElement, nameScope); +// +// _initializers(); +// _redirectedConstructor(); } void _initializers() { - bool isConst = _constructorNode.constructorDeclaration_constKeyword != 0; + throw UnimplementedError(); - var initializers = _constructorNode.constructorDeclaration_initializers; - var resolvedList = List<LinkedNodeBuilder>(); - for (var i = 0; i < initializers.length; ++i) { - var unresolvedNode = initializers[i]; - - // Keep only initializers of constant constructors; or redirects. - if (!isConst && - unresolvedNode.kind != - LinkedNodeKind.redirectingConstructorInvocation) { - continue; - } - - var reader = AstBinaryReader(_linkedContext); - var unresolvedAst = reader.readNode(unresolvedNode); - - var resolvedNode = _astResolver.resolve( - _linkedContext, - unresolvedAst, - enclosingClassElement: _constructorElement.enclosingElement, - enclosingExecutableElement: _constructorElement, - ); - resolvedList.add(resolvedNode); - } - _constructorNode.constructorDeclaration_initializers = resolvedList; +// bool isConst = _constructorNode.constructorDeclaration_constKeyword != 0; +// +// var initializers = _constructorNode.constructorDeclaration_initializers; +// var resolvedList = List<LinkedNodeBuilder>(); +// for (var i = 0; i < initializers.length; ++i) { +// var unresolvedNode = initializers[i]; +// +// // Keep only initializers of constant constructors; or redirects. +// if (!isConst && +// unresolvedNode.kind != +// LinkedNodeKind.redirectingConstructorInvocation) { +// continue; +// } +// +// var reader = AstBinaryReader(_linkedContext); +// var unresolvedAst = reader.readNode(unresolvedNode); +// +// var resolvedNode = _astResolver.resolve( +// _linkedContext, +// unresolvedAst, +// enclosingClassElement: _constructorElement.enclosingElement, +// enclosingExecutableElement: _constructorElement, +// ); +// resolvedList.add(resolvedNode); +// } +// _constructorNode.constructorDeclaration_initializers = resolvedList; } void _redirectedConstructor() { - var redirectedConstructorNode = - _constructorNode.constructorDeclaration_redirectedConstructor; - if (redirectedConstructorNode == null) return; + throw UnimplementedError(); - var reader = AstBinaryReader(_linkedContext); - var unresolvedAst = reader.readNode(redirectedConstructorNode); - var resolvedNode = _astResolver.resolve( - _linkedContext, - unresolvedAst, - enclosingClassElement: _constructorElement.enclosingElement, - enclosingExecutableElement: _constructorElement, - ); - _constructorNode.constructorDeclaration_redirectedConstructor = - resolvedNode; +// var redirectedConstructorNode = +// _constructorNode.constructorDeclaration_redirectedConstructor; +// if (redirectedConstructorNode == null) return; +// +// var reader = AstBinaryReader(_linkedContext); +// var unresolvedAst = reader.readNode(redirectedConstructorNode); +// var resolvedNode = _astResolver.resolve( +// _linkedContext, +// unresolvedAst, +// enclosingClassElement: _constructorElement.enclosingElement, +// enclosingExecutableElement: _constructorElement, +// ); +// _constructorNode.constructorDeclaration_redirectedConstructor = +// resolvedNode; } }
diff --git a/pkg/analyzer/lib/src/summary2/default_value_resolver.dart b/pkg/analyzer/lib/src/summary2/default_value_resolver.dart new file mode 100644 index 0000000..4ee405d --- /dev/null +++ b/pkg/analyzer/lib/src/summary2/default_value_resolver.dart
@@ -0,0 +1,130 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/type.dart'; +import 'package:analyzer/src/dart/element/element.dart'; +import 'package:analyzer/src/dart/element/type_algebra.dart'; +import 'package:analyzer/src/dart/resolver/scope.dart'; +import 'package:analyzer/src/generated/resolver.dart'; +import 'package:analyzer/src/summary2/ast_resolver.dart'; +import 'package:analyzer/src/summary2/link.dart'; +import 'package:analyzer/src/summary2/linked_unit_context.dart'; +import 'package:analyzer/src/summary2/reference.dart'; + +class DefaultValueResolver { + Linker _linker; + LibraryElementImpl _libraryElement; + LinkedUnitContext _linkedContext; + + ClassElement _enclosingClassElement; + ExecutableElement _enclosingExecutableElement; + + Scope _libraryScope; + Scope _classScope; + + AstResolver _astResolver; + + DefaultValueResolver(this._linker, Reference libraryRef) { + _libraryElement = _linker.elementFactory.elementOfReference(libraryRef); + _libraryScope = LibraryScope(_libraryElement); + } + + void resolve() { + for (CompilationUnitElementImpl unit in _libraryElement.units) { + _linkedContext = unit.linkedContext; + + for (var classElement in unit.types) { + _enclosingClassElement = classElement; + _classScope = TypeParameterScope(_libraryScope, classElement); + + for (var element in classElement.constructors) { + _constructor(element); + } + + for (var element in classElement.methods) { + _method(element); + } + + _enclosingClassElement = null; + _classScope = null; + } + + for (var element in unit.functions) { + _function(element); + } + } + } + + void _constructor(ConstructorElementImpl element) { + if (element.isSynthetic) return; + + _astResolver = null; + _enclosingExecutableElement = element; + + _parameters(element.parameters); + } + + void _function(FunctionElementImpl element) { + _astResolver = null; + _enclosingExecutableElement = element; + + _parameters(element.parameters); + } + + void _method(MethodElementImpl element) { + _astResolver = null; + _enclosingExecutableElement = element; + + _parameters(element.parameters); + } + + void _parameter(ParameterElementImpl parameter) { + if (parameter.isNotOptional) return; + +// LinkedNodeBuilder node = parameter.linkedNode; +// var unresolvedNode = node.defaultFormalParameter_defaultValue; +// if (unresolvedNode == null) return; +// +// var reader = AstBinaryReader(_linkedContext); +// var unresolvedAst = reader.readNode(unresolvedNode); +// +// if (_astResolver == null) { +// var scope = FunctionScope( +// _classScope ?? _libraryScope, +// _enclosingExecutableElement, +// ); +// _astResolver = AstResolver(_linker, _libraryElement, scope); +// } +// +// var contextType = TypeVariableEliminator(_linker.typeProvider) +// .substituteType(parameter.type); +// InferenceContext.setType(unresolvedAst, contextType); +// +// var resolvedNode = _astResolver.resolve( +// _linkedContext, +// unresolvedAst, +// enclosingClassElement: _enclosingClassElement, +// enclosingExecutableElement: _enclosingExecutableElement, +// ); +// node.defaultFormalParameter_defaultValue = resolvedNode; + } + + void _parameters(List<ParameterElement> parameters) { + for (var parameter in parameters) { + _parameter(parameter); + } + } +} + +class TypeVariableEliminator extends Substitution { + final TypeProvider _typeProvider; + + TypeVariableEliminator(this._typeProvider); + + @override + DartType getSubstitute(TypeParameterElement parameter, bool upperBound) { + return upperBound ? _typeProvider.nullType : _typeProvider.objectType; + } +}
diff --git a/pkg/analyzer/lib/src/summary2/lazy_ast.dart b/pkg/analyzer/lib/src/summary2/lazy_ast.dart new file mode 100644 index 0000000..d4f01c5 --- /dev/null +++ b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
@@ -0,0 +1,1234 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer/dart/element/type.dart'; +import 'package:analyzer/src/dart/ast/ast.dart'; +import 'package:analyzer/src/summary/idl.dart'; +import 'package:analyzer/src/summary2/ast_binary_reader.dart'; + +/// Accessor for reading AST lazily, or read data that is stored in IDL, but +/// cannot be stored in AST, like inferred types. +class LazyAst { + static const _returnTypeKey = 'lazyAst_returnType'; + static const _typeKey = 'lazyAst_type'; + + final LinkedNode data; + + LazyAst(this.data); + + static DartType getReturnType(AstNode node) { + return node.getProperty(_returnTypeKey); + } + + static DartType getType(AstNode node) { + return node.getProperty(_typeKey); + } + + static void setReturnType(AstNode node, DartType type) { + node.setProperty(_returnTypeKey, type); + } + + static void setType(AstNode node, DartType type) { + node.setProperty(_typeKey, type); + } +} + +class LazyClassDeclaration { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasDocumentationComment = false; + bool _hasExtendsClause = false; + bool _hasImplementsClause = false; + bool _hasMembers = false; + bool _hasMetadata = false; + bool _hasTypeParameters = false; + bool _hasWithClause = false; + + LazyClassDeclaration(this.data); + + static LazyClassDeclaration get(ClassDeclaration node) { + return node.getProperty(_key); + } + + static void readDocumentationComment( + AstBinaryReader reader, + ClassDeclaration node, + ) { + var lazy = LazyClassDeclaration.get(node); + if (lazy != null && !lazy._hasDocumentationComment) { + node.documentationComment = reader.readNode( + lazy.data.annotatedNode_comment, + ); + lazy._hasDocumentationComment = true; + } + } + + static void readExtendsClause( + AstBinaryReader reader, + ClassDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasExtendsClause) { + node.extendsClause = reader.readNode( + lazy.data.classDeclaration_extendsClause, + ); + lazy._hasExtendsClause = true; + } + } + + static void readImplementsClause( + AstBinaryReader reader, + ClassDeclaration node, + ) { + var lazy = LazyClassDeclaration.get(node); + if (lazy != null && !lazy._hasImplementsClause) { + node.implementsClause = reader.readNode( + lazy.data.classOrMixinDeclaration_implementsClause, + ); + lazy._hasImplementsClause = true; + } + } + + static void readMembers( + AstBinaryReader reader, + ClassDeclaration node, + ) { + var lazy = LazyClassDeclaration.get(node); + if (lazy != null && !lazy._hasMembers) { + var dataList = lazy.data.classOrMixinDeclaration_members; + for (var i = 0; i < dataList.length; ++i) { + var data = dataList[i]; + node.members[i] = reader.readNode(data); + } + lazy._hasMembers = true; + } + } + + static void readMetadata( + AstBinaryReader reader, + ClassDeclaration node, + ) { + var lazy = LazyClassDeclaration.get(node); + if (lazy != null && !lazy._hasMetadata) { + var dataList = lazy.data.annotatedNode_metadata; + for (var i = 0; i < dataList.length; ++i) { + var data = dataList[i]; + node.metadata[i] = reader.readNode(data); + } + lazy._hasMetadata = true; + } + } + + static void readTypeParameters( + AstBinaryReader reader, + ClassDeclaration node, + ) { + var lazy = LazyClassDeclaration.get(node); + if (lazy != null && !lazy._hasTypeParameters) { + node.typeParameters = reader.readNode( + lazy.data.classOrMixinDeclaration_typeParameters, + ); + lazy._hasTypeParameters = true; + } + } + + static void readWithClause( + AstBinaryReader reader, + ClassDeclaration node, + ) { + var lazy = LazyClassDeclaration.get(node); + if (lazy != null && !lazy._hasWithClause) { + node.withClause = reader.readNode( + lazy.data.classDeclaration_withClause, + ); + lazy._hasWithClause = true; + } + } + + static void setData(ClassDeclaration node, LinkedNode data) { + node.setProperty(_key, LazyClassDeclaration(data)); + } +} + +class LazyClassTypeAlias { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasDocumentationComment = false; + bool _hasImplementsClause = false; + bool _hasMetadata = false; + bool _hasSuperclass = false; + bool _hasTypeParameters = false; + bool _hasWithClause = false; + + LazyClassTypeAlias(this.data); + + static LazyClassTypeAlias get(ClassTypeAlias node) { + return node.getProperty(_key); + } + + static void readDocumentationComment( + AstBinaryReader reader, + ClassTypeAlias node, + ) { + var lazy = LazyClassTypeAlias.get(node); + if (lazy != null && !lazy._hasDocumentationComment) { + node.documentationComment = reader.readNode( + lazy.data.annotatedNode_comment, + ); + lazy._hasDocumentationComment = true; + } + } + + static void readImplementsClause( + AstBinaryReader reader, + ClassTypeAlias node, + ) { + var lazy = LazyClassTypeAlias.get(node); + if (lazy != null && !lazy._hasImplementsClause) { + node.implementsClause = reader.readNode( + lazy.data.classTypeAlias_implementsClause, + ); + lazy._hasImplementsClause = true; + } + } + + static void readMetadata( + AstBinaryReader reader, + ClassTypeAlias node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasMetadata) { + var dataList = lazy.data.annotatedNode_metadata; + for (var i = 0; i < dataList.length; ++i) { + var data = dataList[i]; + node.metadata[i] = reader.readNode(data); + } + lazy._hasMetadata = true; + } + } + + static void readSuperclass( + AstBinaryReader reader, + ClassTypeAlias node, + ) { + if (reader.isLazy) { + var lazy = get(node); + if (!lazy._hasSuperclass) { + node.superclass = reader.readNode( + lazy.data.classTypeAlias_superclass, + ); + lazy._hasSuperclass = true; + } + } + } + + static void readTypeParameters( + AstBinaryReader reader, + ClassTypeAlias node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasTypeParameters) { + node.typeParameters = reader.readNode( + lazy.data.classTypeAlias_typeParameters, + ); + lazy._hasTypeParameters = true; + } + } + + static void readWithClause( + AstBinaryReader reader, + ClassTypeAlias node, + ) { + var lazy = LazyClassTypeAlias.get(node); + if (lazy != null && !lazy._hasWithClause) { + node.withClause = reader.readNode( + lazy.data.classTypeAlias_withClause, + ); + lazy._hasWithClause = true; + } + } + + static void setData(ClassTypeAlias node, LinkedNode data) { + node.setProperty(_key, LazyClassTypeAlias(data)); + } +} + +class LazyConstructorDeclaration { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasBody = false; + bool _hasDocumentationComment = false; + bool _hasFormalParameters = false; + bool _hasMetadata = false; + + LazyConstructorDeclaration(this.data); + + static LazyConstructorDeclaration get(ConstructorDeclaration node) { + return node.getProperty(_key); + } + + static void readBody( + AstBinaryReader reader, + ConstructorDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasBody) { + node.body = reader.readNode( + lazy.data.constructorDeclaration_body, + ); + lazy._hasBody = true; + } + } + + static void readDocumentationComment( + AstBinaryReader reader, + ConstructorDeclaration node, + ) { + var lazy = LazyConstructorDeclaration.get(node); + if (lazy != null && !lazy._hasDocumentationComment) { + node.documentationComment = reader.readNode( + lazy.data.annotatedNode_comment, + ); + lazy._hasDocumentationComment = true; + } + } + + static void readFormalParameters( + AstBinaryReader reader, + ConstructorDeclaration node, + ) { + var lazy = LazyConstructorDeclaration.get(node); + if (lazy != null && !lazy._hasFormalParameters) { + node.parameters = reader.readNode( + lazy.data.constructorDeclaration_parameters, + ); + lazy._hasFormalParameters = true; + } + } + + static void readMetadata( + AstBinaryReader reader, + ConstructorDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasMetadata) { + var dataList = lazy.data.annotatedNode_metadata; + for (var i = 0; i < dataList.length; ++i) { + var data = dataList[i]; + node.metadata[i] = reader.readNode(data); + } + lazy._hasMetadata = true; + } + } + + static void setData(ConstructorDeclaration node, LinkedNode data) { + node.setProperty(_key, LazyConstructorDeclaration(data)); + } +} + +class LazyDirective { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasMetadata = false; + + LazyDirective(this.data); + + static LazyDirective get(Directive node) { + return node.getProperty(_key); + } + + static void readMetadata(AstBinaryReader reader, Directive node) { + var lazy = get(node); + if (lazy != null && !lazy._hasMetadata) { + var dataList = lazy.data.annotatedNode_metadata; + for (var i = 0; i < dataList.length; ++i) { + var data = dataList[i]; + node.metadata[i] = reader.readNode(data); + } + lazy._hasMetadata = true; + } + } + + static void setData(Directive node, LinkedNode data) { + node.setProperty(_key, LazyDirective(data)); + } +} + +class LazyEnumConstantDeclaration { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasDocumentationComment = false; + bool _hasMetadata = false; + + LazyEnumConstantDeclaration(this.data); + + static LazyEnumConstantDeclaration get(EnumConstantDeclaration node) { + return node.getProperty(_key); + } + + static void readDocumentationComment( + AstBinaryReader reader, + EnumConstantDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasDocumentationComment) { + node.documentationComment = reader.readNode( + lazy.data.annotatedNode_comment, + ); + lazy._hasDocumentationComment = true; + } + } + + static void readMetadata( + AstBinaryReader reader, + EnumConstantDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasMetadata) { + var dataList = lazy.data.annotatedNode_metadata; + for (var i = 0; i < dataList.length; ++i) { + var data = dataList[i]; + node.metadata[i] = reader.readNode(data); + } + lazy._hasMetadata = true; + } + } + + static void setData(EnumConstantDeclaration node, LinkedNode data) { + node.setProperty(_key, LazyEnumConstantDeclaration(data)); + } +} + +class LazyEnumDeclaration { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasConstants = false; + bool _hasDocumentationComment = false; + bool _hasMetadata = false; + + LazyEnumDeclaration(this.data); + + static LazyEnumDeclaration get(EnumDeclaration node) { + return node.getProperty(_key); + } + + static void readConstants( + AstBinaryReader reader, + EnumDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasConstants) { + var dataList = lazy.data.enumDeclaration_constants; + for (var i = 0; i < dataList.length; ++i) { + var data = dataList[i]; + node.constants[i] = reader.readNode(data); + } + lazy._hasConstants = true; + } + } + + static void readDocumentationComment( + AstBinaryReader reader, + EnumDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasDocumentationComment) { + node.documentationComment = reader.readNode( + lazy.data.annotatedNode_comment, + ); + lazy._hasDocumentationComment = true; + } + } + + static void readMetadata( + AstBinaryReader reader, + EnumDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasMetadata) { + var dataList = lazy.data.annotatedNode_metadata; + for (var i = 0; i < dataList.length; ++i) { + var data = dataList[i]; + node.metadata[i] = reader.readNode(data); + } + lazy._hasMetadata = true; + } + } + + static void setData(EnumDeclaration node, LinkedNode data) { + node.setProperty(_key, LazyEnumDeclaration(data)); + } +} + +class LazyFieldDeclaration { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasDocumentationComment = false; + bool _hasMetadata = false; + + LazyFieldDeclaration(this.data); + + static LazyFieldDeclaration get(FieldDeclaration node) { + return node.getProperty(_key); + } + + static void readDocumentationComment( + AstBinaryReader reader, + FieldDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasDocumentationComment) { + node.documentationComment = reader.readNode( + lazy.data.annotatedNode_comment, + ); + lazy._hasDocumentationComment = true; + } + } + + static void readMetadata( + AstBinaryReader reader, + FieldDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasMetadata) { + var dataList = lazy.data.annotatedNode_metadata; + for (var i = 0; i < dataList.length; ++i) { + var data = dataList[i]; + node.metadata[i] = reader.readNode(data); + } + lazy._hasMetadata = true; + } + } + + static void setData(FieldDeclaration node, LinkedNode data) { + node.setProperty(_key, LazyFieldDeclaration(data)); + } +} + +class LazyFormalParameter { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasDefaultValue = false; + bool _hasMetadata = false; + bool _hasType = false; + + LazyFormalParameter(this.data); + + static LazyFormalParameter get(FormalParameter node) { + return node.getProperty(_key); + } + + static DartType getType( + AstBinaryReader reader, + FormalParameter node, + ) { + if (reader.isLazy) { + var lazy = get(node); + if (!lazy._hasType) { + var type = reader.readType(lazy.data.actualType); + LazyAst.setType(node, type); + lazy._hasType = true; + } + } + return LazyAst.getType(node); + } + + static void readDefaultValue( + AstBinaryReader reader, + DefaultFormalParameter node, + ) { + if (reader.isLazy) { + var lazy = LazyFormalParameter.get(node); + if (lazy != null && !lazy._hasDefaultValue) { + node.defaultValue = reader.readNode( + lazy.data.defaultFormalParameter_defaultValue, + ); + lazy._hasDefaultValue = true; + } + } + } + + static void readMetadata( + AstBinaryReader reader, + FormalParameter node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasMetadata) { + var dataList = lazy.data.normalFormalParameter_metadata; + for (var i = 0; i < dataList.length; ++i) { + var data = dataList[i]; + node.metadata[i] = reader.readNode(data); + } + lazy._hasMetadata = true; + } + } + + static void setData(FormalParameter node, LinkedNode data) { + node.setProperty(_key, LazyFormalParameter(data)); + } +} + +class LazyFunctionDeclaration { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasDocumentationComment = false; + bool _hasMetadata = false; + bool _hasReturnType = false; + + LazyFunctionDeclaration(this.data); + + static LazyFunctionDeclaration get(FunctionDeclaration node) { + return node.getProperty(_key); + } + + static DartType getReturnType( + AstBinaryReader reader, + FunctionDeclaration node, + ) { + if (reader.isLazy) { + var lazy = get(node); + if (!lazy._hasReturnType) { + var type = reader.readType(lazy.data.actualReturnType); + LazyAst.setReturnType(node, type); + lazy._hasReturnType = true; + } + } + return LazyAst.getReturnType(node); + } + + static void readDocumentationComment( + AstBinaryReader reader, + FunctionDeclaration node, + ) { + var lazy = LazyFunctionDeclaration.get(node); + if (lazy != null && !lazy._hasDocumentationComment) { + node.documentationComment = reader.readNode( + lazy.data.annotatedNode_comment, + ); + lazy._hasDocumentationComment = true; + } + } + + static void readFunctionExpression( + AstBinaryReader reader, + FunctionDeclaration node, + ) { + if (node.functionExpression == null) { + var lazy = LazyFunctionDeclaration.get(node); + node.functionExpression = reader.readNode( + lazy.data.functionDeclaration_functionExpression, + ); + } + } + + static void readMetadata( + AstBinaryReader reader, + FunctionDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasMetadata) { + var dataList = lazy.data.annotatedNode_metadata; + for (var i = 0; i < dataList.length; ++i) { + var data = dataList[i]; + node.metadata[i] = reader.readNode(data); + } + lazy._hasMetadata = true; + } + } + + static void setData(FunctionDeclaration node, LinkedNode data) { + node.setProperty(_key, LazyFunctionDeclaration(data)); + } +} + +class LazyFunctionExpression { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasBody = false; + bool _hasFormalParameters = false; + bool _hasTypeParameters = false; + + LazyFunctionExpression(this.data); + + static LazyFunctionExpression get(FunctionExpression node) { + return node.getProperty(_key); + } + + static void readBody( + AstBinaryReader reader, + FunctionExpression node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasBody) { + node.body = reader.readNode( + lazy.data.functionExpression_body, + ); + lazy._hasBody = true; + } + } + + static void readFormalParameters( + AstBinaryReader reader, + FunctionExpression node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasFormalParameters) { + node.parameters = reader.readNode( + lazy.data.functionExpression_formalParameters, + ); + lazy._hasFormalParameters = true; + } + } + + static void readTypeParameters( + AstBinaryReader reader, + FunctionExpression node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasTypeParameters) { + node.typeParameters = reader.readNode( + lazy.data.functionExpression_typeParameters, + ); + lazy._hasTypeParameters = true; + } + } + + static void setData(FunctionExpression node, LinkedNode data) { + node.setProperty(_key, LazyFunctionExpression(data)); + } +} + +class LazyFunctionTypeAlias { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasDocumentationComment = false; + bool _hasFormalParameters = false; + bool _hasMetadata = false; + bool _hasReturnType = false; + bool _hasTypeParameters = false; + + LazyFunctionTypeAlias(this.data); + + static LazyFunctionTypeAlias get(FunctionTypeAlias node) { + return node.getProperty(_key); + } + + static DartType getReturnType( + AstBinaryReader reader, + FunctionTypeAlias node, + ) { + if (reader.isLazy) { + var lazy = get(node); + if (!lazy._hasReturnType) { + var type = reader.readType(lazy.data.actualReturnType); + LazyAst.setReturnType(node, type); + lazy._hasReturnType = true; + } + } + return LazyAst.getReturnType(node); + } + + static void readDocumentationComment( + AstBinaryReader reader, + FunctionTypeAlias node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasDocumentationComment) { + node.documentationComment = reader.readNode( + lazy.data.annotatedNode_comment, + ); + lazy._hasDocumentationComment = true; + } + } + + static void readFormalParameters( + AstBinaryReader reader, + FunctionTypeAlias node, + ) { + var lazy = LazyFunctionTypeAlias.get(node); + if (lazy != null && !lazy._hasFormalParameters) { + node.parameters = reader.readNode( + lazy.data.functionTypeAlias_formalParameters, + ); + lazy._hasFormalParameters = true; + } + } + + static void readMetadata( + AstBinaryReader reader, + FunctionTypeAlias node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasMetadata) { + var dataList = lazy.data.annotatedNode_metadata; + for (var i = 0; i < dataList.length; ++i) { + var data = dataList[i]; + node.metadata[i] = reader.readNode(data); + } + lazy._hasMetadata = true; + } + } + + static void readTypeParameters( + AstBinaryReader reader, + FunctionTypeAlias node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasTypeParameters) { + node.typeParameters = reader.readNode( + lazy.data.functionTypeAlias_typeParameters, + ); + lazy._hasTypeParameters = true; + } + } + + static void setData(FunctionTypeAlias node, LinkedNode data) { + node.setProperty(_key, LazyFunctionTypeAlias(data)); + } +} + +class LazyGenericFunctionType { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasFormalParameters = false; + bool _hasReturnType = false; + + LazyGenericFunctionType(this.data); + + static LazyGenericFunctionType get(GenericFunctionType node) { + return node.getProperty(_key); + } + + static DartType getReturnType( + AstBinaryReader reader, + GenericFunctionType node, + ) { + if (reader.isLazy) { + var lazy = get(node); + if (!lazy._hasReturnType) { + var type = reader.readType(lazy.data.actualReturnType); + LazyAst.setReturnType(node, type); + lazy._hasReturnType = true; + } + } + return LazyAst.getReturnType(node); + } + + static void readFormalParameters( + AstBinaryReader reader, + GenericFunctionType node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasFormalParameters) { + node.parameters = reader.readNode( + lazy.data.genericFunctionType_formalParameters, + ); + lazy._hasFormalParameters = true; + } + } + + static void setData(GenericFunctionType node, LinkedNode data) { + node.setProperty(_key, LazyGenericFunctionType(data)); + } +} + +class LazyGenericTypeAlias { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasDocumentationComment = false; + bool _hasFunction = false; + bool _hasTypeParameters = false; + + LazyGenericTypeAlias(this.data); + + static LazyGenericTypeAlias get(GenericTypeAlias node) { + return node.getProperty(_key); + } + + static void readDocumentationComment( + AstBinaryReader reader, + GenericTypeAlias node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasDocumentationComment) { + node.documentationComment = reader.readNode( + lazy.data.annotatedNode_comment, + ); + lazy._hasDocumentationComment = true; + } + } + + static void readFunctionType( + AstBinaryReader reader, + GenericTypeAlias node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasFunction) { + node.functionType = reader.readNode( + lazy.data.genericTypeAlias_functionType, + ); + lazy._hasFunction = true; + } + } + + static void readTypeParameters( + AstBinaryReader reader, + GenericTypeAlias node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasTypeParameters) { + node.typeParameters = reader.readNode( + lazy.data.genericTypeAlias_typeParameters, + ); + lazy._hasTypeParameters = true; + } + } + + static void setData(GenericTypeAlias node, LinkedNode data) { + node.setProperty(_key, LazyGenericTypeAlias(data)); + } +} + +class LazyMethodDeclaration { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasBody = false; + bool _hasDocumentationComment = false; + bool _hasFormalParameters = false; + bool _hasMetadata = false; + bool _hasReturnType = false; + bool _hasTypeParameters = false; + + LazyMethodDeclaration(this.data); + + static LazyMethodDeclaration get(MethodDeclaration node) { + return node.getProperty(_key); + } + + static DartType getReturnType( + AstBinaryReader reader, + MethodDeclaration node, + ) { + if (reader.isLazy) { + var lazy = get(node); + if (!lazy._hasReturnType) { + var type = reader.readType(lazy.data.actualReturnType); + LazyAst.setReturnType(node, type); + lazy._hasReturnType = true; + } + } + return LazyAst.getReturnType(node); + } + + static void readBody( + AstBinaryReader reader, + MethodDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasBody) { + node.body = reader.readNode( + lazy.data.methodDeclaration_body, + ); + lazy._hasBody = true; + } + } + + static void readDocumentationComment( + AstBinaryReader reader, + MethodDeclaration node, + ) { + var lazy = LazyMethodDeclaration.get(node); + if (lazy != null && !lazy._hasDocumentationComment) { + node.documentationComment = reader.readNode( + lazy.data.annotatedNode_comment, + ); + lazy._hasDocumentationComment = true; + } + } + + static void readFormalParameters( + AstBinaryReader reader, + MethodDeclaration node, + ) { + var lazy = LazyMethodDeclaration.get(node); + if (lazy != null && !lazy._hasFormalParameters) { + node.parameters = reader.readNode( + lazy.data.methodDeclaration_formalParameters, + ); + lazy._hasFormalParameters = true; + } + } + + static void readMetadata( + AstBinaryReader reader, + MethodDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasMetadata) { + var dataList = lazy.data.annotatedNode_metadata; + for (var i = 0; i < dataList.length; ++i) { + var data = dataList[i]; + node.metadata[i] = reader.readNode(data); + } + lazy._hasMetadata = true; + } + } + + static void readTypeParameters( + AstBinaryReader reader, + MethodDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasTypeParameters) { + node.typeParameters = reader.readNode( + lazy.data.methodDeclaration_typeParameters, + ); + lazy._hasTypeParameters = true; + } + } + + static void setData(MethodDeclaration node, LinkedNode data) { + node.setProperty(_key, LazyMethodDeclaration(data)); + } +} + +class LazyMixinDeclaration { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasDocumentationComment = false; + bool _hasOnClause = false; + bool _hasImplementsClause = false; + bool _hasMembers = false; + bool _hasTypeParameters = false; + + LazyMixinDeclaration(this.data); + + static LazyMixinDeclaration get(MixinDeclaration node) { + return node.getProperty(_key); + } + + static void readDocumentationComment( + AstBinaryReader reader, + MixinDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasDocumentationComment) { + node.documentationComment = reader.readNode( + lazy.data.annotatedNode_comment, + ); + lazy._hasDocumentationComment = true; + } + } + + static void readImplementsClause( + AstBinaryReader reader, + MixinDeclarationImpl node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasImplementsClause) { + node.implementsClause = reader.readNode( + lazy.data.classOrMixinDeclaration_implementsClause, + ); + lazy._hasImplementsClause = true; + } + } + + static void readMembers( + AstBinaryReader reader, + MixinDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasMembers) { + var dataList = lazy.data.classOrMixinDeclaration_members; + for (var i = 0; i < dataList.length; ++i) { + var data = dataList[i]; + node.members[i] = reader.readNode(data); + } + lazy._hasMembers = true; + } + } + + static void readOnClause( + AstBinaryReader reader, + MixinDeclarationImpl node, + ) { + var lazy = get(node); + if (!lazy._hasOnClause) { + node.onClause = reader.readNode( + lazy.data.mixinDeclaration_onClause, + ); + lazy._hasOnClause = true; + } + } + + static void readTypeParameters( + AstBinaryReader reader, + MixinDeclarationImpl node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasTypeParameters) { + node.typeParameters = reader.readNode( + lazy.data.classOrMixinDeclaration_typeParameters, + ); + lazy._hasTypeParameters = true; + } + } + + static void setData(MixinDeclaration node, LinkedNode data) { + node.setProperty(_key, LazyMixinDeclaration(data)); + } +} + +class LazyTopLevelVariableDeclaration { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasDocumentationComment = false; + bool _hasMetadata = false; + + LazyTopLevelVariableDeclaration(this.data); + + static LazyTopLevelVariableDeclaration get(TopLevelVariableDeclaration node) { + return node.getProperty(_key); + } + + static void readDocumentationComment( + AstBinaryReader reader, + TopLevelVariableDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasDocumentationComment) { + node.documentationComment = reader.readNode( + lazy.data.annotatedNode_comment, + ); + lazy._hasDocumentationComment = true; + } + } + + static void readMetadata( + AstBinaryReader reader, + TopLevelVariableDeclaration node, + ) { + var lazy = get(node); + if (lazy != null && !lazy._hasMetadata) { + var dataList = lazy.data.annotatedNode_metadata; + for (var i = 0; i < dataList.length; ++i) { + var data = dataList[i]; + node.metadata[i] = reader.readNode(data); + } + lazy._hasMetadata = true; + } + } + + static void setData(TopLevelVariableDeclaration node, LinkedNode data) { + node.setProperty(_key, LazyTopLevelVariableDeclaration(data)); + } +} + +class LazyTypeParameter { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasBound = false; + + LazyTypeParameter(this.data); + + static LazyTypeParameter get(TypeParameter node) { + return node.getProperty(_key); + } + + static void readBound(AstBinaryReader reader, TypeParameter node) { + var lazy = get(node); + if (lazy != null && !lazy._hasBound) { + node.bound = reader.readNode(lazy.data.typeParameter_bound); + lazy._hasBound = true; + } + } + + static void setData(TypeParameter node, LinkedNode data) { + node.setProperty(_key, LazyTypeParameter(data)); + } +} + +class LazyVariableDeclaration { + static const _key = 'lazyAst'; + + final LinkedNode data; + + bool _hasInitializer = false; + bool _hasType = false; + + LazyVariableDeclaration(this.data); + + static LazyVariableDeclaration get(VariableDeclaration node) { + return node.getProperty(_key); + } + + static DartType getType( + AstBinaryReader reader, + VariableDeclaration node, + ) { + if (reader.isLazy) { + var lazy = get(node); + if (!lazy._hasType) { + var type = reader.readType(lazy.data.actualType); + LazyAst.setType(node, type); + lazy._hasType = true; + } + } + return LazyAst.getType(node); + } + + static void readInitializer( + AstBinaryReader reader, + VariableDeclaration node, + ) { + if (reader.isLazy) { + var lazy = get(node); + if (lazy != null && !lazy._hasInitializer) { + node.initializer = reader.readNode( + lazy.data.variableDeclaration_initializer, + ); + lazy._hasInitializer = true; + } + } + } + + static void setData(VariableDeclaration node, LinkedNode data) { + node.setProperty(_key, LazyVariableDeclaration(data)); + } +}
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart index 4edc6cd..989a7f4 100644 --- a/pkg/analyzer/lib/src/summary2/link.dart +++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -14,12 +14,13 @@ import 'package:analyzer/src/summary/format.dart'; import 'package:analyzer/src/summary/idl.dart'; import 'package:analyzer/src/summary/summary_sdk.dart'; +import 'package:analyzer/src/summary2/ast_binary_writer.dart'; import 'package:analyzer/src/summary2/builder/source_library_builder.dart'; import 'package:analyzer/src/summary2/linked_bundle_context.dart'; import 'package:analyzer/src/summary2/linked_element_factory.dart'; import 'package:analyzer/src/summary2/linking_bundle_context.dart'; import 'package:analyzer/src/summary2/reference.dart'; -import 'package:analyzer/src/summary2/reference_resolver.dart'; +import 'package:analyzer/src/summary2/tokens_writer.dart'; import 'package:analyzer/src/summary2/type_builder.dart'; LinkResult link( @@ -37,10 +38,9 @@ final Reference rootReference = Reference.root(); LinkedElementFactory elementFactory; - LinkingBundleContext linkingBundleContext; - List<LinkedNodeLibraryBuilder> linkingLibraries = []; LinkedNodeBundleBuilder linkingBundle; LinkedBundleContext bundleContext; + LinkingBundleContext linkingBundleContext; /// Libraries that are being linked. final Map<Uri, SourceLibraryBuilder> builders = {}; @@ -67,32 +67,28 @@ rootReference, ); - linkingBundle = LinkedNodeBundleBuilder( - references: linkingBundleContext.referencesBuilder, - libraries: linkingLibraries, - ); - - bundleContext = LinkedBundleContext( + bundleContext = LinkedBundleContext.forAst( elementFactory, - linkingBundle.references, + linkingBundleContext.references, ); - bundleContext.linking = linkingBundleContext; } void link(List<LinkedNodeBundle> inputs, Map<Source, Map<Source, CompilationUnit>> unitMap) { for (var input in inputs) { - elementFactory.addBundle(input); + var inputBundleContext = LinkedBundleContext(elementFactory, input); + elementFactory.addBundle(inputBundleContext); } for (var librarySource in unitMap.keys) { SourceLibraryBuilder.build(this, librarySource, unitMap[librarySource]); } - - // Add libraries being linked, so we can ask for their elements as well. - elementFactory.addBundle(linkingBundle, context: bundleContext); + // TODO(scheglov) do in build() ? + elementFactory.addBundle(bundleContext); _buildOutlines(); + + _createLinkingBundle(); } void _addExporters() { @@ -115,6 +111,7 @@ _resolveTypes(); _performTopLevelInference(); _resolveConstructors(); + _resolveDefaultValues(); _resolveMetadata(); } @@ -161,14 +158,44 @@ } for (var library in builders.values) { - library.addImportsToScope(); + library.storeExportScope(); } for (var library in builders.values) { - library.storeExportScope(); + library.buildElement(); } } + void _createLinkingBundle() { + var linkingLibraries = <LinkedNodeLibraryBuilder>[]; + for (var builder in builders.values) { + linkingLibraries.add(builder.node); + + for (var unit2 in builder.context.units) { + var unit = unit2.unit; + var tokensResult = TokensWriter().writeTokens( + unit.beginToken, + unit.endToken, + ); + var tokensContext = tokensResult.toContext(); + + var writer = new AstBinaryWriter(linkingBundleContext, tokensContext); + var unitLinkedNode = writer.writeNode(unit); + builder.node.units.add( + LinkedNodeUnitBuilder( + uriStr: unit2.uriStr, + tokens: tokensResult.tokens, + node: unitLinkedNode, + ), + ); + } + } + linkingBundle = LinkedNodeBundleBuilder( + references: linkingBundleContext.referencesBuilder, + libraries: linkingLibraries, + ); + } + void _createTypeSystem() { var coreRef = rootReference.getChild('dart:core'); var coreLib = elementFactory.elementOfReference(coreRef); @@ -194,9 +221,15 @@ } void _resolveConstructors() { - for (var library in builders.values) { - library.resolveConstructors(); - } +// for (var library in builders.values) { +// library.resolveConstructors(); +// } + } + + void _resolveDefaultValues() { +// for (var library in builders.values) { +// library.resolveDefaultValues(); +// } } void _resolveMetadata() { @@ -206,11 +239,12 @@ } void _resolveTypes() { - var typesToBuild = TypesToBuild(); + var nodesToBuildType = NodesToBuildType(); for (var library in builders.values) { - library.resolveTypes(typesToBuild); + library.resolveTypes(nodesToBuildType); } - TypeBuilder(bundleContext).build(typesToBuild); +// computeSimplyBounded(bundleContext, builders.values); + TypeBuilder(linkingBundleContext).build(nodesToBuildType); } }
diff --git a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart index 8ecb51f..88f8655 100644 --- a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart +++ b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
@@ -2,29 +2,71 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/element/type.dart'; import 'package:analyzer/src/generated/utilities_dart.dart'; +import 'package:analyzer/src/summary/format.dart'; import 'package:analyzer/src/summary/idl.dart'; import 'package:analyzer/src/summary2/linked_element_factory.dart'; -import 'package:analyzer/src/summary2/linking_bundle_context.dart'; +import 'package:analyzer/src/summary2/linked_unit_context.dart'; import 'package:analyzer/src/summary2/reference.dart'; /// The context of a linked bundle, with shared references. class LinkedBundleContext { final LinkedElementFactory elementFactory; - final LinkedNodeReferences referencesData; + final LinkedNodeBundle _bundle; final List<Reference> _references; + final Map<String, LinkedLibraryContext> libraryMap = {}; - /// If the bundle is being linked, the reference to the linking context. - /// Otherwise `null`, and we are not expected to access it. - LinkingBundleContext linking; + LinkedBundleContext(this.elementFactory, this._bundle) + : _references = List<Reference>(_bundle.references.name.length) { + for (var library in _bundle.libraries) { + var libraryContext = LinkedLibraryContext(library.uriStr, this, library); + libraryMap[library.uriStr] = libraryContext; - LinkedBundleContext(this.elementFactory, this.referencesData) - : _references = List<Reference>.filled(referencesData.name.length, null, - growable: true); + var units = library.units; + for (var unitIndex = 0; unitIndex < units.length; ++unitIndex) { + var unit = units[unitIndex]; + var unitContext = LinkedUnitContext( + this, + libraryContext, + unitIndex, + unit.uriStr, + unit, + ); + libraryContext.units.add(unitContext); + } + } + } + + LinkedBundleContext.forAst(this.elementFactory, this._references) + : _bundle = null; + + LinkedLibraryContext addLinkingLibrary(String uriStr, + LinkedNodeLibraryBuilder data, Map<String, CompilationUnit> unitMap) { + var uriStr = data.uriStr; + var libraryContext = LinkedLibraryContext(uriStr, this, data); + libraryMap[uriStr] = libraryContext; + + var uriUriStrList = unitMap.keys.toList(); + for (var unitIndex = 0; unitIndex < uriUriStrList.length; ++unitIndex) { + var unitUriStr = uriUriStrList[unitIndex]; + var unit = unitMap[unitUriStr]; + var unitContext = LinkedUnitContext( + this, + libraryContext, + unitIndex, + unitUriStr, + null, + unit: unit, + ); + libraryContext.units.add(unitContext); + } + return libraryContext; + } T elementOfIndex<T extends Element>(int index) { var reference = referenceOfIndex(index); @@ -87,14 +129,6 @@ } Reference referenceOfIndex(int index) { - // When we are linking a bundle, we add new references. - // So, grow the list of references when we have data for them. - if (index >= _references.length) { - if (referencesData.name.length > _references.length) { - _references.length = referencesData.name.length; - } - } - var reference = _references[index]; if (reference != null) return reference; @@ -104,10 +138,10 @@ return reference; } - var parentIndex = referencesData.parent[index]; + var parentIndex = _bundle.references.parent[index]; var parent = referenceOfIndex(parentIndex); - var name = referencesData.name[index]; + var name = _bundle.references.name[index]; reference = parent.getChild(name); _references[index] = reference; @@ -124,3 +158,14 @@ return ParameterKind.REQUIRED; } } + +class LinkedLibraryContext { + final String uriStr; + final LinkedBundleContext context; + final LinkedNodeLibrary node; + final List<LinkedUnitContext> units = []; + + LinkedLibraryContext(this.uriStr, this.context, this.node); + + LinkedUnitContext get definingUnit => units.first; +}
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart index 13197b8..e16238f 100644 --- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart +++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/dart/analysis/session.dart'; +import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/resolver/scope.dart'; @@ -11,22 +12,18 @@ import 'package:analyzer/src/summary2/linked_bundle_context.dart'; import 'package:analyzer/src/summary2/linked_unit_context.dart'; import 'package:analyzer/src/summary2/reference.dart'; -import 'package:analyzer/src/summary2/tokens_context.dart'; class LinkedElementFactory { final AnalysisContext analysisContext; final AnalysisSession analysisSession; final Reference rootReference; - final Map<String, _Library> libraryMap = {}; + final Map<String, LinkedLibraryContext> libraryMap = {}; LinkedElementFactory( this.analysisContext, this.analysisSession, this.rootReference); - void addBundle(LinkedNodeBundle bundle, {LinkedBundleContext context}) { - context ??= LinkedBundleContext(this, bundle.references); - for (var library in bundle.libraries) { - libraryMap[library.uriStr] = _Library(context, library); - } + void addBundle(LinkedBundleContext context) { + libraryMap.addAll(context.libraryMap); } Namespace buildExportNamespace(Uri uri) { @@ -70,28 +67,28 @@ } LinkedNode nodeOfReference(Reference reference) { - if (reference.node != null) { - return reference.node; - } - - var unitRef = reference.parent?.parent; - var unitContainer = unitRef?.parent; - if (unitContainer?.name == '@unit') { - var libraryUriStr = unitContainer.parent.name; - var libraryData = libraryMap[libraryUriStr]; - for (var unitData in libraryData.node.units) { - var definingUnitContext = LinkedUnitContext( - libraryData.context, - TokensContext(unitData.tokens), - ); - _ElementRequest._indexUnitDeclarations( - definingUnitContext, - unitRef, - unitData.node, - ); - return reference.node; - } - } +// if (reference.node != null) { +// return reference.node; +// } +// +// var unitRef = reference.parent?.parent; +// var unitContainer = unitRef?.parent; +// if (unitContainer?.name == '@unit') { +// var libraryUriStr = unitContainer.parent.name; +// var libraryData = libraryMap[libraryUriStr]; +// for (var unitData in libraryData.node.units) { +// var definingUnitContext = LinkedUnitContext( +// libraryData.context, +// TokensContext(unitData.tokens), +// ); +// _ElementRequest._indexUnitDeclarations( +// definingUnitContext, +// unitRef, +// unitData.node, +// ); +// return reference.node; +// } +// } throw UnimplementedError('$reference'); } @@ -191,24 +188,20 @@ ClassElementImpl _class( CompilationUnitElementImpl unit, Reference reference) { - if (reference.node == null) { + if (reference.node2 == null) { _indexUnitElementDeclarations(unit); - assert(reference.node != 0, '$reference'); + assert(reference.node2 != null, '$reference'); } - return reference.element = ClassElementImpl.forLinkedNode( - unit, - reference, - reference.node, - ); + ClassElementImpl.forLinkedNode(unit, reference, reference.node2); + return reference.element; } ConstructorElementImpl _constructor( - ClassElementImpl class_, Reference reference) { - return reference.element = ConstructorElementImpl.forLinkedNode( - reference, - reference.node, - class_, - ); + ClassElementImpl enclosing, Reference reference) { + enclosing.constructors; + // Requesting constructors sets elements for all of them. + assert(reference.element != null); + return reference.element; } LibraryElementImpl _createLibraryElement(Reference reference) { @@ -217,42 +210,40 @@ var sourceFactory = elementFactory.analysisContext.sourceFactory; var librarySource = sourceFactory.forUri(uriStr); - var libraryData = elementFactory.libraryMap[uriStr]; - var node = libraryData.node; - var hasName = node.name.isNotEmpty; + var libraryContext = elementFactory.libraryMap[uriStr]; + // TODO(scheglov) don't use node + var node2 = libraryContext.node; + var hasName = node2.name.isNotEmpty; - var definingUnitData = node.units[0]; - var definingUnitContext = LinkedUnitContext( - libraryData.context, - TokensContext(definingUnitData.tokens), - ); + var definingUnitContext = libraryContext.definingUnit; var libraryElement = LibraryElementImpl.forLinkedNode( elementFactory.analysisContext, elementFactory.analysisSession, - node.name, - hasName ? node.nameOffset : -1, - node.name.length, + node2.name, + hasName ? node2.nameOffset : -1, + node2.name.length, definingUnitContext, reference, - definingUnitData.node, + definingUnitContext.unit_withDeclarations, ); var units = <CompilationUnitElementImpl>[]; var unitContainerRef = reference.getChild('@unit'); - for (var unitData in node.units) { - var unitSource = sourceFactory.forUri(unitData.uriStr); - var tokensContext = TokensContext(unitData.tokens); + for (var unitContext in libraryContext.units) { + var unitNode = unitContext.unit_withDeclarations; + + var unitSource = sourceFactory.forUri(unitContext.uriStr); var unitElement = CompilationUnitElementImpl.forLinkedNode( libraryElement, - LinkedUnitContext(libraryData.context, tokensContext), - unitContainerRef.getChild(unitData.uriStr), - unitData.node, + unitContext, + unitContainerRef.getChild(unitContext.uriStr), + unitNode, ); unitElement.source = unitSource; unitElement.librarySource = librarySource; units.add(unitElement); - unitContainerRef.getChild(unitData.uriStr).element = unitElement; + unitContainerRef.getChild(unitContext.uriStr).element = unitElement; } libraryElement.definingCompilationUnit = units[0]; @@ -261,15 +252,12 @@ } EnumElementImpl _enum(CompilationUnitElementImpl unit, Reference reference) { - if (reference.node == null) { + if (reference.node2 == null) { _indexUnitElementDeclarations(unit); - assert(reference.node != 0, '$reference'); + assert(reference.node2 != null, '$reference'); } - return reference.element = EnumElementImpl.forLinkedNode( - unit, - reference, - reference.node, - ); + EnumElementImpl.forLinkedNode(unit, reference, reference.node2); + return reference.element; } Element _function(CompilationUnitElementImpl enclosing, Reference reference) { @@ -300,15 +288,12 @@ GenericTypeAliasElementImpl _typeAlias( CompilationUnitElementImpl unit, Reference reference) { - if (reference.node == null) { + if (reference.node2 == null) { _indexUnitElementDeclarations(unit); - assert(reference.node != 0, '$reference'); + assert(reference.node2 != null, '$reference'); } - return reference.element = GenericTypeAliasElementImpl.forLinkedNode( - unit, - reference, - reference.node, - ); + GenericTypeAliasElementImpl.forLinkedNode(unit, reference, reference.node2); + return reference.element; } Element _typeParameter( @@ -319,48 +304,31 @@ return reference.element; } + /// Index nodes for which we choose to create elements individually, + /// for example [ClassDeclaration], so that its [Reference] has the node, + /// and we can call the [ClassElementImpl] constructor. static void _indexUnitDeclarations( LinkedUnitContext unitContext, Reference unitRef, - LinkedNode unitNode, + CompilationUnit unitNode, ) { var classRef = unitRef.getChild('@class'); var enumRef = unitRef.getChild('@enum'); - var functionRef = unitRef.getChild('@function'); var typeAliasRef = unitRef.getChild('@typeAlias'); - var variableRef = unitRef.getChild('@variable'); - for (var declaration in unitNode.compilationUnit_declarations) { - var kind = declaration.kind; - if (kind == LinkedNodeKind.classDeclaration || - kind == LinkedNodeKind.classTypeAlias) { - var name = unitContext.getUnitMemberName(declaration); - classRef.getChild(name).node = declaration; - } else if (kind == LinkedNodeKind.enumDeclaration) { - var name = unitContext.getUnitMemberName(declaration); - enumRef.getChild(name).node = declaration; - } else if (kind == LinkedNodeKind.functionDeclaration) { - var name = unitContext.getUnitMemberName(declaration); - functionRef.getChild(name).node = declaration; - } else if (kind == LinkedNodeKind.functionTypeAlias) { - var name = unitContext.getUnitMemberName(declaration); - typeAliasRef.getChild(name).node = declaration; - } else if (kind == LinkedNodeKind.topLevelVariableDeclaration) { - var variables = declaration.topLevelVariableDeclaration_variableList; - for (var variable in variables.variableDeclarationList_variables) { - var name = - unitContext.getSimpleName(variable.variableDeclaration_name); - variableRef.getChild(name).node = variable; - } - } else { - throw UnimplementedError('$kind'); + for (var declaration in unitNode.declarations) { + if (declaration is ClassDeclaration) { + var name = declaration.name.name; + classRef.getChild(name).node2 = declaration; + } else if (declaration is EnumDeclaration) { + var name = declaration.name.name; + enumRef.getChild(name).node2 = declaration; + } else if (declaration is FunctionTypeAlias) { + var name = declaration.name.name; + typeAliasRef.getChild(name).node2 = declaration; + } else if (declaration is GenericTypeAlias) { + var name = declaration.name.name; + typeAliasRef.getChild(name).node2 = declaration; } } } } - -class _Library { - final LinkedBundleContext context; - final LinkedNodeLibrary node; - - _Library(this.context, this.node); -}
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart index 7f2a591..0451be4 100644 --- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart +++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -5,35 +5,107 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/src/dart/element/element.dart'; +import 'package:analyzer/src/generated/utilities_dart.dart'; import 'package:analyzer/src/summary/format.dart'; import 'package:analyzer/src/summary/idl.dart'; import 'package:analyzer/src/summary2/ast_binary_reader.dart'; +import 'package:analyzer/src/summary2/lazy_ast.dart'; import 'package:analyzer/src/summary2/linked_bundle_context.dart'; -import 'package:analyzer/src/summary2/reference.dart'; import 'package:analyzer/src/summary2/tokens_context.dart'; /// The context of a unit - the context of the bundle, and the unit tokens. class LinkedUnitContext { final LinkedBundleContext bundleContext; + final LinkedLibraryContext libraryContext; + final int indexInLibrary; + final String uriStr; + final LinkedNodeUnit data; final TokensContext tokensContext; - LinkedUnitContext(this.bundleContext, this.tokensContext); + AstBinaryReader _astReader; - Iterable<LinkedNode> classFields(LinkedNode class_) sync* { - for (var declaration in class_.classOrMixinDeclaration_members) { - if (declaration.kind == LinkedNodeKind.fieldDeclaration) { - var variableList = declaration.fieldDeclaration_fields; - for (var field in variableList.variableDeclarationList_variables) { - yield field; - } - } - } + CompilationUnit _unit; + bool _hasDirectivesRead = false; + + LinkedUnitContext(this.bundleContext, this.libraryContext, + this.indexInLibrary, this.uriStr, this.data, + {CompilationUnit unit}) + : tokensContext = data != null ? TokensContext(data.tokens) : null { + _astReader = AstBinaryReader(this); + _astReader.isLazy = unit == null; + + _unit = unit; + _hasDirectivesRead = _unit != null; } - String getCommentText(LinkedNode comment) { - if (comment == null) return null; + CompilationUnit get unit => _unit; - return comment.comment_tokens.map(getTokenLexeme).join('\n'); + CompilationUnit get unit_withDeclarations { + if (_unit == null) { + _unit = _astReader.readNode(data.node); + } + return _unit; + } + + CompilationUnit get unit_withDirectives { + if (!_hasDirectivesRead) { + var directiveDataList = data.node.compilationUnit_directives; + for (var i = 0; i < directiveDataList.length; ++i) { + var directiveData = directiveDataList[i]; + _unit.directives[i] = _astReader.readNode(directiveData); + } + _hasDirectivesRead = true; + } + return _unit; + } + + /// Return the absolute URI referenced in the [directive]. + Uri directiveUri(Uri libraryUri, UriBasedDirective directive) { + var relativeUriStr = directive.uri.stringValue; + var relativeUri = Uri.parse(relativeUriStr); + return resolveRelativeUri(libraryUri, relativeUri); + } + + int getCodeLength(AstNode node) { + if (node is ClassDeclaration) { + return LazyClassDeclaration.get(node).data.codeLength; + } else if (node is ClassTypeAlias) { + return LazyClassTypeAlias.get(node).data.codeLength; + } else if (node is ConstructorDeclaration) { + return LazyConstructorDeclaration.get(node).data.codeLength; + } else if (node is FormalParameter) { + return LazyFormalParameter.get(node).data.codeLength; + } else if (node is FunctionDeclaration) { + return LazyFunctionDeclaration.get(node).data.codeLength; + } else if (node is MethodDeclaration) { + return LazyMethodDeclaration.get(node).data.codeLength; + } else if (node is TypeParameter) { + return LazyTypeParameter.get(node).data.codeLength; + } else if (node is VariableDeclaration) { + return LazyVariableDeclaration.get(node).data.codeLength; + } + throw UnimplementedError('${node.runtimeType}'); + } + + int getCodeOffset(AstNode node) { + if (node is ClassDeclaration) { + return LazyClassDeclaration.get(node).data.codeOffset; + } else if (node is ClassTypeAlias) { + return LazyClassTypeAlias.get(node).data.codeOffset; + } else if (node is ConstructorDeclaration) { + return LazyConstructorDeclaration.get(node).data.codeOffset; + } else if (node is FormalParameter) { + return LazyFormalParameter.get(node).data.codeOffset; + } else if (node is FunctionDeclaration) { + return LazyFunctionDeclaration.get(node).data.codeOffset; + } else if (node is MethodDeclaration) { + return LazyMethodDeclaration.get(node).data.codeOffset; + } else if (node is TypeParameter) { + return LazyTypeParameter.get(node).data.codeOffset; + } else if (node is VariableDeclaration) { + return LazyVariableDeclaration.get(node).data.codeOffset; + } + throw UnimplementedError('${node.runtimeType}'); } String getConstructorDeclarationName(LinkedNode node) { @@ -44,58 +116,143 @@ return ''; } + Iterable<ConstructorDeclaration> getConstructors(AstNode node) sync* { + if (node is ClassOrMixinDeclaration) { + var members = _getClassOrMixinMembers(node); + for (var member in members) { + if (member is ConstructorDeclaration) { + yield member; + } + } + } + } + + Comment getDocumentationComment(AstNode node) { + if (node is ClassDeclaration) { + LazyClassDeclaration.readDocumentationComment(_astReader, node); + return node.documentationComment; + } else if (node is ClassTypeAlias) { + LazyClassTypeAlias.readDocumentationComment(_astReader, node); + return node.documentationComment; + } else if (node is ConstructorDeclaration) { + LazyConstructorDeclaration.readDocumentationComment(_astReader, node); + return node.documentationComment; + } else if (node is EnumConstantDeclaration) { + LazyEnumConstantDeclaration.readDocumentationComment(_astReader, node); + return node.documentationComment; + } else if (node is EnumDeclaration) { + LazyEnumDeclaration.readDocumentationComment(_astReader, node); + return node.documentationComment; + } else if (node is FunctionDeclaration) { + LazyFunctionDeclaration.readDocumentationComment(_astReader, node); + return node.documentationComment; + } else if (node is FunctionTypeAlias) { + LazyFunctionTypeAlias.readDocumentationComment(_astReader, node); + return node.documentationComment; + } else if (node is GenericTypeAlias) { + LazyGenericTypeAlias.readDocumentationComment(_astReader, node); + return node.documentationComment; + } else if (node is MethodDeclaration) { + LazyMethodDeclaration.readDocumentationComment(_astReader, node); + return node.documentationComment; + } else if (node is MixinDeclaration) { + LazyMixinDeclaration.readDocumentationComment(_astReader, node); + return node.documentationComment; + } else if (node is VariableDeclaration) { + var parent2 = node.parent.parent; + if (parent2 is FieldDeclaration) { + LazyFieldDeclaration.readDocumentationComment(_astReader, parent2); + return parent2.documentationComment; + } else if (parent2 is TopLevelVariableDeclaration) { + LazyTopLevelVariableDeclaration.readDocumentationComment( + _astReader, + parent2, + ); + return parent2.documentationComment; + } else { + throw UnimplementedError('${parent2.runtimeType}'); + } + } else { + throw UnimplementedError('${node.runtimeType}'); + } + } + + List<EnumConstantDeclaration> getEnumConstants(EnumDeclaration node) { + LazyEnumDeclaration.readConstants(_astReader, node); + return node.constants; + } + + Iterable<VariableDeclaration> getFields(ClassOrMixinDeclaration node) sync* { + var members = _getClassOrMixinMembers(node); + for (var member in members) { + if (member is FieldDeclaration) { + for (var field in member.fields.variables) { + yield field; + } + } + } + } + String getFormalParameterName(LinkedNode node) { return getSimpleName(node.normalFormalParameter_identifier); } - List<LinkedNode> getFormalParameters(LinkedNode node) { - LinkedNode parameterList; - var kind = node.kind; - if (kind == LinkedNodeKind.constructorDeclaration) { - parameterList = node.constructorDeclaration_parameters; - } else if (kind == LinkedNodeKind.functionDeclaration) { - return getFormalParameters(node.functionDeclaration_functionExpression); - } else if (kind == LinkedNodeKind.functionExpression) { - parameterList = node.functionExpression_formalParameters; - } else if (kind == LinkedNodeKind.functionTypeAlias) { - parameterList = node.functionTypeAlias_formalParameters; - } else if (kind == LinkedNodeKind.genericFunctionType) { - parameterList = node.genericFunctionType_formalParameters; - } else if (kind == LinkedNodeKind.methodDeclaration) { - parameterList = node.methodDeclaration_formalParameters; + List<FormalParameter> getFormalParameters(AstNode node) { + if (node is ConstructorDeclaration) { + LazyConstructorDeclaration.readFormalParameters(_astReader, node); + return node.parameters.parameters; + } else if (node is FunctionDeclaration) { + LazyFunctionDeclaration.readFunctionExpression(_astReader, node); + return getFormalParameters(node.functionExpression); + } else if (node is FunctionExpression) { + LazyFunctionExpression.readFormalParameters(_astReader, node); + return node.parameters?.parameters; + } else if (node is FunctionTypeAlias) { + LazyFunctionTypeAlias.readFormalParameters(_astReader, node); + return node.parameters.parameters; + } else if (node is GenericFunctionType) { + LazyGenericFunctionType.readFormalParameters(_astReader, node); + return node.parameters.parameters; + } else if (node is MethodDeclaration) { + LazyMethodDeclaration.readFormalParameters(_astReader, node); + return node.parameters?.parameters; } else { - throw UnimplementedError('$kind'); + throw UnimplementedError('${node.runtimeType}'); } - return parameterList?.formalParameterList_parameters; +// if (kind == LinkedNodeKind.constructorDeclaration) { +// parameterList = node.constructorDeclaration_parameters; +// } else if (kind == LinkedNodeKind.functionDeclaration) { +// return getFormalParameters(node.functionDeclaration_functionExpression); +// } else if (kind == LinkedNodeKind.functionExpression) { +// parameterList = node.functionExpression_formalParameters; +// } else if (kind == LinkedNodeKind.functionTypeAlias) { +// parameterList = node.functionTypeAlias_formalParameters; +// } else if (kind == LinkedNodeKind.genericFunctionType) { +// parameterList = node.genericFunctionType_formalParameters; +// } else if (kind == LinkedNodeKind.methodDeclaration) { +// parameterList = node.methodDeclaration_formalParameters; +// } else { +// throw UnimplementedError('$kind'); +// } } - DartType getFormalParameterType(LinkedNode node) { - var kind = node.kind; - if (kind == LinkedNodeKind.defaultFormalParameter) { - return getFormalParameterType(node.defaultFormalParameter_parameter); - } - if (kind == LinkedNodeKind.fieldFormalParameter) { - return getType(node.fieldFormalParameter_type2); - } - if (kind == LinkedNodeKind.functionTypedFormalParameter) { - return getType(node.functionTypedFormalParameter_type2); - } - if (kind == LinkedNodeKind.simpleFormalParameter) { - return getType(node.simpleFormalParameter_type2); - } - throw UnimplementedError('$kind'); + GenericFunctionType getGeneticTypeAliasFunction(GenericTypeAlias node) { + LazyGenericTypeAlias.readFunctionType(_astReader, node); + return node.functionType; } - LinkedNode getImplementsClause(LinkedNode node) { - var kind = node.kind; - if (kind == LinkedNodeKind.classDeclaration) { - return node.classOrMixinDeclaration_implementsClause; - } else if (kind == LinkedNodeKind.classTypeAlias) { - return node.classTypeAlias_implementsClause; - } else if (kind == LinkedNodeKind.mixinDeclaration) { - return node.classOrMixinDeclaration_implementsClause; + ImplementsClause getImplementsClause(AstNode node) { + if (node is ClassDeclaration) { + LazyClassDeclaration.readImplementsClause(_astReader, node); + return node.implementsClause; + } else if (node is ClassTypeAlias) { + LazyClassTypeAlias.readImplementsClause(_astReader, node); + return node.implementsClause; + } else if (node is MixinDeclaration) { + LazyMixinDeclaration.readImplementsClause(_astReader, node); + return node.implementsClause; } else { - throw UnimplementedError('$kind'); + throw UnimplementedError('${node.runtimeType}'); } } @@ -103,61 +260,135 @@ return bundleContext.getInterfaceType(linkedType); } - List<LinkedNode> getLibraryMetadataOrEmpty(LinkedNode unit) { - for (var directive in unit.compilationUnit_directives) { - if (directive.kind == LinkedNodeKind.libraryDirective) { - return getMetadataOrEmpty(directive); + List<Annotation> getLibraryMetadata(CompilationUnit unit) { + for (var directive in unit.directives) { + if (directive is LibraryDirective) { + return getMetadata(directive); } } - return const <LinkedNode>[]; + return const <Annotation>[]; } - List<LinkedNode> getMetadataOrEmpty(LinkedNode node) { - var kind = node.kind; - if (kind == LinkedNodeKind.classDeclaration || - kind == LinkedNodeKind.classTypeAlias || - kind == LinkedNodeKind.constructorDeclaration || - kind == LinkedNodeKind.enumConstantDeclaration || - kind == LinkedNodeKind.enumDeclaration || - kind == LinkedNodeKind.exportDirective || - kind == LinkedNodeKind.functionDeclaration || - kind == LinkedNodeKind.functionTypeAlias || - kind == LinkedNodeKind.libraryDirective || - kind == LinkedNodeKind.importDirective || - kind == LinkedNodeKind.methodDeclaration || - kind == LinkedNodeKind.mixinDeclaration || - kind == LinkedNodeKind.partDirective || - kind == LinkedNodeKind.partOfDirective || - kind == LinkedNodeKind.variableDeclaration) { - return node.annotatedNode_metadata; + List<Annotation> getMetadata(AstNode node) { + if (node is ClassDeclaration) { + LazyClassDeclaration.readMetadata(_astReader, node); + return node.metadata; + } else if (node is ClassTypeAlias) { + LazyClassTypeAlias.readMetadata(_astReader, node); + return node.metadata; + } else if (node is CompilationUnit) { + assert(node == _unit); + return _getPartDirectiveAnnotation(); + } else if (node is ConstructorDeclaration) { + LazyConstructorDeclaration.readMetadata(_astReader, node); + return node.metadata; + } else if (node is DefaultFormalParameter) { + return getMetadata(node.parameter); + } else if (node is Directive) { + LazyDirective.readMetadata(_astReader, node); + return node.metadata; + } else if (node is EnumConstantDeclaration) { + LazyEnumConstantDeclaration.readMetadata(_astReader, node); + return node.metadata; + } else if (node is EnumDeclaration) { + LazyEnumDeclaration.readMetadata(_astReader, node); + return node.metadata; + } else if (node is FormalParameter) { + LazyFormalParameter.readMetadata(_astReader, node); + return node.metadata; + } else if (node is FunctionDeclaration) { + LazyFunctionDeclaration.readMetadata(_astReader, node); + return node.metadata; + } else if (node is FunctionTypeAlias) { + LazyFunctionTypeAlias.readMetadata(_astReader, node); + return node.metadata; + } else if (node is MethodDeclaration) { + LazyMethodDeclaration.readMetadata(_astReader, node); + return node.metadata; + } else if (node is VariableDeclaration) { + var parent2 = node.parent.parent; + if (parent2 is FieldDeclaration) { + LazyFieldDeclaration.readMetadata(_astReader, parent2); + return parent2.metadata; + } else if (parent2 is TopLevelVariableDeclaration) { + LazyTopLevelVariableDeclaration.readMetadata(_astReader, parent2); + return parent2.metadata; + } } - if (kind == LinkedNodeKind.defaultFormalParameter) { - return getMetadataOrEmpty(node.defaultFormalParameter_parameter); - } - if (kind == LinkedNodeKind.fieldFormalParameter || - kind == LinkedNodeKind.functionTypedFormalParameter || - kind == LinkedNodeKind.simpleFormalParameter) { - return node.normalFormalParameter_metadata; - } - return const <LinkedNode>[]; +// var kind = node.kind; +// if (kind == LinkedNodeKind.classDeclaration || +// kind == LinkedNodeKind.classTypeAlias || +// kind == LinkedNodeKind.constructorDeclaration || +// kind == LinkedNodeKind.enumConstantDeclaration || +// kind == LinkedNodeKind.enumDeclaration || +// kind == LinkedNodeKind.exportDirective || +// kind == LinkedNodeKind.functionDeclaration || +// kind == LinkedNodeKind.functionTypeAlias || +// kind == LinkedNodeKind.libraryDirective || +// kind == LinkedNodeKind.importDirective || +// kind == LinkedNodeKind.methodDeclaration || +// kind == LinkedNodeKind.mixinDeclaration || +// kind == LinkedNodeKind.partDirective || +// kind == LinkedNodeKind.partOfDirective || +// kind == LinkedNodeKind.variableDeclaration) { +// return node.annotatedNode_metadata; +// } +// if (kind == LinkedNodeKind.defaultFormalParameter) { +// return getMetadataOrEmpty(node.defaultFormalParameter_parameter); +// } +// if (kind == LinkedNodeKind.fieldFormalParameter || +// kind == LinkedNodeKind.functionTypedFormalParameter || +// kind == LinkedNodeKind.simpleFormalParameter) { +// return node.normalFormalParameter_metadata; +// } + return const <Annotation>[]; } String getMethodName(LinkedNode node) { return getSimpleName(node.methodDeclaration_name); } - DartType getReturnType(LinkedNode node) { - var kind = node.kind; - if (kind == LinkedNodeKind.functionDeclaration) { - return getType(node.functionDeclaration_returnType2); - } else if (kind == LinkedNodeKind.functionTypeAlias) { - return getType(node.functionTypeAlias_returnType2); - } else if (kind == LinkedNodeKind.genericFunctionType) { - return getType(node.genericFunctionType_returnType2); - } else if (kind == LinkedNodeKind.methodDeclaration) { - return getType(node.methodDeclaration_returnType2); + Iterable<MethodDeclaration> getMethods(AstNode node) sync* { + if (node is ClassOrMixinDeclaration) { + var members = _getClassOrMixinMembers(node); + for (var member in members) { + if (member is MethodDeclaration) { + yield member; + } + } + } + } + + int getNameOffset(AstNode node) { + if (node is NamedCompilationUnitMember) { + return node.name.offset; + } else if (node is EnumConstantDeclaration) { + return node.name.offset; + } else if (node is FormalParameter) { + return node.identifier.offset; + } else if (node is VariableDeclaration) { + return node.name.offset; + } + throw UnimplementedError('${node.runtimeType}'); + } + + OnClause getOnClause(MixinDeclaration node) { + LazyMixinDeclaration.readOnClause(_astReader, node); + return node.onClause; + } + + /// Return the actual return type for the [node] - explicit or inferred. + DartType getReturnType(AstNode node) { + if (node is FunctionDeclaration) { + return LazyFunctionDeclaration.getReturnType(_astReader, node); + } else if (node is FunctionTypeAlias) { + return LazyFunctionTypeAlias.getReturnType(_astReader, node); + } else if (node is GenericFunctionType) { + return LazyGenericFunctionType.getReturnType(_astReader, node); + } else if (node is MethodDeclaration) { + return LazyMethodDeclaration.getReturnType(_astReader, node); } else { - throw UnimplementedError('$kind'); + throw UnimplementedError('${node.runtimeType}'); } } @@ -177,6 +408,18 @@ return node.simpleStringLiteral_value; } + TypeName getSuperclass(AstNode node) { + if (node is ClassDeclaration) { + LazyClassDeclaration.readExtendsClause(_astReader, node); + return node.extendsClause?.superclass; + } else if (node is ClassTypeAlias) { + LazyClassTypeAlias.readSuperclass(_astReader, node); + return node.superclass; + } else { + throw StateError('${node.runtimeType}'); + } + } + String getTokenLexeme(int token) { return tokensContext.lexeme(token); } @@ -185,16 +428,55 @@ return tokensContext.offset(token); } - DartType getType(LinkedNodeType linkedType) { - return bundleContext.getType(linkedType); + /// Return the actual type for the [node] - explicit or inferred. + DartType getType(AstNode node) { + if (node is DefaultFormalParameter) { + return getType(node.parameter); + } else if (node is FormalParameter) { + return LazyFormalParameter.getType(_astReader, node); + } else if (node is VariableDeclaration) { + return LazyVariableDeclaration.getType(_astReader, node); + } else { + throw UnimplementedError('${node.runtimeType}'); + } } - DartType getTypeAnnotationType(LinkedNode node) { - var kind = node.kind; - if (kind == LinkedNodeKind.typeName) { - return getType(node.typeName_type); + TypeAnnotation getTypeParameterBound(TypeParameter node) { + LazyTypeParameter.readBound(_astReader, node); + return node.bound; + } + + TypeParameterList getTypeParameters2(AstNode node) { + if (node is ClassDeclaration) { + LazyClassDeclaration.readTypeParameters(_astReader, node); + return node.typeParameters; + } else if (node is ClassTypeAlias) { + LazyClassTypeAlias.readTypeParameters(_astReader, node); + return node.typeParameters; + } else if (node is ConstructorDeclaration) { + return null; + } else if (node is FunctionDeclaration) { + LazyFunctionDeclaration.readFunctionExpression(_astReader, node); + return getTypeParameters2(node.functionExpression); + } else if (node is FunctionExpression) { + LazyFunctionExpression.readTypeParameters(_astReader, node); + return node.typeParameters; + } else if (node is FunctionTypeAlias) { + LazyFunctionTypeAlias.readTypeParameters(_astReader, node); + return node.typeParameters; + } else if (node is GenericFunctionType) { + return node.typeParameters; + } else if (node is GenericTypeAlias) { + LazyGenericTypeAlias.readTypeParameters(_astReader, node); + return node.typeParameters; + } else if (node is MethodDeclaration) { + LazyMethodDeclaration.readTypeParameters(_astReader, node); + return node.typeParameters; + } else if (node is MixinDeclaration) { + LazyMixinDeclaration.readTypeParameters(_astReader, node); + return node.typeParameters; } else { - throw UnimplementedError('$kind'); + throw UnimplementedError('${node.runtimeType}'); } } @@ -206,38 +488,59 @@ return getSimpleName(node.variableDeclaration_name); } - bool isAbstract(LinkedNode node) { - return node.kind == LinkedNodeKind.methodDeclaration && - node.methodDeclaration_body.kind == LinkedNodeKind.emptyFunctionBody; + WithClause getWithClause(AstNode node) { + if (node is ClassDeclaration) { + LazyClassDeclaration.readWithClause(_astReader, node); + return node.withClause; + } else if (node is ClassTypeAlias) { + LazyClassTypeAlias.readWithClause(_astReader, node); + return node.withClause; + } else { + throw UnimplementedError('${node.runtimeType}'); + } } - bool isAsynchronous(LinkedNode node) { - LinkedNode body = _getFunctionBody(node); - if (body.kind == LinkedNodeKind.blockFunctionBody) { - return isAsyncKeyword(body.blockFunctionBody_keyword); - } else if (body.kind == LinkedNodeKind.emptyFunctionBody) { + bool isAbstract(AstNode node) { + if (node is ClassDeclaration) { + return node.abstractKeyword != null; + } else if (node is ClassTypeAlias) { + return node.abstractKeyword != null; + } else if (node is FunctionDeclaration) { return false; - } else { - return isAsyncKeyword(body.expressionFunctionBody_keyword); + } else if (node is MethodDeclaration) { + return node.isAbstract; } + throw UnimplementedError('${node.runtimeType}'); + } + + bool isAsynchronous(AstNode node) { + var body = _getFunctionBody(node); + return body.isAsynchronous; } bool isAsyncKeyword(int token) { return tokensContext.type(token) == UnlinkedTokenType.ASYNC; } - bool isConst(LinkedNode node) { - var kind = node.kind; - if (kind == LinkedNodeKind.defaultFormalParameter) { - return isConst(node.defaultFormalParameter_parameter); + bool isConst(AstNode node) { + if (node is FormalParameter) { + return node.isConst; } - if (kind == LinkedNodeKind.simpleFormalParameter) { - return isConstKeyword(node.simpleFormalParameter_keyword); + if (node is VariableDeclaration) { + VariableDeclarationList parent = node.parent; + return parent.isConst; } - if (kind == LinkedNodeKind.variableDeclaration) { - return node.variableDeclaration_declaration.isConst; - } - throw UnimplementedError('$kind'); +// var kind = node.kind; +// if (kind == LinkedNodeKind.defaultFormalParameter) { +// return isConst(node.defaultFormalParameter_parameter); +// } +// if (kind == LinkedNodeKind.simpleFormalParameter) { +// return isConstKeyword(node.simpleFormalParameter_keyword); +// } +// if (kind == LinkedNodeKind.variableDeclaration) { +// return node.variableDeclaration_declaration.isConst; +// } + throw UnimplementedError('${node.runtimeType}'); } bool isConstKeyword(int token) { @@ -248,40 +551,35 @@ return isConstKeyword(node.variableDeclarationList_keyword); } - bool isExternal(LinkedNode node) { - var kind = node.kind; - if (kind == LinkedNodeKind.constructorDeclaration) { - return node.constructorDeclaration_externalKeyword != 0; - } else if (kind == LinkedNodeKind.functionDeclaration) { - return node.functionDeclaration_externalKeyword != 0; - } else if (kind == LinkedNodeKind.methodDeclaration) { - return node.methodDeclaration_externalKeyword != 0; + bool isCovariantField(AstNode node) { + if (node is VariableDeclaration) { + var parent2 = node.parent.parent; + return parent2 is FieldDeclaration && parent2.covariantKeyword != null; + } + return false; + } + + bool isExternal(AstNode node) { + if (node is ConstructorDeclaration) { + return node.externalKeyword != null; + } else if (node is FunctionDeclaration) { + return node.externalKeyword != null; + } else if (node is MethodDeclaration) { + return node.externalKeyword != null; } else { - throw UnimplementedError('$kind'); + throw UnimplementedError('${node.runtimeType}'); } } - bool isFinal(LinkedNode node) { - var kind = node.kind; - if (kind == LinkedNodeKind.defaultFormalParameter) { - return isFinal(node.defaultFormalParameter_parameter); - } - if (kind == LinkedNodeKind.enumConstantDeclaration) { + bool isFinal(AstNode node) { + if (node is EnumConstantDeclaration) { return false; } - if (kind == LinkedNodeKind.fieldFormalParameter) { - return isFinalKeyword(node.fieldFormalParameter_keyword); + if (node is VariableDeclaration) { + VariableDeclarationList parent = node.parent; + return parent.isFinal; } - if (kind == LinkedNodeKind.functionTypedFormalParameter) { - return false; - } - if (kind == LinkedNodeKind.simpleFormalParameter) { - return isFinalKeyword(node.simpleFormalParameter_keyword); - } - if (kind == LinkedNodeKind.variableDeclaration) { - return node.variableDeclaration_declaration.isFinal; - } - throw UnimplementedError('$kind'); + throw UnimplementedError('${node.runtimeType}'); } bool isFinalKeyword(int token) { @@ -296,26 +594,19 @@ return node.kind == LinkedNodeKind.functionDeclaration; } - bool isGenerator(LinkedNode node) { - LinkedNode body = _getFunctionBody(node); - if (body.kind == LinkedNodeKind.blockFunctionBody) { - return body.blockFunctionBody_star != 0; + bool isGenerator(AstNode node) { + var body = _getFunctionBody(node); + return body.isGenerator; + } + + bool isGetter(AstNode node) { + if (node is FunctionDeclaration) { + return node.isGetter; + } else if (node is MethodDeclaration) { + return node.isGetter; + } else { + throw StateError('${node.runtimeType}'); } - return false; - } - - bool isGetter(LinkedNode node) { - return isGetterMethod(node) || isGetterFunction(node); - } - - bool isGetterFunction(LinkedNode node) { - return isFunction(node) && - _isGetToken(node.functionDeclaration_propertyKeyword); - } - - bool isGetterMethod(LinkedNode node) { - return isMethod(node) && - _isGetToken(node.methodDeclaration_propertyKeyword); } bool isLibraryKeyword(int token) { @@ -326,131 +617,115 @@ return node.kind == LinkedNodeKind.methodDeclaration; } - bool isSetter(LinkedNode node) { - return isSetterMethod(node) || isSetterFunction(node); - } - - bool isSetterFunction(LinkedNode node) { - return isFunction(node) && - _isSetToken(node.functionDeclaration_propertyKeyword); - } - - bool isSetterMethod(LinkedNode node) { - return isMethod(node) && - _isSetToken(node.methodDeclaration_propertyKeyword); - } - - bool isStatic(LinkedNode node) { - var kind = node.kind; - if (kind == LinkedNodeKind.functionDeclaration) { - return true; - } else if (kind == LinkedNodeKind.methodDeclaration) { - return node.methodDeclaration_modifierKeyword != 0; - } else if (kind == LinkedNodeKind.variableDeclaration) { - return node.variableDeclaration_declaration.isStatic; + bool isSetter(AstNode node) { + if (node is FunctionDeclaration) { + return node.isSetter; + } else if (node is MethodDeclaration) { + return node.isSetter; + } else { + throw StateError('${node.runtimeType}'); } - throw UnimplementedError('$kind'); + } + + bool isStatic(AstNode node) { + if (node is FunctionDeclaration) { + return true; + } else if (node is MethodDeclaration) { + return node.modifierKeyword != null; + } else if (node is VariableDeclaration) { + var parent2 = node.parent.parent; + return parent2 is FieldDeclaration && parent2.isStatic; + } + throw UnimplementedError('${node.runtimeType}'); } bool isSyncKeyword(int token) { return tokensContext.type(token) == UnlinkedTokenType.SYNC; } - void loadClassMemberReferences(Reference reference) { - var node = reference.node; - if (node.kind != LinkedNodeKind.classDeclaration && - node.kind != LinkedNodeKind.mixinDeclaration) { - return; + Expression readInitializer(ElementImpl enclosing, AstNode node) { + if (node is DefaultFormalParameter) { + LazyFormalParameter.readDefaultValue(_astReader, node); + return node.defaultValue; + } else if (node is VariableDeclaration) { + LazyVariableDeclaration.readInitializer(_astReader, node); + return node.initializer; + } else { + throw StateError('${node.runtimeType}'); } - - var constructorContainerRef = reference.getChild('@constructor'); - var fieldContainerRef = reference.getChild('@field'); - var methodContainerRef = reference.getChild('@method'); - var getterContainerRef = reference.getChild('@getter'); - var setterContainerRef = reference.getChild('@setter'); - for (var member in node.classOrMixinDeclaration_members) { - if (member.kind == LinkedNodeKind.constructorDeclaration) { - var name = getConstructorDeclarationName(member); - constructorContainerRef.getChild(name).node = member; - } else if (member.kind == LinkedNodeKind.fieldDeclaration) { - var variableList = member.fieldDeclaration_fields; - for (var field in variableList.variableDeclarationList_variables) { - var name = getSimpleName(field.variableDeclaration_name); - fieldContainerRef.getChild(name).node = field; - } - } else if (member.kind == LinkedNodeKind.methodDeclaration) { - var name = getSimpleName(member.methodDeclaration_name); - var propertyKeyword = member.methodDeclaration_propertyKeyword; - if (_isGetToken(propertyKeyword)) { - getterContainerRef.getChild(name).node = member; - } else if (_isSetToken(propertyKeyword)) { - setterContainerRef.getChild(name).node = member; - } else { - methodContainerRef.getChild(name).node = member; - } - } - } - } - - Expression readInitializer(ElementImpl enclosing, LinkedNode linkedNode) { - var reader = AstBinaryReader(this); - return reader.withLocalScope(enclosing, () { - if (linkedNode.kind == LinkedNodeKind.defaultFormalParameter) { - var data = linkedNode.defaultFormalParameter_defaultValue; - return reader.readNode(data); - } - var data = linkedNode.variableDeclaration_initializer; - return reader.readNode(data); - }); } AstNode readNode(LinkedNode linkedNode) { - var reader = AstBinaryReader(this); - return reader.readNode(linkedNode); + return _astReader.readNode(linkedNode); } void setReturnType(LinkedNodeBuilder node, DartType type) { - var typeData = bundleContext.linking.writeType(type); - node.functionDeclaration_returnType2 = typeData; + throw UnimplementedError(); +// var typeData = bundleContext.linking.writeType(type); +// node.functionDeclaration_returnType2 = typeData; } void setVariableType(LinkedNodeBuilder node, DartType type) { - var typeData = bundleContext.linking.writeType(type); - node.simpleFormalParameter_type2 = typeData; + throw UnimplementedError(); +// var typeData = bundleContext.linking.writeType(type); +// node.simpleFormalParameter_type2 = typeData; } - Iterable<LinkedNode> topLevelVariables(LinkedNode unit) sync* { - for (var declaration in unit.compilationUnit_declarations) { - if (declaration.kind == LinkedNodeKind.topLevelVariableDeclaration) { - var variableList = declaration.topLevelVariableDeclaration_variableList; - for (var variable in variableList.variableDeclarationList_variables) { + Iterable<VariableDeclaration> topLevelVariables(CompilationUnit unit) sync* { + for (var declaration in unit.declarations) { + if (declaration is TopLevelVariableDeclaration) { + for (var variable in declaration.variables.variables) { yield variable; } } } } - LinkedNode _getFunctionBody(LinkedNode node) { - var kind = node.kind; - if (kind == LinkedNodeKind.constructorDeclaration) { - return node.constructorDeclaration_body; - } else if (kind == LinkedNodeKind.functionDeclaration) { - return _getFunctionBody(node.functionDeclaration_functionExpression); - } else if (kind == LinkedNodeKind.functionExpression) { - return node.functionExpression_body; - } else if (kind == LinkedNodeKind.methodDeclaration) { - return node.methodDeclaration_body; + List<ClassMember> _getClassOrMixinMembers(ClassOrMixinDeclaration node) { + if (node is ClassDeclaration) { + LazyClassDeclaration.readMembers(_astReader, node); + } else if (node is MixinDeclaration) { + LazyMixinDeclaration.readMembers(_astReader, node); } else { - throw UnimplementedError('$kind'); + throw StateError('${node.runtimeType}'); + } + return node.members; + } + + FunctionBody _getFunctionBody(AstNode node) { + if (node is ConstructorDeclaration) { + LazyConstructorDeclaration.readBody(_astReader, node); + return node.body; + } else if (node is FunctionDeclaration) { + LazyFunctionDeclaration.readFunctionExpression(_astReader, node); + return _getFunctionBody(node.functionExpression); + } else if (node is FunctionExpression) { + LazyFunctionExpression.readBody(_astReader, node); + return node.body; + } else if (node is MethodDeclaration) { + LazyMethodDeclaration.readBody(_astReader, node); + return node.body; + } else { + throw UnimplementedError('${node.runtimeType}'); } } - bool _isGetToken(int token) { - return tokensContext.type(token) == UnlinkedTokenType.GET; - } - - bool _isSetToken(int token) { - return tokensContext.type(token) == UnlinkedTokenType.SET; + NodeList<Annotation> _getPartDirectiveAnnotation() { + if (indexInLibrary != 0) { + var definingContext = libraryContext.definingUnit; + var unit = definingContext.unit; + var partDirectiveIndex = 0; + for (var directive in unit.directives) { + if (directive is PartDirective) { + partDirectiveIndex++; + if (partDirectiveIndex == indexInLibrary) { + LazyDirective.readMetadata(definingContext._astReader, directive); + return directive.metadata; + } + } + } + } + throw StateError('Expected to find $indexInLibrary part directive.'); } static List<LinkedNode> getTypeParameters(LinkedNode node) {
diff --git a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart index 6eb82be..e089151 100644 --- a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart +++ b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
@@ -3,153 +3,171 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/dart/ast/ast.dart'; -import 'package:analyzer/dart/ast/standard_ast_factory.dart'; +import 'package:analyzer/dart/ast/visitor.dart'; +import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/generated/resolver.dart'; -import 'package:analyzer/src/summary/format.dart'; -import 'package:analyzer/src/summary/idl.dart'; -import 'package:analyzer/src/summary2/ast_binary_reader.dart'; import 'package:analyzer/src/summary2/ast_resolver.dart'; -import 'package:analyzer/src/summary2/builder/source_library_builder.dart'; import 'package:analyzer/src/summary2/link.dart'; -import 'package:analyzer/src/summary2/reference.dart'; -class MetadataResolver { - AstResolver _astResolver; +class MetadataResolver extends ThrowingAstVisitor<void> { + final Linker _linker; + final LibraryElement _libraryElement; - MetadataResolver(Linker linker, Reference libraryRef) { - var libraryElement = linker.elementFactory.elementOfReference(libraryRef); - var libraryScope = LibraryScope(libraryElement); - _astResolver = AstResolver(linker, libraryElement, libraryScope); + Scope scope; + + MetadataResolver(this._linker, this._libraryElement); + + @override + void visitAnnotation(Annotation node) { + // TODO(scheglov) get rid of? + node.elementAnnotation = ElementAnnotationImpl(null); + + var astResolver = AstResolver(_linker, _libraryElement, scope); + // TODO(scheglov) enclosing elements? + astResolver.resolve(node); } - void resolve(UnitBuilder unit) { - var unitDirectives = unit.node.compilationUnit_directives; - for (var directive in unitDirectives) { - _annotatedNode(unit, directive); - } - - var unitDeclarations = unit.node.compilationUnit_declarations; - for (LinkedNodeBuilder unitDeclaration in unitDeclarations) { - var kind = unitDeclaration.kind; - if (_isAnnotatedNode(kind)) { - _annotatedNode(unit, unitDeclaration); - } - if (kind == LinkedNodeKind.classDeclaration) { - _class(unit, unitDeclaration); - } else if (kind == LinkedNodeKind.enumDeclaration) { - _enumDeclaration(unit, unitDeclaration); - } else if (kind == LinkedNodeKind.functionDeclaration) { - var function = unitDeclaration.functionDeclaration_functionExpression; - _formalParameterList( - unit, - function.functionExpression_formalParameters, - ); - } else if (kind == LinkedNodeKind.topLevelVariableDeclaration) { - _variables( - unit, - unitDeclaration, - unitDeclaration.topLevelVariableDeclaration_variableList, - ); - } - } + @override + void visitClassDeclaration(ClassDeclaration node) { + node.metadata.accept(this); + node.typeParameters?.accept(this); + node.members.accept(this); } - void _annotatedNode(UnitBuilder unit, LinkedNodeBuilder node) { - var unresolved = node.annotatedNode_metadata; - var resolved = _list(unit, unresolved); - node.annotatedNode_metadata = resolved; + @override + void visitClassTypeAlias(ClassTypeAlias node) { + node.metadata.accept(this); + node.typeParameters?.accept(this); } - void _class(UnitBuilder unit, LinkedNodeBuilder unitDeclaration) { - var members = unitDeclaration.classOrMixinDeclaration_members; - for (var classMember in members) { - var kind = classMember.kind; - if (_isAnnotatedNode(kind)) { - _annotatedNode(unit, classMember); - } - if (kind == LinkedNodeKind.constructorDeclaration) { - _formalParameterList( - unit, - classMember.constructorDeclaration_parameters, - ); - } else if (kind == LinkedNodeKind.fieldDeclaration) { - _variables( - unit, - classMember, - classMember.fieldDeclaration_fields, - ); - } else if (kind == LinkedNodeKind.methodDeclaration) { - _formalParameterList( - unit, - classMember.methodDeclaration_formalParameters, - ); - } - } + @override + void visitCompilationUnit(CompilationUnit node) { + node.directives.accept(this); + node.declarations.accept(this); } - void _enumDeclaration(UnitBuilder unit, LinkedNodeBuilder node) { - for (var constant in node.enumDeclaration_constants) { - var kind = constant.kind; - if (kind == LinkedNodeKind.enumConstantDeclaration) { - _annotatedNode(unit, constant); - } - } + @override + void visitConstructorDeclaration(ConstructorDeclaration node) { + node.metadata.accept(this); + node.parameters.accept(this); } - void _formalParameterList(UnitBuilder unit, LinkedNodeBuilder node) { - if (node == null) return; - - for (var parameter in node.formalParameterList_parameters) { - if (parameter.kind == LinkedNodeKind.defaultFormalParameter) { - var actual = parameter.defaultFormalParameter_parameter; - var unresolved = actual.normalFormalParameter_metadata; - var resolved = _list(unit, unresolved); - actual.normalFormalParameter_metadata = resolved; - } else { - var unresolved = parameter.normalFormalParameter_metadata; - var resolved = _list(unit, unresolved); - parameter.normalFormalParameter_metadata = resolved; - } - } + @override + void visitDefaultFormalParameter(DefaultFormalParameter node) { + node.parameter.accept(this); } - List<LinkedNodeBuilder> _list(UnitBuilder unit, List<LinkedNode> unresolved) { - var resolved = List<LinkedNodeBuilder>(unresolved.length); - for (var i = 0; i < unresolved.length; ++i) { - var unresolvedNode = unresolved[i]; - - var reader = AstBinaryReader(unit.context); - var ast = reader.readNode(unresolvedNode) as Annotation; - ast.elementAnnotation = ElementAnnotationImpl(null); - - // Set some parent, so that resolver does not bail out. - astFactory.libraryDirective(null, [ast], null, null, null); - - var resolvedNode = _astResolver.resolve(unit.context, ast); - resolved[i] = resolvedNode; - } - return resolved; + @override + void visitEnumConstantDeclaration(EnumConstantDeclaration node) { + node.metadata.accept(this); } - /// Resolve annotations of the [declaration] (field or top-level variable), - /// and set them as metadata for each variable in the [variableList]. - void _variables(UnitBuilder unit, LinkedNodeBuilder declaration, - LinkedNodeBuilder variableList) { - for (var variable in variableList.variableDeclarationList_variables) { - var unresolved = declaration.annotatedNode_metadata; - var resolved = _list(unit, unresolved); - variable.annotatedNode_metadata = resolved; - } + @override + void visitEnumDeclaration(EnumDeclaration node) { + node.metadata.accept(this); + node.constants.accept(this); } - static bool _isAnnotatedNode(LinkedNodeKind kind) { - return kind == LinkedNodeKind.classDeclaration || - kind == LinkedNodeKind.classTypeAlias || - kind == LinkedNodeKind.constructorDeclaration || - kind == LinkedNodeKind.enumDeclaration || - kind == LinkedNodeKind.functionDeclaration || - kind == LinkedNodeKind.functionTypeAlias || - kind == LinkedNodeKind.methodDeclaration; + @override + void visitExportDirective(ExportDirective node) { + node.metadata.accept(this); + } + + @override + void visitFieldDeclaration(FieldDeclaration node) { + node.metadata.accept(this); + } + + @override + void visitFieldFormalParameter(FieldFormalParameter node) { + node.metadata.accept(this); + node.parameters?.accept(this); + } + + @override + void visitFormalParameterList(FormalParameterList node) { + node.parameters.accept(this); + } + + @override + void visitFunctionDeclaration(FunctionDeclaration node) { + node.metadata.accept(this); + node.functionExpression.accept(this); + } + + @override + void visitFunctionExpression(FunctionExpression node) { + node.typeParameters?.accept(this); + node.parameters?.accept(this); + } + + @override + void visitFunctionTypeAlias(FunctionTypeAlias node) { + node.metadata.accept(this); + node.typeParameters?.accept(this); + node.parameters.accept(this); + } + + @override + void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { + node.metadata.accept(this); + node.typeParameters?.accept(this); + node.parameters.accept(this); + } + + @override + void visitGenericTypeAlias(GenericTypeAlias node) { + // TODO: implement visitGenericTypeAlias +// super.visitGenericTypeAlias(node); + } + + @override + void visitImportDirective(ImportDirective node) { + node.metadata.accept(this); + } + + @override + void visitLibraryDirective(LibraryDirective node) { + node.metadata.accept(this); + } + + @override + void visitMethodDeclaration(MethodDeclaration node) { + node.metadata.accept(this); + node.typeParameters?.accept(this); + node.parameters?.accept(this); + } + + @override + void visitMixinDeclaration(MixinDeclaration node) { + // TODO: implement visitMixinDeclaration +// super.visitMixinDeclaration(node); + } + + @override + void visitPartDirective(PartDirective node) { + node.metadata.accept(this); + } + + @override + void visitPartOfDirective(PartOfDirective node) { + node.metadata.accept(this); + } + + @override + void visitSimpleFormalParameter(SimpleFormalParameter node) { + node.metadata.accept(this); + } + + @override + void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { + node.metadata.accept(this); + } + + @override + void visitTypeParameterList(TypeParameterList node) { + // TODO: implement visitTypeParameterList +// super.visitTypeParameterList(node); } }
diff --git a/pkg/analyzer/lib/src/summary2/reference.dart b/pkg/analyzer/lib/src/summary2/reference.dart index 234ed5d..7f8af39 100644 --- a/pkg/analyzer/lib/src/summary2/reference.dart +++ b/pkg/analyzer/lib/src/summary2/reference.dart
@@ -2,6 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/src/summary/idl.dart'; import 'package:analyzer/src/summary2/scope.dart'; @@ -35,6 +36,9 @@ /// The corresponding [LinkedNode], or `null` if a named container. LinkedNode node; + /// The corresponding [AstNode], or `null` if a named container. + AstNode node2; + /// The corresponding [Element], or `null` if a named container. Element element; @@ -50,16 +54,23 @@ Reference._(this.parent, this.name); + Iterable<Reference> get children { + if (_children != null) { + return _children.values; + } + return const []; + } + bool get isClass => parent != null && parent.name == '@class'; bool get isDynamic => name == 'dynamic' && parent?.name == 'dart:core'; bool get isEnum => parent != null && parent.name == '@enum'; - bool get isGenericTypeAlias => parent != null && parent.name == '@typeAlias'; - bool get isPrefix => parent != null && parent.name == '@prefix'; + bool get isTypeAlias => parent != null && parent.name == '@typeAlias'; + bool get isTypeParameter => parent != null && parent.name == '@typeParameter'; int get numOfChildren => _children != null ? _children.length : 0;
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart index c76cd0b..4d27523e 100644 --- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart +++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -2,12 +2,523 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/src/summary/format.dart'; +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer/dart/ast/visitor.dart'; +import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/src/dart/element/element.dart'; +import 'package:analyzer/src/dart/element/type.dart'; +import 'package:analyzer/src/dart/resolver/scope.dart'; import 'package:analyzer/src/summary/idl.dart'; -import 'package:analyzer/src/summary2/builder/source_library_builder.dart'; -import 'package:analyzer/src/summary2/linking_bundle_context.dart'; +import 'package:analyzer/src/summary2/linked_element_factory.dart'; import 'package:analyzer/src/summary2/reference.dart'; -import 'package:analyzer/src/summary2/scope.dart'; +import 'package:analyzer/src/summary2/type_builder.dart'; + +// TODO(scheglov) This class is not used, not [get] yet. +class LinkingNodeContext { + static const _key = 'linkingNodeContext'; + + final Scope scope; + + LinkingNodeContext(this.scope); + + static LinkingNodeContext get(AstNode node) { + LinkingNodeContext context = node.getProperty(_key); + if (context == null) { + throw StateError('No context for: $node'); + } + return context; + } + + static void set(AstNode node, LinkingNodeContext context) { + node.setProperty(_key, context); + } +} + +//class ReferenceResolver { +// final LinkingBundleContext linkingBundleContext; +// final TypesToBuild typesToBuild; +// final UnitBuilder unit; +// +// /// TODO(scheglov) Update scope with local scopes (formal / type parameters). +// Scope scope; +// +// Reference reference; +// +// ReferenceResolver( +// this.linkingBundleContext, +// this.typesToBuild, +// this.unit, +// this.scope, +// this.reference, +// ); +// +// LinkedNodeTypeBuilder get _dynamicType { +// return LinkedNodeTypeBuilder( +// kind: LinkedNodeTypeKind.dynamic_, +// ); +// } +// +// void resolve() { +// _node(unit.node); +// } +// +// void _classDeclaration(LinkedNodeBuilder node) { +// var name = unit.context.getUnitMemberName(node); +// reference = reference.getChild('@class').getChild(name); +// +// var typeParameters = node.classOrMixinDeclaration_typeParameters; +// _withTypeParameters(typeParameters, () { +// _extendsClause(node.classDeclaration_extendsClause); +// _withClause(node.classDeclaration_withClause); +// _implementsClause(node.classOrMixinDeclaration_implementsClause); +// +// for (var member in node.classOrMixinDeclaration_members) { +// if (member.kind != LinkedNodeKind.constructorDeclaration) { +// _node(member); +// } +// } +// for (var member in node.classOrMixinDeclaration_members) { +// if (member.kind == LinkedNodeKind.constructorDeclaration) { +// _node(member); +// } +// } +// }); +// +// reference = reference.parent.parent; +// } +// +// void _classTypeAlias(LinkedNodeBuilder node) { +// var name = unit.context.getUnitMemberName(node); +// reference = reference.getChild('@class').getChild(name); +// +// var typeParameters = node.classTypeAlias_typeParameters; +// _withTypeParameters(typeParameters, () { +// _typeName(node.classTypeAlias_superclass); +// _withClause(node.classTypeAlias_withClause); +// _implementsClause(node.classTypeAlias_implementsClause); +// }); +// +// reference = reference.parent.parent; +// } +// +// void _compilationUnit(LinkedNodeBuilder node) { +// _nodeList(node.compilationUnit_directives); +// _nodeList(node.compilationUnit_declarations); +// } +// +// void _constructorDeclaration(LinkedNodeBuilder node) { +// _node(node.constructorDeclaration_parameters); +// } +// +// void _enumConstantDeclaration(LinkedNodeBuilder node) {} +// +// void _enumDeclaration(LinkedNodeBuilder node) { +// _nodeList(node.enumDeclaration_constants); +// } +// +// void _exportDirective(LinkedNodeBuilder node) {} +// +// void _extendsClause(LinkedNodeBuilder node) { +// if (node == null) return; +// +// _typeName(node.extendsClause_superclass); +// } +// +// void _fieldDeclaration(LinkedNodeBuilder node) { +// _node(node.fieldDeclaration_fields); +// } +// +// void _fieldFormalParameter(LinkedNodeBuilder node) { +// var typeNode = node.fieldFormalParameter_type; +// if (typeNode != null) { +// _node(typeNode); +// } +// +// var formalParameters = node.fieldFormalParameter_formalParameters; +// if (formalParameters != null) { +// _formalParameters(formalParameters); +// } +// +// if (typeNode != null || formalParameters != null) { +// typesToBuild.declarations.add(node); +// } +// } +// +// void _formalParameters(LinkedNodeBuilder node) { +// for (var parameter in node.formalParameterList_parameters) { +// _node(parameter); +// } +// } +// +// void _functionDeclaration(LinkedNodeBuilder node) { +// var name = unit.context.getUnitMemberName(node); +// reference = reference.getChild('@function').getChild(name); +// +// var function = node.functionDeclaration_functionExpression; +// var typeParameters = function.functionExpression_typeParameters; +// _withTypeParameters(typeParameters, () { +// var returnType = node.functionDeclaration_returnType; +// if (returnType != null) { +// _node(returnType); +// typesToBuild.declarations.add(node); +// } else { +// node.functionDeclaration_returnType2 = _dynamicType; +// } +// +// _node(function.functionExpression_formalParameters); +// }); +// +// reference = reference.parent.parent; +// } +// +// void _functionExpression(LinkedNodeBuilder node) { +// var typeParameters = node.functionExpression_typeParameters; +// _withTypeParameters(typeParameters, () { +// _node(node.functionExpression_formalParameters); +// }); +// } +// +// void _functionTypeAlias(LinkedNodeBuilder node) { +// var name = unit.context.getUnitMemberName(node); +// reference = reference.getChild('@typeAlias').getChild(name); +// +// var typeParameters = node.functionTypeAlias_typeParameters; +// _withTypeParameters(typeParameters, () { +// var returnType = node.functionTypeAlias_returnType; +// if (returnType != null) { +// _node(returnType); +// typesToBuild.declarations.add(node); +// } else { +// node.functionTypeAlias_returnType2 = _dynamicType; +// } +// +// _node(node.functionTypeAlias_formalParameters); +// }); +// +// reference = reference.parent.parent; +// } +// +// void _functionTypedFormalParameter(LinkedNodeBuilder node) { +// var typeParameters = node.functionTypedFormalParameter_typeParameters; +// _withTypeParameters(typeParameters, () { +// var typeNode = node.functionTypedFormalParameter_returnType; +// if (typeNode != null) { +// _node(typeNode); +// } +// +// _formalParameters(node.functionTypedFormalParameter_formalParameters); +// typesToBuild.declarations.add(node); +// }); +// } +// +// void _genericFunctionType(LinkedNodeBuilder node) { +// reference = reference.getChild('@function'); +// +// var name = '${reference.numOfChildren}'; +// reference = reference.getChild(name); +// +// var typeParameters = node.genericFunctionType_typeParameters; +// _withTypeParameters(typeParameters, () { +// var returnType = node.genericFunctionType_returnType; +// if (returnType != null) { +// _node(returnType); +// typesToBuild.declarations.add(node); +// } +// +// _formalParameters(node.genericFunctionType_formalParameters); +// +// typesToBuild.typeAnnotations.add(node); +// }); +// +// reference = reference.parent.parent; +// } +// +// void _genericTypeAlias(LinkedNodeBuilder node) { +// var name = unit.context.getSimpleName( +// node.namedCompilationUnitMember_name, +// ); +// reference = reference.getChild('@typeAlias').getChild(name); +// +// var typeParameters = node.genericTypeAlias_typeParameters; +// _withTypeParameters(typeParameters, () { +// _node(node.genericTypeAlias_functionType); +// }); +// +// reference = reference.parent.parent; +// } +// +// void _implementsClause(LinkedNodeBuilder node) { +// if (node == null) return; +// +// _typeNameList(node.implementsClause_interfaces); +// } +// +// void _importDirective(LinkedNodeBuilder node) {} +// +// void _libraryDirective(LinkedNodeBuilder node) {} +// +// void _methodDeclaration(LinkedNodeBuilder node) { +// var name = unit.context.getMethodName(node); +// reference = reference.getChild('@method').getChild(name); +// +// var typeParameters = node.methodDeclaration_typeParameters; +// _withTypeParameters(typeParameters, () { +// var returnType = node.methodDeclaration_returnType; +// if (returnType != null) { +// _node(returnType); +// typesToBuild.declarations.add(node); +// } +// +// _node(node.methodDeclaration_formalParameters); +// }); +// +// reference = reference.parent.parent; +// } +// +// void _mixinDeclaration(LinkedNodeBuilder node) { +// var name = unit.context.getUnitMemberName(node); +// reference = reference.getChild('@class').getChild(name); +// +// var typeParameters = node.classOrMixinDeclaration_typeParameters; +// _withTypeParameters(typeParameters, () { +// _onClause(node.mixinDeclaration_onClause); +// _implementsClause(node.classOrMixinDeclaration_implementsClause); +// _nodeList(node.classOrMixinDeclaration_members); +// }); +// +// reference = reference.parent.parent; +// } +// +// void _node(LinkedNodeBuilder node) { +// if (node == null) return; +// +// if (node.kind == LinkedNodeKind.classDeclaration) { +// _classDeclaration(node); +// } else if (node.kind == LinkedNodeKind.classTypeAlias) { +// _classTypeAlias(node); +// } else if (node.kind == LinkedNodeKind.compilationUnit) { +// _compilationUnit(node); +// } else if (node.kind == LinkedNodeKind.constructorDeclaration) { +// _constructorDeclaration(node); +// } else if (node.kind == LinkedNodeKind.defaultFormalParameter) { +// _node(node.defaultFormalParameter_parameter); +// } else if (node.kind == LinkedNodeKind.enumDeclaration) { +// _enumDeclaration(node); +// } else if (node.kind == LinkedNodeKind.enumConstantDeclaration) { +// _enumConstantDeclaration(node); +// } else if (node.kind == LinkedNodeKind.exportDirective) { +// _exportDirective(node); +// } else if (node.kind == LinkedNodeKind.fieldDeclaration) { +// _fieldDeclaration(node); +// } else if (node.kind == LinkedNodeKind.fieldFormalParameter) { +// _fieldFormalParameter(node); +// } else if (node.kind == LinkedNodeKind.formalParameterList) { +// _formalParameters(node); +// } else if (node.kind == LinkedNodeKind.functionDeclaration) { +// _functionDeclaration(node); +// } else if (node.kind == LinkedNodeKind.functionExpression) { +// _functionExpression(node); +// } else if (node.kind == LinkedNodeKind.functionTypeAlias) { +// _functionTypeAlias(node); +// } else if (node.kind == LinkedNodeKind.functionTypedFormalParameter) { +// _functionTypedFormalParameter(node); +// } else if (node.kind == LinkedNodeKind.genericFunctionType) { +// _genericFunctionType(node); +// } else if (node.kind == LinkedNodeKind.genericTypeAlias) { +// _genericTypeAlias(node); +// } else if (node.kind == LinkedNodeKind.importDirective) { +// _importDirective(node); +// } else if (node.kind == LinkedNodeKind.libraryDirective) { +// _libraryDirective(node); +// } else if (node.kind == LinkedNodeKind.methodDeclaration) { +// _methodDeclaration(node); +// } else if (node.kind == LinkedNodeKind.mixinDeclaration) { +// _mixinDeclaration(node); +// } else if (node.kind == LinkedNodeKind.partDirective) { +// _partDirective(node); +// } else if (node.kind == LinkedNodeKind.partOfDirective) { +// _partOfDirective(node); +// } else if (node.kind == LinkedNodeKind.simpleFormalParameter) { +// _simpleFormalParameter(node); +// } else if (node.kind == LinkedNodeKind.topLevelVariableDeclaration) { +// _topLevelVariableDeclaration(node); +// } else if (node.kind == LinkedNodeKind.typeArgumentList) { +// _typeArgumentList(node); +// } else if (node.kind == LinkedNodeKind.typeName) { +// _typeName(node); +// } else if (node.kind == LinkedNodeKind.typeParameter) { +// _typeParameter(node); +// } else if (node.kind == LinkedNodeKind.typeParameterList) { +// _typeParameterList(node); +// } else if (node.kind == LinkedNodeKind.variableDeclarationList) { +// _variableDeclarationList(node); +// } else { +// // TODO(scheglov) implement +// throw UnimplementedError('${node.kind}'); +// } +// } +// +// void _nodeList(List<LinkedNode> nodeList) { +// if (nodeList == null) return; +// +// for (var i = 0; i < nodeList.length; ++i) { +// var node = nodeList[i]; +// _node(node); +// } +// } +// +// void _onClause(LinkedNodeBuilder node) { +// if (node == null) return; +// +// _typeNameList(node.onClause_superclassConstraints); +// } +// +// void _partDirective(LinkedNodeBuilder node) {} +// +// void _partOfDirective(LinkedNodeBuilder node) {} +// +// void _setSimpleElement(LinkedNodeBuilder identifier, Reference reference) { +// var referenceIndex = linkingBundleContext.indexOfReference(reference); +// identifier.simpleIdentifier_element = referenceIndex; +// } +// +// void _simpleFormalParameter(LinkedNodeBuilder node) { +// var typeNode = node.simpleFormalParameter_type; +// if (typeNode != null) { +// _node(typeNode); +// typesToBuild.declarations.add(node); +// } else { +// // TODO(scheglov) might be inferred +// node.simpleFormalParameter_type2 = _dynamicType; +// } +// +// if (node.normalFormalParameter_covariantKeyword != 0) { +// node.normalFormalParameter_isCovariant = true; +// } else { +// // TODO(scheglov) might be inferred +// } +// } +// +// void _topLevelVariableDeclaration(LinkedNodeBuilder node) { +// _node(node.topLevelVariableDeclaration_variableList); +// } +// +// void _typeArgumentList(LinkedNodeBuilder node) { +// for (var typeArgument in node.typeArgumentList_arguments) { +// _typeName(typeArgument); +// } +// } +// +// void _typeName(LinkedNodeBuilder node) { +// if (node == null) return; +// +// var identifier = node.typeName_name; +// Reference reference; +// +// if (identifier.kind == LinkedNodeKind.simpleIdentifier) { +// var name = unit.context.getSimpleName(identifier); +// +// if (name == 'void') { +// node.typeName_type = LinkedNodeTypeBuilder( +// kind: LinkedNodeTypeKind.void_, +// ); +// return; +// } +// +// reference = scope.lookup(name); +// } else { +// var prefixNode = identifier.prefixedIdentifier_prefix; +// var prefixName = unit.context.getSimpleName(prefixNode); +// var prefixReference = scope.lookup(prefixName); +// _setSimpleElement(prefixNode, prefixReference); +// +// identifier = identifier.prefixedIdentifier_identifier; +// var name = unit.context.getSimpleName(identifier); +// +// if (prefixReference != null && prefixReference.isPrefix) { +// var prefixScope = prefixReference.prefixScope; +// reference = prefixScope.lookup(name); +// } else { +// identifier.simpleIdentifier_element = 0; +// node.typeName_type = _dynamicType; +// return; +// } +// } +// +// if (reference == null) { +// identifier.simpleIdentifier_element = 0; +// node.typeName_type = _dynamicType; +// return; +// } +// +// _setSimpleElement(identifier, reference); +// +// var typeArgumentList = node.typeName_typeArguments; +// if (typeArgumentList != null) { +// _node(typeArgumentList); +// } +// +// typesToBuild.typeAnnotations.add(node); +// } +// +// void _typeNameList(List<LinkedNode> nodeList) { +// for (var i = 0; i < nodeList.length; ++i) { +// var node = nodeList[i]; +// _typeName(node); +// } +// } +// +// void _typeParameter(LinkedNodeBuilder node) { +// _node(node.typeParameter_bound); +// // TODO(scheglov) set Object bound if no explicit? +// } +// +// void _typeParameterList(LinkedNodeBuilder node) { +// for (var typeParameter in node.typeParameterList_typeParameters) { +// _node(typeParameter); +// } +// } +// +// void _variableDeclarationList(LinkedNodeBuilder node) { +// var typeNode = node.variableDeclarationList_type; +// if (typeNode != null) { +// _node(typeNode); +// typesToBuild.declarations.add(node); +// } +// } +// +// void _withClause(LinkedNodeBuilder node) { +// if (node == null) return; +// +// _typeNameList(node.withClause_mixinTypes); +// } +// +// /// Enter the type parameters scope, visit them, and run [f]. +// void _withTypeParameters(LinkedNode typeParameterList, void f()) { +// if (typeParameterList == null) { +// f(); +// return; +// } +// +// scope = Scope(this.scope, {}); +// +// var containerRef = this.reference.getChild('@typeParameter'); +// var typeParameters = typeParameterList.typeParameterList_typeParameters; +// for (var typeParameter in typeParameters) { +// var name = unit.context.getSimpleName(typeParameter.typeParameter_name); +// var reference = containerRef.getChild(name); +// reference.node = typeParameter; +// scope.declare(name, reference); +// } +// +// _node(typeParameterList); +// f(); +// +// if (typeParameterList != null) { +// scope = scope.parent; +// } +// } +//} /// Recursive visitor of [LinkedNode]s that resolves explicit type annotations /// in outlines. This includes resolving element references in identifiers @@ -18,512 +529,355 @@ /// the corresponding type set (so, if there is an explicit type annotation, /// the type is set, otherwise we keep it empty, so we will attempt to infer /// it later). -class ReferenceResolver { - final LinkingBundleContext linkingBundleContext; - final TypesToBuild typesToBuild; - final UnitBuilder unit; - - /// TODO(scheglov) Update scope with local scopes (formal / type parameters). - Scope scope; +class ReferenceResolver extends ThrowingAstVisitor<void> { + final NodesToBuildType nodesToBuildType; + final LinkedElementFactory elementFactory; + final LibraryElement _libraryElement; Reference reference; + Scope scope; ReferenceResolver( - this.linkingBundleContext, - this.typesToBuild, - this.unit, - this.scope, + this.nodesToBuildType, + this.elementFactory, + this._libraryElement, this.reference, + this.scope, ); - LinkedNodeTypeBuilder get _dynamicType { - return LinkedNodeTypeBuilder( - kind: LinkedNodeTypeKind.dynamic_, + @override + void visitBlockFunctionBody(BlockFunctionBody node) {} + + @override + void visitClassDeclaration(ClassDeclaration node) { + var outerScope = scope; + var outerReference = reference; + + var name = node.name.name; + reference = reference.getChild('@class').getChild(name); + + var element = ClassElementImpl.forLinkedNode( + outerReference.element, + reference, + node, ); + node.name.staticElement = element; + scope = new TypeParameterScope(scope, element); + scope = new ClassScope(scope, element); + LinkingNodeContext.set(node, LinkingNodeContext(scope)); + + node.typeParameters?.accept(this); + node.extendsClause?.accept(this); + node.implementsClause?.accept(this); + node.withClause?.accept(this); + node.members.accept(this); + + scope = outerScope; + reference = outerReference; } - void resolve() { - _node(unit.node); - } + @override + void visitClassTypeAlias(ClassTypeAlias node) { + var outerScope = scope; + var outerReference = reference; - void _classDeclaration(LinkedNodeBuilder node) { - var name = unit.context.getUnitMemberName(node); + var name = node.name.name; reference = reference.getChild('@class').getChild(name); - var typeParameters = node.classOrMixinDeclaration_typeParameters; - _withTypeParameters(typeParameters, () { - _extendsClause(node.classDeclaration_extendsClause); - _withClause(node.classDeclaration_withClause); - _implementsClause(node.classOrMixinDeclaration_implementsClause); + var element = ClassElementImpl.forLinkedNode( + outerReference.element, + reference, + node, + ); + node.name.staticElement = element; + scope = new TypeParameterScope(scope, element); + scope = new ClassScope(scope, element); + LinkingNodeContext.set(node, LinkingNodeContext(scope)); - for (var member in node.classOrMixinDeclaration_members) { - if (member.kind != LinkedNodeKind.constructorDeclaration) { - _node(member); - } - } - for (var member in node.classOrMixinDeclaration_members) { - if (member.kind == LinkedNodeKind.constructorDeclaration) { - _node(member); - } - } - }); + node.typeParameters?.accept(this); + node.superclass?.accept(this); + node.withClause?.accept(this); + node.implementsClause?.accept(this); - reference = reference.parent.parent; + scope = outerScope; + reference = outerReference; } - void _classTypeAlias(LinkedNodeBuilder node) { - var name = unit.context.getUnitMemberName(node); - reference = reference.getChild('@class').getChild(name); - - var typeParameters = node.classTypeAlias_typeParameters; - _withTypeParameters(typeParameters, () { - _typeName(node.classTypeAlias_superclass); - _withClause(node.classTypeAlias_withClause); - _implementsClause(node.classTypeAlias_implementsClause); - }); - - reference = reference.parent.parent; + @override + void visitCompilationUnit(CompilationUnit node) { + LinkingNodeContext.set(node, LinkingNodeContext(scope)); + node.declarations.accept(this); } - void _compilationUnit(LinkedNodeBuilder node) { - _nodeList(node.compilationUnit_directives); - _nodeList(node.compilationUnit_declarations); + @override + void visitConstructorDeclaration(ConstructorDeclaration node) { + node.parameters?.accept(this); } - void _constructorDeclaration(LinkedNodeBuilder node) { - _node(node.constructorDeclaration_parameters); + @override + void visitDefaultFormalParameter(DefaultFormalParameter node) { + node.parameter.accept(this); } - void _enumConstantDeclaration(LinkedNodeBuilder node) {} + @override + void visitEnumDeclaration(EnumDeclaration node) {} - void _enumDeclaration(LinkedNodeBuilder node) { - _nodeList(node.enumDeclaration_constants); + @override + void visitExpressionFunctionBody(ExpressionFunctionBody node) {} + + @override + void visitExtendsClause(ExtendsClause node) { + node.superclass.accept(this); } - void _exportDirective(LinkedNodeBuilder node) {} - - void _extendsClause(LinkedNodeBuilder node) { - if (node == null) return; - - _typeName(node.extendsClause_superclass); + @override + void visitFieldDeclaration(FieldDeclaration node) { + node.fields.accept(this); } - void _fieldDeclaration(LinkedNodeBuilder node) { - _node(node.fieldDeclaration_fields); + @override + void visitFieldFormalParameter(FieldFormalParameter node) { + node.type?.accept(this); + node.parameters?.accept(this); + nodesToBuildType.addDeclaration(node); } - void _fieldFormalParameter(LinkedNodeBuilder node) { - var typeNode = node.fieldFormalParameter_type; - if (typeNode != null) { - _node(typeNode); - } - - var formalParameters = node.fieldFormalParameter_formalParameters; - if (formalParameters != null) { - _formalParameters(formalParameters); - } - - if (typeNode != null || formalParameters != null) { - typesToBuild.declarations.add(node); - } + @override + void visitFormalParameterList(FormalParameterList node) { + node.parameters.accept(this); } - void _formalParameters(LinkedNodeBuilder node) { - for (var parameter in node.formalParameterList_parameters) { - _node(parameter); - } - } + @override + void visitFunctionDeclaration(FunctionDeclaration node) { + var outerScope = scope; + var outerReference = reference; - void _functionDeclaration(LinkedNodeBuilder node) { - var name = unit.context.getUnitMemberName(node); + var name = node.name.name; reference = reference.getChild('@function').getChild(name); - var function = node.functionDeclaration_functionExpression; - var typeParameters = function.functionExpression_typeParameters; - _withTypeParameters(typeParameters, () { - var returnType = node.functionDeclaration_returnType; - if (returnType != null) { - _node(returnType); - typesToBuild.declarations.add(node); - } else { - node.functionDeclaration_returnType2 = _dynamicType; - } + var element = FunctionElementImpl.forLinkedNode( + outerReference.element, + reference, + node, + ); + node.name.staticElement = element; + scope = new FunctionScope(scope, element); + LinkingNodeContext.set(node, LinkingNodeContext(scope)); - _node(function.functionExpression_formalParameters); - }); + node.returnType?.accept(this); + node.functionExpression.accept(this); + nodesToBuildType.addDeclaration(node); - reference = reference.parent.parent; + scope = outerScope; + reference = outerReference; } - void _functionExpression(LinkedNodeBuilder node) { - var typeParameters = node.functionExpression_typeParameters; - _withTypeParameters(typeParameters, () { - _node(node.functionExpression_formalParameters); - }); + @override + void visitFunctionExpression(FunctionExpression node) { + node.typeParameters?.accept(this); + node.parameters?.accept(this); } - void _functionTypeAlias(LinkedNodeBuilder node) { - var name = unit.context.getUnitMemberName(node); + @override + void visitFunctionTypeAlias(FunctionTypeAlias node) { + var outerScope = scope; + var outerReference = reference; + + var name = node.name.name; reference = reference.getChild('@typeAlias').getChild(name); - var typeParameters = node.functionTypeAlias_typeParameters; - _withTypeParameters(typeParameters, () { - var returnType = node.functionTypeAlias_returnType; - if (returnType != null) { - _node(returnType); - typesToBuild.declarations.add(node); - } else { - node.functionTypeAlias_returnType2 = _dynamicType; - } + var element = GenericTypeAliasElementImpl.forLinkedNode( + outerReference.element, + reference, + node, + ); + node.name.staticElement = element; + scope = FunctionTypeScope(outerScope, element); - _node(node.functionTypeAlias_formalParameters); - }); + node.returnType?.accept(this); + node.typeParameters?.accept(this); + node.parameters.accept(this); + nodesToBuildType.addDeclaration(node); - reference = reference.parent.parent; + scope = outerScope; + reference = outerReference; } - void _functionTypedFormalParameter(LinkedNodeBuilder node) { - var typeParameters = node.functionTypedFormalParameter_typeParameters; - _withTypeParameters(typeParameters, () { - var typeNode = node.functionTypedFormalParameter_returnType; - if (typeNode != null) { - _node(typeNode); - } + @override + void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { + node.returnType?.accept(this); + node.typeParameters?.accept(this); + node.parameters.accept(this); - _formalParameters(node.functionTypedFormalParameter_formalParameters); - typesToBuild.declarations.add(node); - }); + nodesToBuildType.addDeclaration(node); } - void _genericFunctionType(LinkedNodeBuilder node) { - reference = reference.getChild('@function'); + @override + void visitGenericFunctionType(GenericFunctionType node) { + var outerScope = scope; + var outerReference = reference; - var name = '${reference.numOfChildren}'; + var name = '${outerReference.numOfChildren}'; reference = reference.getChild(name); - var typeParameters = node.genericFunctionType_typeParameters; - _withTypeParameters(typeParameters, () { - var returnType = node.genericFunctionType_returnType; - if (returnType != null) { - _node(returnType); - typesToBuild.declarations.add(node); - } + var element = GenericFunctionTypeElementImpl.forLinkedNode( + outerReference.element, + reference, + node, + ); + scope = TypeParameterScope(outerScope, element); - _formalParameters(node.genericFunctionType_formalParameters); + node.returnType?.accept(this); + node.typeParameters?.accept(this); + node.parameters.accept(this); + nodesToBuildType.addTypeAnnotation(node); + nodesToBuildType.addDeclaration(node); - typesToBuild.typeAnnotations.add(node); - }); - - reference = reference.parent.parent; + scope = outerScope; + reference = outerReference; } - void _genericTypeAlias(LinkedNodeBuilder node) { - var name = unit.context.getSimpleName( - node.namedCompilationUnitMember_name, - ); + @override + void visitGenericTypeAlias(GenericTypeAlias node) { + var outerScope = scope; + var outerReference = reference; + + var name = node.name.name; reference = reference.getChild('@typeAlias').getChild(name); - var typeParameters = node.genericTypeAlias_typeParameters; - _withTypeParameters(typeParameters, () { - _node(node.genericTypeAlias_functionType); - }); + var element = GenericTypeAliasElementImpl.forLinkedNode( + outerReference.element, + reference, + node, + ); + node.name.staticElement = element; + scope = TypeParameterScope(outerScope, element); - reference = reference.parent.parent; + node.typeParameters?.accept(this); + node.functionType.accept(this); + + scope = outerScope; + reference = outerReference; } - void _implementsClause(LinkedNodeBuilder node) { - if (node == null) return; - - _typeNameList(node.implementsClause_interfaces); + @override + void visitImplementsClause(ImplementsClause node) { + node.interfaces.accept(this); } - void _importDirective(LinkedNodeBuilder node) {} + @override + void visitMethodDeclaration(MethodDeclaration node) { + var outerScope = scope; + var outerReference = reference; - void _libraryDirective(LinkedNodeBuilder node) {} - - void _methodDeclaration(LinkedNodeBuilder node) { - var name = unit.context.getMethodName(node); + var name = node.name.name; reference = reference.getChild('@method').getChild(name); - var typeParameters = node.methodDeclaration_typeParameters; - _withTypeParameters(typeParameters, () { - var returnType = node.methodDeclaration_returnType; - if (returnType != null) { - _node(returnType); - typesToBuild.declarations.add(node); - } + var element = MethodElementImpl.forLinkedNode( + outerReference.element, + reference, + node, + ); + node.name.staticElement = element; + scope = new FunctionScope(scope, element); + LinkingNodeContext.set(node, LinkingNodeContext(scope)); - _node(node.methodDeclaration_formalParameters); - }); + node.returnType?.accept(this); + node.parameters?.accept(this); + node.typeParameters?.accept(this); + nodesToBuildType.addDeclaration(node); - reference = reference.parent.parent; + scope = outerScope; + reference = outerReference; } - void _mixinDeclaration(LinkedNodeBuilder node) { - var name = unit.context.getUnitMemberName(node); + @override + void visitMixinDeclaration(MixinDeclaration node) { + var outerScope = scope; + var outerReference = reference; + + var name = node.name.name; reference = reference.getChild('@class').getChild(name); - var typeParameters = node.classOrMixinDeclaration_typeParameters; - _withTypeParameters(typeParameters, () { - _onClause(node.mixinDeclaration_onClause); - _implementsClause(node.classOrMixinDeclaration_implementsClause); - _nodeList(node.classOrMixinDeclaration_members); - }); + var element = ClassElementImpl.forLinkedNode( + outerReference.element, + reference, + node, + ); + node.name.staticElement = element; + scope = new TypeParameterScope(scope, element); + scope = new ClassScope(scope, element); - reference = reference.parent.parent; + node.typeParameters?.accept(this); + node.onClause?.accept(this); + node.implementsClause?.accept(this); + node.members.accept(this); + + scope = outerScope; + reference = outerReference; } - void _node(LinkedNodeBuilder node) { - if (node == null) return; - - if (node.kind == LinkedNodeKind.classDeclaration) { - _classDeclaration(node); - } else if (node.kind == LinkedNodeKind.classTypeAlias) { - _classTypeAlias(node); - } else if (node.kind == LinkedNodeKind.compilationUnit) { - _compilationUnit(node); - } else if (node.kind == LinkedNodeKind.constructorDeclaration) { - _constructorDeclaration(node); - } else if (node.kind == LinkedNodeKind.defaultFormalParameter) { - _node(node.defaultFormalParameter_parameter); - } else if (node.kind == LinkedNodeKind.enumDeclaration) { - _enumDeclaration(node); - } else if (node.kind == LinkedNodeKind.enumConstantDeclaration) { - _enumConstantDeclaration(node); - } else if (node.kind == LinkedNodeKind.exportDirective) { - _exportDirective(node); - } else if (node.kind == LinkedNodeKind.fieldDeclaration) { - _fieldDeclaration(node); - } else if (node.kind == LinkedNodeKind.fieldFormalParameter) { - _fieldFormalParameter(node); - } else if (node.kind == LinkedNodeKind.formalParameterList) { - _formalParameters(node); - } else if (node.kind == LinkedNodeKind.functionDeclaration) { - _functionDeclaration(node); - } else if (node.kind == LinkedNodeKind.functionExpression) { - _functionExpression(node); - } else if (node.kind == LinkedNodeKind.functionTypeAlias) { - _functionTypeAlias(node); - } else if (node.kind == LinkedNodeKind.functionTypedFormalParameter) { - _functionTypedFormalParameter(node); - } else if (node.kind == LinkedNodeKind.genericFunctionType) { - _genericFunctionType(node); - } else if (node.kind == LinkedNodeKind.genericTypeAlias) { - _genericTypeAlias(node); - } else if (node.kind == LinkedNodeKind.importDirective) { - _importDirective(node); - } else if (node.kind == LinkedNodeKind.libraryDirective) { - _libraryDirective(node); - } else if (node.kind == LinkedNodeKind.methodDeclaration) { - _methodDeclaration(node); - } else if (node.kind == LinkedNodeKind.mixinDeclaration) { - _mixinDeclaration(node); - } else if (node.kind == LinkedNodeKind.partDirective) { - _partDirective(node); - } else if (node.kind == LinkedNodeKind.partOfDirective) { - _partOfDirective(node); - } else if (node.kind == LinkedNodeKind.simpleFormalParameter) { - _simpleFormalParameter(node); - } else if (node.kind == LinkedNodeKind.topLevelVariableDeclaration) { - _topLevelVariableDeclaration(node); - } else if (node.kind == LinkedNodeKind.typeArgumentList) { - _typeArgumentList(node); - } else if (node.kind == LinkedNodeKind.typeName) { - _typeName(node); - } else if (node.kind == LinkedNodeKind.typeParameter) { - _typeParameter(node); - } else if (node.kind == LinkedNodeKind.typeParameterList) { - _typeParameterList(node); - } else if (node.kind == LinkedNodeKind.variableDeclarationList) { - _variableDeclarationList(node); - } else { - // TODO(scheglov) implement - throw UnimplementedError('${node.kind}'); - } + @override + void visitOnClause(OnClause node) { + node.superclassConstraints.accept(this); } - void _nodeList(List<LinkedNode> nodeList) { - if (nodeList == null) return; - - for (var i = 0; i < nodeList.length; ++i) { - var node = nodeList[i]; - _node(node); - } + @override + void visitSimpleFormalParameter(SimpleFormalParameter node) { + node.type?.accept(this); + nodesToBuildType.addDeclaration(node); } - void _onClause(LinkedNodeBuilder node) { - if (node == null) return; - - _typeNameList(node.onClause_superclassConstraints); + @override + void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { + node.variables.accept(this); } - void _partDirective(LinkedNodeBuilder node) {} - - void _partOfDirective(LinkedNodeBuilder node) {} - - void _setSimpleElement(LinkedNodeBuilder identifier, Reference reference) { - var referenceIndex = linkingBundleContext.indexOfReference(reference); - identifier.simpleIdentifier_element = referenceIndex; + @override + void visitTypeArgumentList(TypeArgumentList node) { + node.arguments.accept(this); } - void _simpleFormalParameter(LinkedNodeBuilder node) { - var typeNode = node.simpleFormalParameter_type; - if (typeNode != null) { - _node(typeNode); - typesToBuild.declarations.add(node); - } else { - // TODO(scheglov) might be inferred - node.simpleFormalParameter_type2 = _dynamicType; - } - - if (node.normalFormalParameter_covariantKeyword != 0) { - node.normalFormalParameter_isCovariant = true; - } else { - // TODO(scheglov) might be inferred - } - } - - void _topLevelVariableDeclaration(LinkedNodeBuilder node) { - _node(node.topLevelVariableDeclaration_variableList); - } - - void _typeArgumentList(LinkedNodeBuilder node) { - for (var typeArgument in node.typeArgumentList_arguments) { - _typeName(typeArgument); - } - } - - void _typeName(LinkedNodeBuilder node) { - if (node == null) return; - - var identifier = node.typeName_name; - Reference reference; - - if (identifier.kind == LinkedNodeKind.simpleIdentifier) { - var name = unit.context.getSimpleName(identifier); - - if (name == 'void') { - node.typeName_type = LinkedNodeTypeBuilder( - kind: LinkedNodeTypeKind.void_, - ); - return; - } - - reference = scope.lookup(name); - } else { - var prefixNode = identifier.prefixedIdentifier_prefix; - var prefixName = unit.context.getSimpleName(prefixNode); - var prefixReference = scope.lookup(prefixName); - _setSimpleElement(prefixNode, prefixReference); - - identifier = identifier.prefixedIdentifier_identifier; - var name = unit.context.getSimpleName(identifier); - - if (prefixReference != null && prefixReference.isPrefix) { - var prefixScope = prefixReference.prefixScope; - reference = prefixScope.lookup(name); - } else { - identifier.simpleIdentifier_element = 0; - node.typeName_type = _dynamicType; - return; - } - } - - if (reference == null) { - identifier.simpleIdentifier_element = 0; - node.typeName_type = _dynamicType; + @override + void visitTypeName(TypeName node) { + var typeName = node.name; + if (typeName is SimpleIdentifier && typeName.name == 'void') { + node.type = VoidTypeImpl.instance; return; } - _setSimpleElement(identifier, reference); - - var typeArgumentList = node.typeName_typeArguments; - if (typeArgumentList != null) { - _node(typeArgumentList); + var element = scope.lookup(typeName, _libraryElement); + if (typeName is SimpleIdentifier) { + typeName.staticElement = element; + } else if (typeName is PrefixedIdentifier) { + typeName.identifier.staticElement = element; + SimpleIdentifier prefix = typeName.prefix; + prefix.staticElement = scope.lookup(prefix, _libraryElement); } - typesToBuild.typeAnnotations.add(node); + node.typeArguments?.accept(this); + + nodesToBuildType.addTypeAnnotation(node); } - void _typeNameList(List<LinkedNode> nodeList) { - for (var i = 0; i < nodeList.length; ++i) { - var node = nodeList[i]; - _typeName(node); - } + @override + void visitTypeParameter(TypeParameter node) { + node.bound?.accept(this); } - void _typeParameter(LinkedNodeBuilder node) { - _node(node.typeParameter_bound); - // TODO(scheglov) set Object bound if no explicit? + @override + void visitTypeParameterList(TypeParameterList node) { + node.typeParameters.accept(this); } - void _typeParameterList(LinkedNodeBuilder node) { - for (var typeParameter in node.typeParameterList_typeParameters) { - _node(typeParameter); - } + @override + void visitVariableDeclarationList(VariableDeclarationList node) { + node.type?.accept(this); + nodesToBuildType.addDeclaration(node); } - void _variableDeclarationList(LinkedNodeBuilder node) { - var typeNode = node.variableDeclarationList_type; - if (typeNode != null) { - _node(typeNode); - typesToBuild.declarations.add(node); - } + @override + void visitWithClause(WithClause node) { + node.mixinTypes.accept(this); } - - void _withClause(LinkedNodeBuilder node) { - if (node == null) return; - - _typeNameList(node.withClause_mixinTypes); - } - - /// Enter the type parameters scope, visit them, and run [f]. - void _withTypeParameters(LinkedNode typeParameterList, void f()) { - if (typeParameterList == null) { - f(); - return; - } - - scope = Scope(this.scope, {}); - - var containerRef = this.reference.getChild('@typeParameter'); - var typeParameters = typeParameterList.typeParameterList_typeParameters; - for (var typeParameter in typeParameters) { - var name = unit.context.getSimpleName(typeParameter.typeParameter_name); - var reference = containerRef.getChild(name); - reference.node = typeParameter; - scope.declare(name, reference); - } - - _node(typeParameterList); - f(); - - if (typeParameterList != null) { - scope = scope.parent; - } - } -} - -/// Type annotations and declarations to build types for. -/// -/// Not all types can be build during reference resolution phase. -/// For example `A` means `A<num>` if `class A<T extends num>`, but we don't -/// know this until we resolved `A` declaration, and we might have not yet. -/// So, we remember [LinkedNodeKind.typeName] nodes to resolve them later. -class TypesToBuild { - /// Nodes with [LinkedNodeKind.typeName] (with type arguments, and without - /// them), and [LinkedNodeKind.genericFunctionType]. These nodes will be - /// resolved by [ReferenceResolver], so that they have their references set, - /// but their types will not be set yet. - /// - /// Types arguments, return types, and types of formal parameters must be - /// before the types that use them in this list. - final List<LinkedNodeBuilder> typeAnnotations = []; - - /// Nodes with type annotations, where we want not just resolve these types - /// annotations, but also set additional types. For example instance method - /// return types might be specified, and then the method has the specified - /// return type. But if the return type is not specified explicitly, the - /// method still might have a return type, inferred from a superclass. - final List<LinkedNodeBuilder> declarations = []; }
diff --git a/pkg/analyzer/lib/src/summary2/simply_bounded.dart b/pkg/analyzer/lib/src/summary2/simply_bounded.dart new file mode 100644 index 0000000..13a6dc4 --- /dev/null +++ b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
@@ -0,0 +1,313 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/src/summary/format.dart'; +import 'package:analyzer/src/summary/idl.dart' show LinkedNode; +import 'package:analyzer/src/summary/idl.dart'; +import 'package:analyzer/src/summary/link.dart' as graph + show DependencyWalker, Node; +import 'package:analyzer/src/summary2/builder/source_library_builder.dart'; +import 'package:analyzer/src/summary2/linked_bundle_context.dart'; +import 'package:analyzer/src/summary2/linked_unit_context.dart'; +import 'package:analyzer/src/summary2/reference.dart'; +import 'package:analyzer/src/summary2/type_builder.dart'; + +/// Compute simple-boundedness for all classes and generic types aliases in +/// the source [libraryBuilders]. There might be dependencies between them, +/// so they all should be processed simultaneously. +void computeSimplyBounded( + LinkedBundleContext bundleContext, + Iterable<SourceLibraryBuilder> libraryBuilders, +) { + var walker = SimplyBoundedDependencyWalker(bundleContext); + var nodes = <SimplyBoundedNode>[]; + for (var libraryBuilder in libraryBuilders) { + var unitsRef = libraryBuilder.reference.getChild('@unit'); + for (var unitRef in unitsRef.children) { + for (var classRef in unitRef.getChild('@class').children) { + var node = walker.getNode(classRef); + nodes.add(node); + } + for (var ref in unitRef.getChild('@typeAlias').children) { + var node = walker.getNode(ref); + nodes.add(node); + } + } + } + + for (var node in nodes) { + if (!node.isEvaluated) { + walker.walk(node); + } + LinkedNodeBuilder builder = node._reference.node; + builder.simplyBoundable_isSimplyBounded = node.isSimplyBounded; + } +} + +/// The graph walker for evaluating whether types are simply bounded. +class SimplyBoundedDependencyWalker + extends graph.DependencyWalker<SimplyBoundedNode> { + final LinkedBundleContext bundleContext; + final Map<Reference, SimplyBoundedNode> nodeMap = {}; + + SimplyBoundedDependencyWalker(this.bundleContext); + + @override + void evaluate(SimplyBoundedNode v) { + v._evaluate(); + } + + @override + void evaluateScc(List<SimplyBoundedNode> scc) { + for (var node in scc) { + node._markCircular(); + } + } + + SimplyBoundedNode getNode(Reference reference) { + var node = nodeMap[reference]; + if (node == null) { + if (reference.isClass) { + var parameters = LinkedUnitContext.getTypeParameters(reference.node); + node = SimplyBoundedNode( + this, + reference, + parameters ?? const <LinkedNode>[], + const <LinkedNode>[], + ); + } else if (reference.isTypeAlias) { + var parameters = LinkedUnitContext.getTypeParameters(reference.node); + node = SimplyBoundedNode( + this, + reference, + parameters ?? const <LinkedNode>[], + _collectTypedefRhsTypes(reference.node), + ); + } else { + throw UnimplementedError('$reference'); + } + nodeMap[reference] = node; + } + return node; + } + + /// Collects all the type references appearing on the "right hand side" of a + /// typedef. + /// + /// The "right hand side" of a typedef is the type appearing after the "=" + /// in a new style typedef declaration, or for an old style typedef + /// declaration, the type that *would* appear after the "=" if it were + /// converted to a new style typedef declaration. This means that type + /// parameter declarations and their bounds are not included. + static List<LinkedNode> _collectTypedefRhsTypes(LinkedNode node) { + var kind = node.kind; + if (kind == LinkedNodeKind.functionTypeAlias) { + var types = <LinkedNode>[]; + _TypeCollector.addType( + types, + node.functionTypeAlias_returnType, + ); + _TypeCollector.visitParameters( + types, + node.functionTypeAlias_formalParameters, + ); + return types; + } else if (kind == LinkedNodeKind.genericTypeAlias) { + var types = <LinkedNode>[]; + var function = node.genericTypeAlias_functionType; + _TypeCollector.addType( + types, + function.genericFunctionType_returnType, + ); + _TypeCollector.visitParameters( + types, + function.genericFunctionType_formalParameters, + ); + return types; + } else { + throw StateError('$kind'); + } + } +} + +/// The graph node used to construct the dependency graph for evaluating +/// whether types are simply bounded. +class SimplyBoundedNode extends graph.Node<SimplyBoundedNode> { + final SimplyBoundedDependencyWalker _walker; + final Reference _reference; + + /// The type parameters of the type whose simple-boundedness we check. + final List<LinkedNode> _typeParameters; + + /// If the type whose simple-boundedness we check is a typedef, the types + /// appearing in its "right hand side". + final List<LinkedNode> _rhsTypes; + + @override + bool isEvaluated = false; + + /// After execution of [_evaluate], indicates whether the type is + /// simply bounded. + /// + /// Prior to execution of [computeDependencies], `true`. + /// + /// Between execution of [computeDependencies] and [_evaluate], `true` + /// indicates that the type is simply bounded only if all of its dependencies + /// are simply bounded; `false` indicates that the type is not simply bounded. + bool isSimplyBounded = true; + + SimplyBoundedNode( + this._walker, + this._reference, + this._typeParameters, + this._rhsTypes, + ); + + @override + List<SimplyBoundedNode> computeDependencies() { + var dependencies = <SimplyBoundedNode>[]; + for (var typeParameter in _typeParameters) { + var bound = typeParameter.typeParameter_bound; + if (bound != null) { + if (!_visitType(dependencies, bound, false)) { + // Note: we might consider setting isEvaluated=true here to prevent an + // unnecessary call to SimplyBoundedDependencyWalker.evaluate. + // However, we'd have to be careful to make sure this doesn't violate + // an invariant of the DependencyWalker algorithm, since normally it + // only expects isEvaluated to change during a call to .evaluate or + // .evaluateScc. + isSimplyBounded = false; + return const []; + } + } + } + for (var type in _rhsTypes) { + if (!_visitType(dependencies, type, true)) { + // Note: we might consider setting isEvaluated=true here to prevent an + // unnecessary call to SimplyBoundedDependencyWalker.evaluate. + // However, we'd have to be careful to make sure this doesn't violate + // an invariant of the DependencyWalker algorithm, since normally it + // only expects isEvaluated to change during a call to .evaluate or + // .evaluateScc. + isSimplyBounded = false; + return const []; + } + } + return dependencies; + } + + void _evaluate() { + for (var dependency in graph.Node.getDependencies(this)) { + if (!dependency.isSimplyBounded) { + isSimplyBounded = false; + break; + } + } + isEvaluated = true; + } + + void _markCircular() { + isSimplyBounded = false; + isEvaluated = true; + } + + /// Visits the type specified by [type], storing the [SimplyBoundedNode] for + /// any types it references in [dependencies]. + /// + /// Return `false` if a type that is known to be not simply bound is found. + /// + /// Return `false` if a reference to a type parameter is found, and + /// [allowTypeParameters] is `false`. + /// + /// If `false` is returned, further visiting is short-circuited. + /// + /// Otherwise `true` is returned. + bool _visitType(List<SimplyBoundedNode> dependencies, LinkedNode type, + bool allowTypeParameters) { + if (type == null) return true; + + if (type.kind == LinkedNodeKind.typeName) { + var element = TypeBuilder.typeNameElementIndex(type.typeName_name); + var reference = _walker.bundleContext.referenceOfIndex(element); + + if (reference.isTypeParameter) { + return allowTypeParameters; + } + + var arguments = type.typeName_typeArguments; + if (arguments == null) { + var graphNode = _walker.nodeMap[reference]; + + // If not a node being linked, then the flag is already set. + if (graphNode == null) { + if (reference.isClass || reference.isTypeAlias) { + var elementFactory = _walker.bundleContext.elementFactory; + var node = elementFactory.nodeOfReference(reference); + return node.simplyBoundable_isSimplyBounded; + } + return true; + } + + dependencies.add(graphNode); + } else { + for (var argument in arguments.typeArgumentList_arguments) { + if (!_visitType(dependencies, argument, allowTypeParameters)) { + return false; + } + } + } + return true; + } + + if (type.kind == LinkedNodeKind.genericFunctionType) { + var types = <LinkedNode>[]; + _TypeCollector.addType(types, type.genericFunctionType_returnType); + _TypeCollector.visitParameters( + types, + type.genericFunctionType_formalParameters, + ); + for (var type in types) { + if (!_visitType(dependencies, type, allowTypeParameters)) { + return false; + } + } + return true; + } + + throw UnimplementedError('${type.kind}'); + } +} + +/// Helper for collecting type annotations in formal parameters. +class _TypeCollector { + static void addType(List<LinkedNode> types, LinkedNode type) { + if (type != null) { + types.add(type); + } + } + + static void visitParameter(List<LinkedNode> types, LinkedNode parameter) { + var kind = parameter.kind; + if (kind == LinkedNodeKind.defaultFormalParameter) { + visitParameter(types, parameter.defaultFormalParameter_parameter); + } else if (kind == LinkedNodeKind.functionTypedFormalParameter) { + addType(types, parameter.functionTypedFormalParameter_returnType); + visitParameters( + types, + parameter.functionTypedFormalParameter_formalParameters, + ); + } else if (kind == LinkedNodeKind.simpleFormalParameter) { + addType(types, parameter.simpleFormalParameter_type); + } else { + throw UnimplementedError('$kind'); + } + } + + static void visitParameters(List<LinkedNode> types, LinkedNode parameters) { + assert(parameters.kind == LinkedNodeKind.formalParameterList); + for (var parameter in parameters.formalParameterList_parameters) { + visitParameter(types, parameter); + } + } +}
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart index 4779752..c5b38e4 100644 --- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart +++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -2,15 +2,14 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/dart/ast/standard_ast_factory.dart'; +import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/element/type.dart'; import 'package:analyzer/src/dart/resolver/scope.dart'; -import 'package:analyzer/src/summary/format.dart'; -import 'package:analyzer/src/summary/idl.dart'; import 'package:analyzer/src/summary2/ast_resolver.dart'; +import 'package:analyzer/src/summary2/lazy_ast.dart'; import 'package:analyzer/src/summary2/link.dart'; import 'package:analyzer/src/summary2/linked_unit_context.dart'; import 'package:analyzer/src/summary2/reference.dart'; @@ -44,6 +43,12 @@ _nameScope = _libraryScope; } + DynamicTypeImpl get _dynamicType { + return DynamicTypeImpl.instance; + } + + VoidTypeImpl get _voidType => VoidTypeImpl.instance; + void infer() { _setOmittedReturnTypes(); _inferFieldsTemporary(); @@ -56,12 +61,12 @@ _linkedContext = unit.linkedContext; for (var class_ in unit.types) { - var fields = <String, LinkedNodeType>{}; + var fields = <String, DartType>{}; for (FieldElementImpl field in class_.fields) { if (field.isSynthetic) continue; var name = field.name; - var type = field.linkedNode.variableDeclaration_type2; + var type = field.type; if (type == null) { throw StateError('Field $name should have a type.'); } @@ -71,20 +76,18 @@ for (ConstructorElementImpl constructor in class_.constructors) { for (ParameterElementImpl parameter in constructor.parameters) { if (parameter is FieldFormalParameterElement) { - LinkedNodeBuilder parameterNode = parameter.linkedNode; - if (parameterNode.kind == LinkedNodeKind.defaultFormalParameter) { - parameterNode = parameterNode.defaultFormalParameter_parameter; + FormalParameter node = parameter.linkedNode; + if (node is DefaultFormalParameter) { + var defaultParameter = node as DefaultFormalParameter; + node = defaultParameter.parameter; } - if (parameterNode.fieldFormalParameter_type2 == null) { + if (node is FieldFormalParameter && + node.type == null && + node.parameters == null) { var name = parameter.name; - var type = fields[name]; - if (type == null) { - type = LinkedNodeTypeBuilder( - kind: LinkedNodeTypeKind.dynamic_, - ); - } - parameterNode.fieldFormalParameter_type2 = type; + var type = fields[name] ?? _dynamicType; + LazyAst.setType(node, type); } } } @@ -108,10 +111,10 @@ for (TopLevelVariableElementImpl variable in unit.topLevelVariables) { if (variable.isSynthetic) continue; - LinkedNodeBuilder variableNode = variable.linkedNode; - if (variableNode.variableDeclaration_type2 == null || - _linkedContext.isConst(variableNode)) { - _inferVariableTypeFromInitializerTemporary(variableNode); + VariableDeclaration node = variable.linkedNode; + VariableDeclarationList parent = node.parent; + if (parent.type == null || _linkedContext.isConst(node)) { + _inferVariableTypeFromInitializerTemporary(node); } } } @@ -125,43 +128,34 @@ for (FieldElementImpl field in class_.fields) { if (field.isSynthetic) continue; - var fieldNode = field.linkedNode; - + VariableDeclaration node = field.linkedNode; + VariableDeclarationList parent = node.parent; // TODO(scheglov) Use inheritance // TODO(scheglov) infer in the correct order - if (fieldNode.variableDeclaration_type2 == null) { - _inferVariableTypeFromInitializerTemporary(fieldNode); + if (parent.type == null || parent.isConst) { + _inferVariableTypeFromInitializerTemporary(node); } } _nameScope = prevScope; } - void _inferVariableTypeFromInitializerTemporary(LinkedNodeBuilder node) { - var unresolvedNode = node.variableDeclaration_initializer; + void _inferVariableTypeFromInitializerTemporary(VariableDeclaration node) { + var initializer = node.initializer; - if (unresolvedNode == null) { - node.variableDeclaration_type2 = LinkedNodeTypeBuilder( - kind: LinkedNodeTypeKind.dynamic_, - ); + if (initializer == null) { + LazyAst.setType(node, _dynamicType); return; } - var expression = _linkedContext.readInitializer(unitElement, node); - astFactory.expressionFunctionBody(null, null, expression, null); - var astResolver = AstResolver(linker, _libraryElement, _nameScope); - var resolvedNode = astResolver.resolve(_linkedContext, expression); - node.variableDeclaration_initializer = resolvedNode; + astResolver.resolve(initializer); - if (node.variableDeclaration_type2 == null) { - var initializerType = expression.staticType; + VariableDeclarationList parent = node.parent; + if (parent.type == null) { + var initializerType = initializer.staticType; initializerType = _dynamicIfNull(initializerType); - - var linkingBundleContext = linker.linkingBundleContext; - node.variableDeclaration_type2 = linkingBundleContext.writeType( - initializerType, - ); + LazyAst.setType(node, initializerType); } } @@ -179,23 +173,16 @@ } for (FunctionElementImpl function in unit.functions) { - LinkedNodeBuilder functionNode = function.linkedNode; - if (functionNode.functionDeclaration_returnType == null) { - functionNode.functionDeclaration_returnType2 = LinkedNodeTypeBuilder( - kind: LinkedNodeTypeKind.dynamic_, - ); + FunctionDeclaration node = function.linkedNode; + if (node.returnType == null) { + LazyAst.setReturnType(node, _dynamicType); } } for (PropertyAccessorElementImpl accessor in unit.accessors) { if (accessor.isSynthetic) continue; if (accessor.isSetter) { - LinkedNodeBuilder node = accessor.linkedNode; - if (node.functionDeclaration_returnType == null) { - node.functionDeclaration_returnType2 = LinkedNodeTypeBuilder( - kind: LinkedNodeTypeKind.void_, - ); - } + LazyAst.setReturnType(accessor.linkedNode, _voidType); } } } @@ -203,28 +190,22 @@ void _setOmittedReturnTypesClass(ClassElement class_) { for (MethodElementImpl method in class_.methods) { - LinkedNodeBuilder methodNode = method.linkedNode; - if (methodNode.methodDeclaration_returnType == null) { - methodNode.methodDeclaration_returnType2 = LinkedNodeTypeBuilder( - kind: LinkedNodeTypeKind.dynamic_, - ); + MethodDeclaration node = method.linkedNode; + if (node.returnType == null) { + LazyAst.setReturnType(node, _dynamicType); } } for (PropertyAccessorElementImpl accessor in class_.accessors) { if (accessor.isSynthetic) continue; - LinkedNodeBuilder accessorNode = accessor.linkedNode; - if (accessorNode.methodDeclaration_returnType != null) continue; + MethodDeclaration node = accessor.linkedNode; + if (node.returnType != null) continue; if (accessor.isSetter) { - accessorNode.methodDeclaration_returnType2 = LinkedNodeTypeBuilder( - kind: LinkedNodeTypeKind.void_, - ); + LazyAst.setReturnType(node, _voidType); } else { - accessorNode.methodDeclaration_returnType2 = LinkedNodeTypeBuilder( - kind: LinkedNodeTypeKind.dynamic_, - ); + LazyAst.setReturnType(node, _dynamicType); } } }
diff --git a/pkg/analyzer/lib/src/summary2/type_builder.dart b/pkg/analyzer/lib/src/summary2/type_builder.dart index 9423d65..3588181 100644 --- a/pkg/analyzer/lib/src/summary2/type_builder.dart +++ b/pkg/analyzer/lib/src/summary2/type_builder.dart
@@ -2,220 +2,326 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/src/summary/format.dart'; +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/type.dart'; +import 'package:analyzer/src/dart/ast/ast.dart'; +import 'package:analyzer/src/dart/element/element.dart'; +import 'package:analyzer/src/dart/element/type.dart'; +import 'package:analyzer/src/dart/element/type_algebra.dart'; +import 'package:analyzer/src/generated/utilities_dart.dart'; import 'package:analyzer/src/summary/idl.dart'; -import 'package:analyzer/src/summary2/linked_bundle_context.dart'; -import 'package:analyzer/src/summary2/linked_unit_context.dart'; -import 'package:analyzer/src/summary2/reference.dart'; -import 'package:analyzer/src/summary2/reference_resolver.dart'; +import 'package:analyzer/src/summary2/lazy_ast.dart'; +import 'package:analyzer/src/summary2/linking_bundle_context.dart'; -/// Build types in a [TypesToBuild]. +/// Type annotations and declarations to build types for. +/// +/// Not all types can be build during reference resolution phase. +/// For example `A` means `A<num>` if `class A<T extends num>`, but we don't +/// know this until we resolved `A` declaration, and we might have not yet. +/// +/// So, we remember type annotations that should be resolved later, and +/// declarations to set types from explicit type annotations. +class NodesToBuildType { + final List<NodeToBuildType> items = []; + + void addDeclaration(AstNode declaration) { + items.add(NodeToBuildType._(null, declaration)); + } + + void addTypeAnnotation(TypeAnnotation typeAnnotation) { + items.add(NodeToBuildType._(typeAnnotation, null)); + } +} + +/// A type annotation to build type for, or a declaration to set its explicitly +/// declared type. +class NodeToBuildType { + final TypeAnnotation typeAnnotation; + final AstNode declaration; + + NodeToBuildType._(this.typeAnnotation, this.declaration); +} + +/// Build types in a [NodesToBuildType]. class TypeBuilder { - final LinkedBundleContext bundleContext; + final LinkingBundleContext bundleContext; TypeBuilder(this.bundleContext); - LinkedNodeTypeBuilder get _dynamicType { - return LinkedNodeTypeBuilder( - kind: LinkedNodeTypeKind.dynamic_, - ); + DynamicTypeImpl get _dynamicType { + return DynamicTypeImpl.instance; } - void build(TypesToBuild typesToBuild) { - for (var node in typesToBuild.typeAnnotations) { - var kind = node.kind; - if (kind == LinkedNodeKind.genericFunctionType) { - _buildGenericFunctionType(node); - } else if (kind == LinkedNodeKind.typeName) { - _buildTypeName(node); - } else { - throw StateError('$kind'); + void build(NodesToBuildType nodesToBuildType) { + for (var item in nodesToBuildType.items) { + if (item.typeAnnotation != null) { + var node = item.typeAnnotation; + if (node is GenericFunctionType) { + _buildGenericFunctionType(node); + } else if (node is TypeName) { + _buildTypeName(node); + } else { + throw StateError('${node.runtimeType}'); + } + } else if (item.declaration != null) { + _setTypesForDeclaration(item.declaration); } } - for (var node in typesToBuild.declarations) { - _setTypesForDeclaration(node); - } } - LinkedNodeTypeBuilder _buildFunctionType( - LinkedNode returnTypeNode, - LinkedNode parameterList, + DartType _buildFunctionType( + TypeAnnotation returnTypeNode, + FormalParameterList parameterList, ) { - var returnType = _getType(returnTypeNode); + var returnType = returnTypeNode?.type ?? _dynamicType; - var formalParameters = <LinkedNodeTypeFormalParameterBuilder>[]; - for (var parameter in parameterList.formalParameterList_parameters) { - formalParameters.add(LinkedNodeTypeFormalParameterBuilder( - kind: parameter.formalParameter_kind, - type: _getFormalParameterType(parameter), - )); - } + // TODO(scheglov) type parameters + var typeParameters = const <TypeParameterElement>[]; - return LinkedNodeTypeBuilder( - kind: LinkedNodeTypeKind.function, - functionFormalParameters: formalParameters, - functionReturnType: returnType, + var formalParameters = parameterList.parameters.map((p) { + // TODO(scheglov) other types and kinds + return ParameterElementImpl.synthetic( + (p as SimpleFormalParameter).identifier.name, + LazyAst.getType(p), + ParameterKind.REQUIRED, + ); + }).toList(); + + return FunctionTypeImpl.synthetic( + returnType, + typeParameters, + formalParameters, ); } - void _buildGenericFunctionType(LinkedNodeBuilder node) { + void _buildGenericFunctionType(GenericFunctionTypeImpl node) { // TODO(scheglov) Type parameters? - node.genericFunctionType_type = _buildFunctionType( - node.genericFunctionType_returnType, - node.genericFunctionType_formalParameters, - ); + node.type = _buildFunctionType(node.returnType, node.parameters); } - void _buildTypeName(LinkedNodeBuilder node) { - var referenceIndex = _typeNameElementIndex(node.typeName_name); - var reference = bundleContext.referenceOfIndex(referenceIndex); + void _buildTypeName(TypeName node) { + var element = node.name.staticElement; - List<LinkedNodeTypeBuilder> typeArguments; - var typeArgumentList = node.typeName_typeArguments; + List<DartType> typeArguments; + var typeArgumentList = node.typeArguments; if (typeArgumentList != null) { - typeArguments = typeArgumentList.typeArgumentList_arguments - .map((node) => _getType(node)) - .toList(); + typeArguments = typeArgumentList.arguments.map((a) => a.type).toList(); } - if (reference.isClass) { + if (element is ClassElement) { + if (element.isEnum) { + node.type = InterfaceTypeImpl.explicit(element, const []); + } else { + // TODO(scheglov) Use instantiate to bounds. + var typeParametersLength = element.typeParameters.length; + if (typeArguments == null || + typeArguments.length != typeParametersLength) { + typeArguments = List<DartType>.filled( + typeParametersLength, + DynamicTypeImpl.instance, + ); + } + node.type = InterfaceTypeImpl.explicit(element, typeArguments); + } + } else if (element is GenericTypeAliasElement) { // TODO(scheglov) Use instantiate to bounds. - var typeParametersLength = _typeParametersLength(reference); + var typeParametersLength = element.typeParameters.length; if (typeArguments == null || typeArguments.length != typeParametersLength) { - typeArguments = List<LinkedNodeTypeBuilder>.filled( + typeArguments = List<DartType>.filled( typeParametersLength, - _dynamicType, + DynamicTypeImpl.instance, ); } - node.typeName_type = LinkedNodeTypeBuilder( - kind: LinkedNodeTypeKind.interface, - interfaceClass: referenceIndex, - interfaceTypeArguments: typeArguments, + + var substitution = Substitution.fromPairs( + element.typeParameters, + typeArguments, ); - } else if (reference.isDynamic) { - node.typeName_type = LinkedNodeTypeBuilder( - kind: LinkedNodeTypeKind.dynamic_, - ); - } else if (reference.isGenericTypeAlias) { - // TODO(scheglov) Use instantiate to bounds. - var typeParametersLength = _typeParametersLength(reference); - if (typeArguments == null || - typeArguments.length != typeParametersLength) { - typeArguments = List<LinkedNodeTypeBuilder>.filled( - typeParametersLength, - _dynamicType, - ); - } - node.typeName_type = LinkedNodeTypeBuilder( - kind: LinkedNodeTypeKind.genericTypeAlias, - genericTypeAliasReference: referenceIndex, - genericTypeAliasTypeArguments: typeArguments, - ); - } else if (reference.isEnum) { - node.typeName_type = LinkedNodeTypeBuilder( - kind: LinkedNodeTypeKind.interface, - interfaceClass: referenceIndex, - ); - } else if (reference.isTypeParameter) { - node.typeName_type = LinkedNodeTypeBuilder( - kind: LinkedNodeTypeKind.typeParameter, - typeParameterParameter: referenceIndex, - ); + + // TODO(scheglov) Not sure if I like this. + var type = substitution.substituteType(element.function.type); + node.type = type; + } else if (element is TypeParameterElement) { + node.type = TypeParameterTypeImpl(element); } else { - node.typeName_type = _dynamicType; +// throw UnimplementedError('${element.runtimeType}'); + // TODO(scheglov) implement + node.type = DynamicTypeImpl.instance; } + +// var referenceIndex = typeNameElementIndex(node.typeName_name); +// var reference = bundleContext.referenceOfIndex(referenceIndex); +// +// List<LinkedNodeTypeBuilder> typeArguments; +// var typeArgumentList = node.typeName_typeArguments; +// if (typeArgumentList != null) { +// typeArguments = typeArgumentList.typeArgumentList_arguments +// .map((node) => _getType(node)) +// .toList(); +// } +// +// if (reference.isClass) { +// // TODO(scheglov) Use instantiate to bounds. +// var typeParametersLength = _typeParametersLength(reference); +// if (typeArguments == null || +// typeArguments.length != typeParametersLength) { +// typeArguments = List<LinkedNodeTypeBuilder>.filled( +// typeParametersLength, +// _dynamicType, +// ); +// } +// node.typeName_type = LinkedNodeTypeBuilder( +// kind: LinkedNodeTypeKind.interface, +// interfaceClass: referenceIndex, +// interfaceTypeArguments: typeArguments, +// ); +// } else if (reference.isDynamic) { +// node.typeName_type = LinkedNodeTypeBuilder( +// kind: LinkedNodeTypeKind.dynamic_, +// ); +// } else if (reference.isTypeAlias) { +// // TODO(scheglov) Use instantiate to bounds. +// var typeParametersLength = _typeParametersLength(reference); +// if (typeArguments == null || +// typeArguments.length != typeParametersLength) { +// typeArguments = List<LinkedNodeTypeBuilder>.filled( +// typeParametersLength, +// _dynamicType, +// ); +// } +// node.typeName_type = LinkedNodeTypeBuilder( +// kind: LinkedNodeTypeKind.genericTypeAlias, +// genericTypeAliasReference: referenceIndex, +// genericTypeAliasTypeArguments: typeArguments, +// ); +// } else if (reference.isEnum) { +// node.typeName_type = LinkedNodeTypeBuilder( +// kind: LinkedNodeTypeKind.interface, +// interfaceClass: referenceIndex, +// ); +// } else if (reference.isTypeParameter) { +// node.typeName_type = LinkedNodeTypeBuilder( +// kind: LinkedNodeTypeKind.typeParameter, +// typeParameterParameter: referenceIndex, +// ); +// } else { +// node.typeName_type = _dynamicType; +// } } - void _fieldFormalParameter(LinkedNodeBuilder node) { - var parameterList = node.fieldFormalParameter_formalParameters; + void _fieldFormalParameter(FieldFormalParameter node) { + var parameterList = node.parameters; if (parameterList != null) { - node.fieldFormalParameter_type2 = _buildFunctionType( - node.fieldFormalParameter_type, - parameterList, - ); + var type = _buildFunctionType(node.type, parameterList); + LazyAst.setType(node, type); } else { - var type = _getType(node.fieldFormalParameter_type); - node.fieldFormalParameter_type2 = type; + LazyAst.setType(node, node.type?.type ?? _dynamicType); } } - void _functionTypedFormalParameter(LinkedNodeBuilder node) { - node.functionTypedFormalParameter_type2 = _buildFunctionType( - node.functionTypedFormalParameter_returnType, - node.functionTypedFormalParameter_formalParameters, - ); + void _functionTypedFormalParameter(FunctionTypedFormalParameter node) { + var type = _buildFunctionType(node.returnType, node.parameters); + LazyAst.setType(node, type); } - LinkedNodeTypeBuilder _getFormalParameterType(LinkedNode node) { - var kind = node.kind; - if (kind == LinkedNodeKind.defaultFormalParameter) { - return _getFormalParameterType(node.defaultFormalParameter_parameter); - } - if (kind == LinkedNodeKind.functionTypedFormalParameter) { - return node.functionTypedFormalParameter_type2; - } - if (kind == LinkedNodeKind.simpleFormalParameter) { - return _getType(node.simpleFormalParameter_type); - } - throw UnimplementedError('$kind'); - } +// LinkedNodeTypeBuilder _getFormalParameterType(LinkedNode node) { +// var kind = node.kind; +// if (kind == LinkedNodeKind.defaultFormalParameter) { +// return _getFormalParameterType(node.defaultFormalParameter_parameter); +// } +// if (kind == LinkedNodeKind.functionTypedFormalParameter) { +// return node.functionTypedFormalParameter_type2; +// } +// if (kind == LinkedNodeKind.simpleFormalParameter) { +// return _getType(node.simpleFormalParameter_type); +// } +// throw UnimplementedError('$kind'); +// } - LinkedNodeTypeBuilder _getType(LinkedNodeBuilder node) { - if (node == null) return _dynamicType; +// LinkedNodeTypeBuilder _getType(LinkedNodeBuilder node) { +// if (node == null) return _dynamicType; +// +// var kind = node.kind; +// if (kind == LinkedNodeKind.genericFunctionType) { +// return node.genericFunctionType_type; +// } else if (kind == LinkedNodeKind.typeName) { +// return node.typeName_type; +// } else { +// throw UnimplementedError('$kind'); +// } +// } - var kind = node.kind; - if (kind == LinkedNodeKind.genericFunctionType) { - return node.genericFunctionType_type; - } else if (kind == LinkedNodeKind.typeName) { - return node.typeName_type; - } else { - throw UnimplementedError('$kind'); - } - } - - void _setTypesForDeclaration(LinkedNodeBuilder node) { - var kind = node.kind; - if (kind == LinkedNodeKind.fieldFormalParameter) { + void _setTypesForDeclaration(AstNode node) { + if (node is FieldFormalParameter) { _fieldFormalParameter(node); - } else if (kind == LinkedNodeKind.functionDeclaration) { - node.functionDeclaration_returnType2 = _getType( - node.functionDeclaration_returnType, - ); - } else if (kind == LinkedNodeKind.functionTypeAlias) { - node.functionTypeAlias_returnType2 = _getType( - node.functionTypeAlias_returnType, - ); - } else if (kind == LinkedNodeKind.functionTypedFormalParameter) { + } else if (node is FunctionDeclaration) { + LazyAst.setReturnType(node, node.returnType?.type ?? _dynamicType); + } else if (node is FunctionTypeAlias) { + LazyAst.setReturnType(node, node.returnType?.type ?? _dynamicType); + } else if (node is FunctionTypedFormalParameter) { _functionTypedFormalParameter(node); - } else if (kind == LinkedNodeKind.genericFunctionType) { - node.genericFunctionType_returnType2 = _getType( - node.genericFunctionType_returnType, - ); - } else if (kind == LinkedNodeKind.methodDeclaration) { - node.methodDeclaration_returnType2 = _getType( - node.methodDeclaration_returnType, - ); - } else if (kind == LinkedNodeKind.simpleFormalParameter) { - node.simpleFormalParameter_type2 = _getType( - node.simpleFormalParameter_type, - ); - } else if (kind == LinkedNodeKind.variableDeclarationList) { - var typeNode = node.variableDeclarationList_type; - for (var variable in node.variableDeclarationList_variables) { - variable.variableDeclaration_type2 = _getType(typeNode); + } else if (node is GenericFunctionType) { + LazyAst.setReturnType(node, node.returnType?.type ?? _dynamicType); + } else if (node is MethodDeclaration) { + if (node.returnType != null) { + LazyAst.setReturnType(node, node.returnType.type); + } + } else if (node is SimpleFormalParameter) { + // TODO(scheglov) use top-level inference + LazyAst.setType(node, node.type?.type ?? _dynamicType); + } else if (node is VariableDeclarationList) { + var type = node.type?.type; + if (type != null) { + for (var variable in node.variables) { + LazyAst.setType(variable, type); + } } } else { - throw UnimplementedError('$kind'); + throw UnimplementedError('${node.runtimeType}'); } +// var kind = node.kind; +// if (kind == LinkedNodeKind.fieldFormalParameter) { +// _fieldFormalParameter(node); +// } else if (kind == LinkedNodeKind.functionDeclaration) { +// node.functionDeclaration_returnType2 = _getType( +// node.functionDeclaration_returnType, +// ); +// } else if (kind == LinkedNodeKind.functionTypeAlias) { +// node.functionTypeAlias_returnType2 = _getType( +// node.functionTypeAlias_returnType, +// ); +// } else if (kind == LinkedNodeKind.functionTypedFormalParameter) { +// _functionTypedFormalParameter(node); +// } else if (kind == LinkedNodeKind.genericFunctionType) { +// node.genericFunctionType_returnType2 = _getType( +// node.genericFunctionType_returnType, +// ); +// } else if (kind == LinkedNodeKind.methodDeclaration) { +// node.methodDeclaration_returnType2 = _getType( +// node.methodDeclaration_returnType, +// ); +// } else if (kind == LinkedNodeKind.simpleFormalParameter) { +// node.simpleFormalParameter_type2 = _getType( +// node.simpleFormalParameter_type, +// ); +// } else if (kind == LinkedNodeKind.variableDeclarationList) { +// var typeNode = node.variableDeclarationList_type; +// for (var variable in node.variableDeclarationList_variables) { +// variable.variableDeclaration_type2 = _getType(typeNode); +// } +// } else { +// throw UnimplementedError('$kind'); +// } } - int _typeParametersLength(Reference reference) { - var node = bundleContext.elementFactory.nodeOfReference(reference); - return LinkedUnitContext.getTypeParameters(node)?.length ?? 0; - } +// int _typeParametersLength(Reference reference) { +// var node = bundleContext.elementFactory.nodeOfReference(reference); +// return LinkedUnitContext.getTypeParameters(node)?.length ?? 0; +// } - static int _typeNameElementIndex(LinkedNode name) { + static int typeNameElementIndex(LinkedNode name) { if (name.kind == LinkedNodeKind.simpleIdentifier) { return name.simpleIdentifier_element; } else {
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart index 351daef..9bc342b 100644 --- a/pkg/analyzer/lib/src/task/options.dart +++ b/pkg/analyzer/lib/src/task/options.dart
@@ -121,9 +121,13 @@ static const String exclude = 'exclude'; static const String include = 'include'; static const String language = 'language'; + static const String optionalChecks = 'optional-checks'; static const String plugins = 'plugins'; static const String strong_mode = 'strong-mode'; + // Optional checks options. + static const String chromeOsManifestChecks = 'chrome-os-manifest-checks'; + // Strong mode options (see AnalysisOptionsImpl for documentation). static const String declarationCasts = 'declaration-casts'; static const String implicitCasts = 'implicit-casts'; @@ -152,6 +156,7 @@ errors, exclude, language, + optionalChecks, plugins, strong_mode, ]; @@ -168,6 +173,11 @@ strictInference, strictRawTypes ]; + + // Supported 'analyzer' optional checks options. + static const List<String> optionalCecksOptions = const [ + chromeOsManifestChecks, + ]; } /// Validates `analyzer` options. @@ -178,7 +188,8 @@ new StrongModeOptionValueValidator(), new ErrorFilterOptionValidator(), new EnabledExperimentsValidator(), - new LanguageOptionValidator() + new LanguageOptionValidator(), + new OptionalChecksValueValidator() ]); } @@ -484,6 +495,43 @@ } } +/// Validates `analyzer` optional-checks value configuration options. +class OptionalChecksValueValidator extends OptionsValidator { + ErrorBuilder builder = new ErrorBuilder(AnalyzerOptions.optionalCecksOptions); + ErrorBuilder trueOrFalseBuilder = new TrueOrFalseValueErrorBuilder(); + + @override + void validate(ErrorReporter reporter, YamlMap options) { + var analyzer = getValue(options, AnalyzerOptions.analyzer); + if (analyzer is YamlMap) { + var v = getValue(analyzer, AnalyzerOptions.optionalChecks); + if (v is YamlScalar) { + var value = toLowerCase(v.value); + if (value != AnalyzerOptions.chromeOsManifestChecks) { + builder.reportError( + reporter, AnalyzerOptions.chromeOsManifestChecks, v); + } + } else if (v is YamlMap) { + v.nodes.forEach((k, v) { + String key, value; + if (k is YamlScalar) { + key = k.value?.toString(); + if (key != AnalyzerOptions.chromeOsManifestChecks) { + builder.reportError( + reporter, AnalyzerOptions.chromeOsManifestChecks, k); + } else { + value = toLowerCase(v.value); + if (!AnalyzerOptions.trueOrFalse.contains(value)) { + trueOrFalseBuilder.reportError(reporter, key, v); + } + } + } + }); + } + } + } +} + /// Validates `analyzer` top-level options. class TopLevelAnalyzerOptionsValidator extends TopLevelOptionValidator { TopLevelAnalyzerOptionsValidator() @@ -572,6 +620,10 @@ options.enabledExperiments = enabledExperiments; } + // Process optional checks options. + var optionalChecks = getValue(analyzer, AnalyzerOptions.optionalChecks); + _applyOptionalChecks(options, optionalChecks); + // Process language options. var language = getValue(analyzer, AnalyzerOptions.language); _applyLanguageOptions(options, language); @@ -675,6 +727,31 @@ } } + void _applyOptionalChecksOption( + AnalysisOptionsImpl options, String feature, Object value) { + bool boolValue = toBool(value); + if (boolValue != null) { + if (feature == AnalyzerOptions.chromeOsManifestChecks) { + options.chromeOsManifestChecks = boolValue; + } + } + } + + void _applyOptionalChecks(AnalysisOptionsImpl options, YamlNode config) { + if (config is YamlMap) { + config.nodes.forEach((k, v) { + if (k is YamlScalar && v is YamlScalar) { + _applyOptionalChecksOption(options, k.value?.toString(), v.value); + } + }); + } + if (config is YamlScalar) { + if (config.value?.toString() == AnalyzerOptions.chromeOsManifestChecks) { + options.chromeOsManifestChecks = true; + } + } + } + String _toString(YamlNode node) { if (node is YamlScalar) { var value = node.value;
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart index d4c070c..917fc1c 100644 --- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart +++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -340,6 +340,7 @@ external factory String.fromCharCodes(Iterable<int> charCodes, [int start = 0, int end]); List<int> get codeUnits; + int indexOf(Pattern pattern, [int start]); bool get isEmpty => false; bool get isNotEmpty => false; int get length => 0;
diff --git a/pkg/analyzer/lib/src/test_utilities/package_mixin.dart b/pkg/analyzer/lib/src/test_utilities/package_mixin.dart index 9ad69d8..9fe449e 100644 --- a/pkg/analyzer/lib/src/test_utilities/package_mixin.dart +++ b/pkg/analyzer/lib/src/test_utilities/package_mixin.dart
@@ -22,6 +22,7 @@ const Immutable immutable = const Immutable(); const _Literal literal = const _Literal(); const _MustCallSuper mustCallSuper = const _MustCallSuper(); +const _OptionalTypeArgs optionalTypeArgs = const _OptionalTypeArgs(); const _Protected protected = const _Protected(); const Required required = const Required(); const _Sealed sealed = const _Sealed(); @@ -43,6 +44,9 @@ class _MustCallSuper { const _MustCallSuper(); } +class _OptionalTypeArgs { + const _OptionalTypeArgs(); +} class _Protected { const _Protected(); }
diff --git a/pkg/analyzer/lib/src/workspace/gn.dart b/pkg/analyzer/lib/src/workspace/gn.dart index 6490363..1f2a608 100644 --- a/pkg/analyzer/lib/src/workspace/gn.dart +++ b/pkg/analyzer/lib/src/workspace/gn.dart
@@ -267,15 +267,14 @@ * that file cannot be found, looks for standard output directory locations. */ static Folder _getOutDirectory(String root, ResourceProvider provider) { + const String fuchsiaDirConfigFile = '.fx-build-dir'; + path.Context pathContext = provider.pathContext; - File config = provider.getFile(pathContext.join(root, '.config')); - if (config.exists) { - String content = config.readAsStringSync(); - Match match = - new RegExp(r'^FUCHSIA_BUILD_DIR=["\x27](.+)["\x27]$', multiLine: true) - .firstMatch(content); - if (match != null) { - String buildDirPath = match.group(1); + File configFile = + provider.getFile(pathContext.join(root, fuchsiaDirConfigFile)); + if (configFile.exists) { + String buildDirPath = configFile.readAsStringSync().trim(); + if (buildDirPath.isNotEmpty) { if (pathContext.isRelative(buildDirPath)) { buildDirPath = pathContext.join(root, buildDirPath); }
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml index b49c0f3..cf9777b 100644 --- a/pkg/analyzer/pubspec.yaml +++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@ name: analyzer -version: 0.36.0 +version: 0.36.1-dev author: Dart Team <misc@dartlang.org> description: Static analyzer for Dart. homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer @@ -13,6 +13,7 @@ crypto: '>=1.1.1 <3.0.0' front_end: 0.1.15 glob: ^1.0.3 + html: '>=0.13.4+1 <0.15.0' kernel: 0.3.15 meta: ^1.0.2 package_config: '>=0.1.5 <2.0.0'
diff --git a/pkg/analyzer/test/error/error_test.dart b/pkg/analyzer/test/error/error_test.dart index 379efcd..b68dbac 100644 --- a/pkg/analyzer/test/error/error_test.dart +++ b/pkg/analyzer/test/error/error_test.dart
@@ -6,14 +6,17 @@ import 'dart:io'; import 'package:analyzer/dart/ast/ast.dart'; -import 'package:front_end/src/testing/package_root.dart' as package_root; import 'package:path/path.dart' as path; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../generated/parser_test.dart'; +List<String> _analyzerRootComponents; + main() { + _analyzerRootComponents = + path.split(path.fromUri(Platform.script.resolve("../../"))); defineReflectiveSuite(() { defineReflectiveTests(ErrorCodeValuesTest); }); @@ -21,17 +24,6 @@ @reflectiveTest class ErrorCodeValuesTest extends ParserTestCase { - List<String> _rootComponents; - - List<String> get rootComponents { - if (_rootComponents == null) { - List<String> components = path.split(package_root.packageRoot); - components.add('analyzer'); - _rootComponents = components; - } - return _rootComponents; - } - bool bad() { return false; } @@ -77,7 +69,7 @@ } CompilationUnit parseFile(List<String> relativeComponents) { - List<String> pathComponents = rootComponents.toList() + List<String> pathComponents = _analyzerRootComponents.toList() ..addAll(relativeComponents); String filePath = path.normalize(path.joinAll(pathComponents)); return parseCompilationUnit(new File(filePath).readAsStringSync());
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart index 3601b5c..6318820 100644 --- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart +++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
@@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/error/codes.dart'; -import 'package:analyzer/src/generated/engine.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../src/dart/resolution/driver_resolution.dart'; @@ -16,9 +15,6 @@ @reflectiveTest class CheckedModeCompileTimeErrorCodeTest extends DriverResolutionTest { - @override - AnalysisOptions get defaultAnalysisOptions => new AnalysisOptionsImpl(); - test_assertion_throws() async { await assertErrorsInCode(r''' class A {
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart index b767777..2daae3d 100644 --- a/pkg/analyzer/test/generated/compile_time_error_code.dart +++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -6,6 +6,7 @@ import 'package:analyzer/dart/analysis/declared_variables.dart'; import 'package:analyzer/error/error.dart'; +import 'package:analyzer/src/dart/analysis/experiments.dart'; import 'package:analyzer/src/error/codes.dart'; import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode; import 'package:analyzer/src/generated/source_io.dart'; @@ -622,14 +623,18 @@ } test_constEvalTypeBoolNumString_equal() async { - await assertErrorsInCode(r''' + await assertErrorsInCode( + r''' class A { const A(); } const num a = 0; const _ = a == const A(); -''', [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING]); +''', + IsEnabledByDefault.constant_update_2018 + ? [] + : [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING]); } test_constEvalTypeBoolNumString_notEqual() async {
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart index 18bb4a8..d13e5f5 100644 --- a/pkg/analyzer/test/generated/hint_code_test.dart +++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -2,7 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/error/error.dart'; import 'package:analyzer/src/error/codes.dart'; import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/generated/parser.dart'; @@ -19,58 +18,11 @@ }); } -/// The contents of the 'meta' package. Code that uses this variable should be -/// converted to use PackageMixin.addMetaPackage. -final _metaLibraryStub = r''' -library meta; - -const _AlwaysThrows alwaysThrows = const _AlwaysThrows(); -const _Factory factory = const _Factory(); -const Immutable immutable = const Immutable(); -const _Literal literal = const _Literal(); -const _MustCallSuper mustCallSuper = const _MustCallSuper(); -const _Protected protected = const _Protected(); -const Required required = const Required(); -const _Sealed sealed = const _Sealed(); -const _VisibleForTesting visibleForTesting = const _VisibleForTesting(); - -class Immutable { - final String reason; - const Immutable([this.reason]); -} -class _AlwaysThrows { - const _AlwaysThrows(); -} -class _Factory { - const _Factory(); -} -class _Literal { - const _Literal(); -} -class _MustCallSuper { - const _MustCallSuper(); -} -class _Protected { - const _Protected(); -} -class Required { - final String reason; - const Required([this.reason]); -} -class _Sealed { - const _Sealed(); -} -class _VisibleForTesting { - const _VisibleForTesting(); -} -'''; - @reflectiveTest class HintCodeTest extends ResolverTestCase { @override void reset() { super.resetWith(packages: [ - ['meta', _metaLibraryStub], [ 'js', r''' @@ -80,18 +32,6 @@ } ''' ], - [ - 'angular_meta', - r''' -library angular.meta; - -const _VisibleForTemplate visibleForTemplate = const _VisibleForTemplate(); - -class _VisibleForTemplate { - const _VisibleForTemplate(); -} -''' - ], ]); } @@ -174,1004 +114,6 @@ verify([source]); } - test_factory__expr_return_null_OK() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -class Stateful { - @factory - State createState() => null; -} - -class State { } -'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_factory_abstract_OK() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -abstract class Stateful { - @factory - State createState(); -} - -class State { } -'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_factory_bad_return() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -class Stateful { - State _s = new State(); - - @factory - State createState() => _s; -} - -class State { } -'''); - await computeAnalysisResult(source); - assertErrors(source, [HintCode.INVALID_FACTORY_METHOD_IMPL]); - verify([source]); - } - - test_factory_block_OK() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -class Stateful { - @factory - State createState() { - return new State(); - } -} - -class State { } -'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_factory_block_return_null_OK() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -class Stateful { - @factory - State createState() { - return null; - } -} - -class State { } -'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_factory_expr_OK() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -class Stateful { - @factory - State createState() => new State(); -} - -class State { } -'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_factory_misplaced_annotation() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -@factory -class X { - @factory - int x; -} - -@factory -main() { } -'''); - await computeAnalysisResult(source); - assertErrors(source, [ - HintCode.INVALID_FACTORY_ANNOTATION, - HintCode.INVALID_FACTORY_ANNOTATION, - HintCode.INVALID_FACTORY_ANNOTATION - ]); - verify([source]); - } - - test_factory_no_return_type_OK() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -class Stateful { - @factory - createState() { - return new Stateful(); - } -} -'''); - // Null return types will get flagged elsewhere, no need to pile-on here. - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_factory_subclass_OK() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -abstract class Stateful { - @factory - State createState(); -} - -class MyThing extends Stateful { - @override - State createState() { - print('my state'); - return new MyState(); - } -} - -class State { } -class MyState extends State { } -'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_factory_void_return() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -class Stateful { - @factory - void createState() {} -} -'''); - await computeAnalysisResult(source); - assertErrors(source, [HintCode.INVALID_FACTORY_METHOD_DECL]); - verify([source]); - } - - test_invalidUseOfProtectedMember_closure() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:meta/meta.dart'; - -class A { - @protected - int a() => 42; -} -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -void main() { - var leak = new A().a; - print(leak); -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); - assertNoErrors(source); - verify([source, source2]); - } - - test_invalidUseOfProtectedMember_field() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:meta/meta.dart'; -class A { - @protected - int a; -} -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -abstract class B { - int b() => new A().a; -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); - assertNoErrors(source); - verify([source, source2]); - } - - test_invalidUseOfProtectedMember_field_OK() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; -class A { - @protected - int a; -} -abstract class B implements A { - int b() => a; -}'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_invalidUseOfProtectedMember_fromSuperclassConstraint() async { - Source sourceA = addNamedSource('/a.dart', r''' -import 'package:meta/meta.dart'; - -abstract class A { - @protected - void foo() {} -} -'''); - Source sourceM = addNamedSource('/m.dart', r''' -import 'a.dart'; - -mixin M on A { - @override - void foo() { - super.foo(); - } -} -'''); - - await computeAnalysisResult(sourceA); - await computeAnalysisResult(sourceM); - assertNoErrors(sourceA); - assertNoErrors(sourceM); - verify([sourceA, sourceM]); - } - - test_invalidUseOfProtectedMember_function() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:meta/meta.dart'; -class A { - @protected - void a(){ } -} -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -main() { - new A().a(); -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); - assertNoErrors(source); - verify([source, source2]); - } - - test_invalidUseOfProtectedMember_function_OK() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; -class A { - @protected - int a() => 0; -} - -abstract class B implements A { - int b() => a(); -}'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_invalidUseOfProtectedMember_function_OK2() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; -class A { - @protected - void a(){ } -} -main() { - new A().a(); -}'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_invalidUseOfProtectedMember_getter() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:meta/meta.dart'; -class A { - @protected - int get a => 42; -} -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -class B { - A a; - int b() => a.a; -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); - assertNoErrors(source); - verify([source, source2]); - } - - test_invalidUseOfProtectedMember_getter_OK() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; -class A { - @protected - int get a => 42; -} -abstract class B implements A { - int b() => a; -}'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_invalidUseOfProtectedMember_in_docs_OK() async { - addNamedSource('/a.dart', r''' -import 'package:meta/meta.dart'; - -class A { - @protected - int c = 0; - - @protected - int get b => 0; - - @protected - int a() => 0; -} -'''); - Source source = addSource(r''' -import 'a.dart'; - -/// OK: [A.a], [A.b], [A.c]. -f() {} -'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_invalidUseOfProtectedMember_message() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:meta/meta.dart'; -class A { - @protected - void a(){ } -} -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -class B { - void b() => new A().a(); -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); - verify([source, source2]); - } - - test_invalidUseOfProtectedMember_method_1() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:meta/meta.dart'; -class A { - @protected - void a(){ } -} -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -class B { - void b() => new A().a(); -} -'''); - - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); - assertNoErrors(source); - verify([source, source2]); - } - - test_invalidUseOfProtectedMember_method_OK() async { - // https://github.com/dart-lang/linter/issues/257 - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -typedef void VoidCallback(); - -class State<E> { - @protected - void setState(VoidCallback fn) {} -} - -class Button extends State<Object> { - void handleSomething() { - setState(() {}); - } -} -'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_invalidUseOfProtectedMember_OK_1() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; -class A { - @protected - void a(){ } -} -class B extends A { - void b() => a(); -}'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_invalidUseOfProtectedMember_OK_2() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; -class A { - @protected - void a(){ } -} -class B extends Object with A { - void b() => a(); -}'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_invalidUseOfProtectedMember_OK_3() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; -class A { - @protected m1() {} -} -class B extends A { - static m2(A a) => a.m1(); -}'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_invalidUseOfProtectedMember_OK_4() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; -class A { - @protected - void a(){ } -} -class B extends A { - void a() => a(); -} -main() { - new B().a(); -}'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_invalidUseOfProtectedMember_OK_field() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; -class A { - @protected - int a = 42; -} -class B extends A { - int b() => a; -} -'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_invalidUseOfProtectedMember_OK_getter() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; -class A { - @protected - int get a => 42; -} -class B extends A { - int b() => a; -} -'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_invalidUseOfProtectedMember_OK_setter() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; -class A { - @protected - void set a(int i) { } -} -class B extends A { - void b(int i) { - a = i; - } -} -'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_invalidUseOfProtectedMember_OK_setter_2() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; -class A { - int _a; - @protected - void set a(int a) { _a = a; } - A(int a) { - this.a = a; - } -} -'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_invalidUseOfProtectedMember_setter() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:meta/meta.dart'; -class A { - @protected - void set a(int i) { } -} -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -class B{ - A a; - b(int i) { - a.a = i; - } -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); - assertNoErrors(source); - verify([source, source2]); - } - - test_invalidUseOfProtectedMember_setter_OK() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; -class A { - @protected - void set a(int i) { } -} -abstract class B implements A { - b(int i) { - a = i; - } -}'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_invalidUseOfProtectedMember_topLevelVariable() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; -@protected -int x = 0; -main() { - print(x); -}'''); - // TODO(brianwilkerson) This should produce a hint because the annotation is - // being applied to the wrong kind of declaration. - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_invalidUseOfVisibleForTemplateMember_constructor() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:angular_meta/angular_meta.dart'; -class A { - int _x; - - @visibleForTemplate - A.forTemplate(this._x); -} -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -void main() { - new A.forTemplate(0); -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertErrors( - source2, [HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]); - verify([source, source2]); - } - - test_invalidUseOfVisibleForTemplateMember_export_OK() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:angular_meta/angular_meta.dart'; - -@visibleForTemplate -int fn0() => 1; -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -export 'lib1.dart' show fn0; -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertNoErrors(source2); - verify([source, source2]); - } - - test_invalidUseOfVisibleForTemplateMember_method() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:angular_meta/angular_meta.dart'; -class A { - @visibleForTemplate - void a(){ } -} -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -class B { - void b() => new A().a(); -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertErrors( - source2, [HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]); - verify([source, source2]); - } - - test_invalidUseOfVisibleForTemplateMember_method_OK() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:angular_meta/angular_meta.dart'; -class A { - @visibleForTemplate - void a(){ } -} -'''); - Source source2 = addNamedSource('/lib1.template.dart', r''' -import 'lib1.dart'; - -class B { - void b() => new A().a(); -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertNoErrors(source2); - verify([source, source2]); - } - - test_invalidUseOfVisibleForTemplateMember_propertyAccess() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:angular_meta/angular_meta.dart'; -class A { - @visibleForTemplate - int get a => 7; - - @visibleForTemplate - set b(_) => 7; -} -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -void main() { - new A().a; - new A().b = 6; -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertErrors(source2, [ - HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER, - HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER - ]); - verify([source, source2]); - } - - test_invalidUseOfVisibleForTemplateMember_topLevelFunction() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:angular_meta/angular_meta.dart'; - -@visibleForTemplate -int fn0() => 1; -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -void main() { - fn0(); -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertErrors( - source2, [HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]); - verify([source, source2]); - } - - test_invalidUseOfVisibleForTestingMember_constructor() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:meta/meta.dart'; -class A { - int _x; - - @visibleForTesting - A.forTesting(this._x); -} -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -void main() { - new A.forTesting(0); -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertErrors(source2, [HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]); - verify([source, source2]); - } - - test_invalidUseOfVisibleForTestingMember_export_OK() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:meta/meta.dart'; - -@visibleForTesting -int fn0() => 1; -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -export 'lib1.dart' show fn0; -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertNoErrors(source2); - verify([source, source2]); - } - - test_invalidUseOfVisibleForTestingMember_method() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:meta/meta.dart'; -class A { - @visibleForTesting - void a(){ } -} -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -class B { - void b() => new A().a(); -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertErrors(source2, [HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]); - verify([source, source2]); - } - - test_invalidUseOfVisibleForTestingMember_method_OK() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:meta/meta.dart'; -class A { - @visibleForTesting - void a(){ } -} -'''); - Source source2 = addNamedSource('/test/test1.dart', r''' -import '../lib1.dart'; - -class B { - void b() => new A().a(); -} -'''); - Source source3 = addNamedSource('/testing/lib1.dart', r''' -import '../lib1.dart'; - -class C { - void b() => new A().a(); -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - await computeAnalysisResult(source3); - assertNoErrors(source2); - assertNoErrors(source3); - verify([source, source2, source3]); - } - - test_invalidUseOfVisibleForTestingMember_propertyAccess() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:meta/meta.dart'; -class A { - @visibleForTesting - int get a => 7; - - @visibleForTesting - set b(_) => 7; -} -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -void main() { - new A().a; - new A().b = 6; -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertErrors(source2, [ - HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER, - HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER - ]); - verify([source, source2]); - } - - test_invalidUseOfVisibleForTestingMember_topLevelFunction() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:meta/meta.dart'; - -@visibleForTesting -int fn0() => 1; -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -void main() { - fn0(); -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertErrors(source2, [HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]); - verify([source, source2]); - } - - test_invalidUseProtectedAndForTemplate_asProtected_OK() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:angular_meta/angular_meta.dart'; -import 'package:meta/meta.dart'; -class A { - @protected - @visibleForTemplate - void a(){ } -} -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -class B extends A { - void b() => new A().a(); -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertNoErrors(source2); - verify([source, source2]); - } - - test_invalidUseProtectedAndForTemplate_asTemplate_OK() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:angular_meta/angular_meta.dart'; -import 'package:meta/meta.dart'; -class A { - @protected - @visibleForTemplate - void a(){ } -} -'''); - Source source2 = addNamedSource('/lib1.template.dart', r''' -import 'lib1.dart'; - -void main() { - new A().a(); -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertNoErrors(source2); - verify([source, source2]); - } - - test_invalidUseProtectedAndForTesting_asProtected_OK() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:meta/meta.dart'; -class A { - @protected - @visibleForTesting - void a(){ } -} -'''); - Source source2 = addNamedSource('/lib2.dart', r''' -import 'lib1.dart'; - -class B extends A { - void b() => new A().a(); -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertNoErrors(source2); - verify([source, source2]); - } - - test_invalidUseProtectedAndForTesting_asTesting_OK() async { - Source source = addNamedSource('/lib1.dart', r''' -import 'package:meta/meta.dart'; -class A { - @protected - @visibleForTesting - void a(){ } -} -'''); - Source source2 = addNamedSource('/test/test1.dart', r''' -import '../lib1.dart'; - -void main() { - new A().a(); -} -'''); - await computeAnalysisResult(source); - await computeAnalysisResult(source2); - assertNoErrors(source2); - verify([source, source2]); - } - test_isDouble() async { AnalysisOptionsImpl options = new AnalysisOptionsImpl(); options.dart2jsHint = true; @@ -1293,173 +235,6 @@ verify([source]); } - test_required_constructor_param() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -class C { - C({@Required('must specify an `a`') int a}) {} -} - -main() { - new C(); -} -'''); - await computeAnalysisResult(source); - assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]); - verify([source]); - } - - test_required_constructor_param_no_reason() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -class C { - C({@required int a}) {} -} - -main() { - new C(); -} -'''); - await computeAnalysisResult(source); - assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]); - verify([source]); - } - - test_required_constructor_param_null_reason() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -class C { - C({@Required(null) int a}) {} -} - -main() { - new C(); -} -'''); - await computeAnalysisResult(source); - assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]); - verify([source]); - } - - test_required_constructor_param_OK() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -class C { - C({@required int a}) {} -} - -main() { - new C(a: 2); -} -'''); - await computeAnalysisResult(source); - assertNoErrors(source); - verify([source]); - } - - test_required_constructor_param_redirecting_cons_call() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -class C { - C({@required int x}); - C.named() : this(); -} -'''); - await computeAnalysisResult(source); - assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]); - verify([source]); - } - - test_required_constructor_param_super_call() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -class C { - C({@Required('must specify an `a`') int a}) {} -} - -class D extends C { - D() : super(); -} -'''); - await computeAnalysisResult(source); - assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]); - verify([source]); - } - - test_required_function_param() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -void f({@Required('must specify an `a`') int a}) {} - -main() { - f(); -} -'''); - await computeAnalysisResult(source); - assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]); - verify([source]); - } - - test_required_method_param() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; -class A { - void m({@Required('must specify an `a`') int a}) {} -} -f() { - new A().m(); -} -'''); - await computeAnalysisResult(source); - assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]); - verify([source]); - } - - test_required_method_param_in_other_lib() async { - addNamedSource('/a_lib.dart', r''' -library a_lib; -import 'package:meta/meta.dart'; -class A { - void m({@Required('must specify an `a`') int a}) {} -} -'''); - - Source source = addSource(r''' -import "a_lib.dart"; -f() { - new A().m(); -} -'''); - - await computeAnalysisResult(source); - assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]); - verify([source]); - } - - test_required_typedef_function_param() async { - Source source = addSource(r''' -import 'package:meta/meta.dart'; - -String test(C c) => c.m()(); - -typedef String F({@required String x}); - -class C { - F m() => ({@required String x}) => null; -} -'''); - await computeAnalysisResult(source); - assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]); - verify([source]); - } - test_strongMode_downCastCompositeHint() async { AnalysisOptionsImpl options = new AnalysisOptionsImpl(); options.strongModeHints = true;
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart index 03d2693..24c5811 100644 --- a/pkg/analyzer/test/generated/non_hint_code_test.dart +++ b/pkg/analyzer/test/generated/non_hint_code_test.dart
@@ -2,7 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/error/error.dart'; import 'package:analyzer/src/error/codes.dart'; import 'package:analyzer/src/generated/source_io.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart index 1beed7e..738676c 100644 --- a/pkg/analyzer/test/generated/parser_fasta_test.dart +++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -878,6 +878,11 @@ //super.test_expectedStringLiteral(); } + void test_factory_issue_36400() { + parseCompilationUnit('class T { T factory T() { return null; } }', + errors: [expectedError(ParserErrorCode.TYPE_BEFORE_FACTORY, 10, 1)]); + } + void test_getterNativeWithBody() { createParser('String get m native "str" => 0;'); parser.parseClassMember('C') as MethodDeclaration;
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart index 1c63c45..36e49bc 100644 --- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart +++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -90,7 +90,11 @@ 'c', errorCodes: [CompileTimeErrorCode.INVALID_CONSTANT], ); - expect(result, isNull); + if (analysisOptions.experimentStatus.constant_update_2018) { + expect(result.toIntValue(), 1); + } else { + expect(result, isNull); + } } test_visitConditionalExpression_eager_true_invalid_int() async {
diff --git a/pkg/analyzer/test/src/dart/element/test_all.dart b/pkg/analyzer/test/src/dart/element/test_all.dart index 134b672..d51bf52 100644 --- a/pkg/analyzer/test/src/dart/element/test_all.dart +++ b/pkg/analyzer/test/src/dart/element/test_all.dart
@@ -7,6 +7,7 @@ import 'element_test.dart' as element; import 'function_type_test.dart' as function_type; import 'inheritance_manager2_test.dart' as inheritance_manager2; +import 'type_algebra_test.dart' as type_algebra; /// Utility for manually running all tests. main() { @@ -14,5 +15,6 @@ element.main(); function_type.main(); inheritance_manager2.main(); + type_algebra.main(); }, name: 'element'); }
diff --git a/pkg/analyzer/test/src/dart/element/type_algebra_test.dart b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart new file mode 100644 index 0000000..5aa1321 --- /dev/null +++ b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
@@ -0,0 +1,271 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/type.dart'; +import 'package:analyzer/src/dart/element/type.dart'; +import 'package:analyzer/src/dart/element/type_algebra.dart'; +import 'package:test/test.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import '../resolution/driver_resolution.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(SubstituteEmptyTest); + defineReflectiveTests(SubstituteFromInterfaceTypeTest); + defineReflectiveTests(SubstituteFromPairsTest); + defineReflectiveTests(SubstituteFromUpperAndLowerBoundsTest); + defineReflectiveTests(SubstituteTest); + }); +} + +@reflectiveTest +class SubstituteEmptyTest extends DriverResolutionTest { + test_interface() async { + addTestFile(r''' +class A<T> {} +'''); + await resolveTestFile(); + + var type = findElement.class_('A').type; + var result = Substitution.empty.substituteType(type); + expect(result, same(type)); + } +} + +@reflectiveTest +class SubstituteFromInterfaceTypeTest extends _Base { + test_interface() async { + addTestFile(r''' +class A<T> {} +class B<U> extends A<U> {} +'''); + await resolveTestFile(); + + var a = findElement.class_('A'); + var b = findElement.class_('B'); + var u = b.typeParameters.single; + + var bType = _instantiate(b, [intType]); + var substitution = Substitution.fromInterfaceType(bType); + + // `extends A<U>` + var type = _instantiate(a, [u.type]); + assertElementTypeString(type, 'A<U>'); + + var result = substitution.substituteType(type); + assertElementTypeString(result, 'A<int>'); + } +} + +@reflectiveTest +class SubstituteFromPairsTest extends DriverResolutionTest { + test_interface() async { + addTestFile(r''' +class A<T, U> {} +'''); + await resolveTestFile(); + + var a = findElement.class_('A'); + var result = Substitution.fromPairs( + a.typeParameters, + [intType, doubleType], + ).substituteType(a.type); + assertElementTypeString(result, 'A<int, double>'); + } +} + +@reflectiveTest +class SubstituteFromUpperAndLowerBoundsTest extends DriverResolutionTest { + test_function() async { + addTestFile(r''' +typedef F<T> = T Function(T); +'''); + await resolveTestFile(); + + var type = findElement.genericTypeAlias('F').function.type; + var t = findElement.typeParameter('T'); + + var result = Substitution.fromUpperAndLowerBounds( + {t: intType}, + {t: BottomTypeImpl.instance}, + ).substituteType(type); + assertElementTypeString(result, '(<bottom>) → int'); + } +} + +@reflectiveTest +class SubstituteTest extends _Base { + test_bottom() async { + addTestFile(r''' +class A<T> {} +'''); + await resolveTestFile(); + + var t = findElement.typeParameter('T'); + _assertIdenticalType(typeProvider.bottomType, {t: intType}); + } + + test_dynamic() async { + addTestFile(r''' +class A<T> {} +'''); + await resolveTestFile(); + + var t = findElement.typeParameter('T'); + _assertIdenticalType(typeProvider.dynamicType, {t: intType}); + } + + test_function_noTypeParameters() async { + addTestFile(r''' +typedef F = bool Function(int); +class B<T> {} +'''); + await resolveTestFile(); + + var type = findElement.genericTypeAlias('F').function.type; + var t = findElement.typeParameter('T'); + _assertIdenticalType(type, {t: intType}); + } + + test_function_typeFormals() async { + addTestFile(r''' +typedef F<T> = T Function<U extends T>(U); +'''); + await resolveTestFile(); + + var type = findElement.genericTypeAlias('F').function.type; + var t = findElement.typeParameter('T'); + assertElementTypeString(type, '<U extends T>(U) → T'); + _assertSubstitution( + type, + {t: intType}, + '<U extends int>(U) → int', + ); + } + + test_function_typeParameters() async { + addTestFile(r''' +typedef F<T, U> = T Function(U u, bool); +'''); + await resolveTestFile(); + + var type = findElement.genericTypeAlias('F').function.type; + var t = findElement.typeParameter('T'); + var u = findElement.typeParameter('U'); + assertElementTypeString(type, '(U, bool) → T'); + _assertSubstitution( + type, + {t: intType}, + '(U, bool) → int', + ); + _assertSubstitution( + type, + {t: intType, u: doubleType}, + '(double, bool) → int', + ); + } + + test_interface_arguments() async { + addTestFile(r''' +class A<T> {} +class B<U> {} +'''); + await resolveTestFile(); + + var a = findElement.class_('A'); + var u = findElement.typeParameter('U'); + var uType = new TypeParameterTypeImpl(u); + + var type = _instantiate(a, [uType]); + assertElementTypeString(type, 'A<U>'); + _assertSubstitution(type, {u: intType}, 'A<int>'); + } + + test_interface_arguments_deep() async { + addTestFile(r''' +class A<T> {} +class B<U> {} +'''); + await resolveTestFile(); + + var a = findElement.class_('A'); + var u = findElement.typeParameter('U'); + var uType = new TypeParameterTypeImpl(u); + + var type = _instantiate(a, [ + _instantiate(listElement, [uType]) + ]); + assertElementTypeString(type, 'A<List<U>>'); + _assertSubstitution(type, {u: intType}, 'A<List<int>>'); + } + + test_interface_noArguments() async { + addTestFile(r''' +class A {} +class B<T> {} +'''); + await resolveTestFile(); + + var a = findElement.class_('A'); + var t = findElement.typeParameter('T'); + _assertIdenticalType(a.type, {t: intType}); + } + + test_interface_noArguments_inArguments() async { + addTestFile(r''' +class A<T> {} +class B<U> {} +'''); + await resolveTestFile(); + + var a = findElement.class_('A'); + var u = findElement.typeParameter('U'); + _assertIdenticalType( + _instantiate(a, [intType]), + {u: doubleType}, + ); + } + + test_void() async { + addTestFile(r''' +class A<T> {} +'''); + await resolveTestFile(); + + var t = findElement.typeParameter('T'); + _assertIdenticalType(voidType, {t: intType}); + } + + test_void_emptyMap() async { + addTestFile(''); + await resolveTestFile(); + _assertIdenticalType(voidType, {}); + } + + void _assertIdenticalType( + DartType type, Map<TypeParameterElement, DartType> substitution) { + var result = substitute(type, substitution); + expect(result, same(type)); + } + + void _assertSubstitution( + DartType type, + Map<TypeParameterElement, DartType> substitution, + String expected, + ) { + var result = substitute(type, substitution); + assertElementTypeString(result, expected); + } +} + +class _Base extends DriverResolutionTest { + /// Intentionally low-level implementation for creating [InterfaceType] + /// for [ClassElement] and type arguments. We just create it explicitly, + /// without using `InterfaceType.instantiate()`. + InterfaceType _instantiate(ClassElement element, List<DartType> arguments) { + return new InterfaceTypeImpl(element)..typeArguments = arguments; + } +}
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart index 08971b0..262e9cf 100644 --- a/pkg/analyzer/test/src/dart/resolution/resolution.dart +++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -42,6 +42,10 @@ Element get dynamicElement => typeProvider.dynamicType.element; + bool get enableUnusedElement => false; + + bool get enableUnusedLocalVariable => false; + ClassElement get intElement => typeProvider.intType.element; InterfaceType get intType => typeProvider.intType; @@ -62,6 +66,8 @@ /// Whether `DartType.toString()` with nullability should be asked. bool get typeToStringWithNullability => false; + VoidType get voidType => VoidTypeImpl.instance; + void addTestFile(String content) { newFile('/test/lib/test.dart', content: content); } @@ -144,10 +150,6 @@ expect(element.enclosingElement, expectedEnclosing); } - bool get enableUnusedLocalVariable => false; - - bool get enableUnusedElement => false; - /** * Assert that the number of error codes in reported [errors] matches the * number of [expected] error codes. The order of errors is ignored.
diff --git a/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart b/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart index 8c52012..47b2dd1 100644 --- a/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart +++ b/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart
@@ -13,6 +13,7 @@ main() { defineReflectiveSuite(() { defineReflectiveTests(ConstEvalThrowsExceptionTest); + defineReflectiveTests(ConstEvalThrowsExceptionWithConstantUpdateTest); defineReflectiveTests(ConstEvalThrowsExceptionWithUIAsCodeTest); }); } @@ -131,6 +132,26 @@ } @reflectiveTest +class ConstEvalThrowsExceptionWithConstantUpdateTest + extends ConstEvalThrowsExceptionTest { + @override + AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl() + ..enabledExperiments = [ + EnableString.constant_update_2018, + ]; + + test_eqEq_nonPrimitiveRightOperand() async { + await assertNoErrorsInCode(''' +const c = const T.eq(1, const Object()); +class T { + final Object value; + const T.eq(Object o1, Object o2) : value = o1 == o2; +} +'''); + } +} + +@reflectiveTest class ConstEvalThrowsExceptionWithUIAsCodeTest extends ConstEvalThrowsExceptionTest { @override
diff --git a/pkg/analyzer/test/src/diagnostics/dead_code_test.dart b/pkg/analyzer/test/src/diagnostics/dead_code_test.dart index 48ccc75..f2f92f9 100644 --- a/pkg/analyzer/test/src/diagnostics/dead_code_test.dart +++ b/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
@@ -19,6 +19,52 @@ @reflectiveTest class DeadCodeTest extends DriverResolutionTest with PackageMixin { + test_afterForEachWithBreakLabel() async { + await assertNoErrorsInCode(r''' +f() { + named: { + for (var x in [1]) { + if (x == null) + break named; + } + return; + } + print('not dead'); +} +'''); + } + + test_afterForWithBreakLabel() async { + await assertNoErrorsInCode(r''' +f() { + named: { + for (int i = 0; i < 7; i++) { + if (i == null) + break named; + } + return; + } + print('not dead'); +} +'''); + } + + test_afterTryCatch() async { + await assertNoErrorsInCode(r''' +main() { + try { + return f(); + } catch (e) { + print(e); + } + print('not dead'); +} +f() { + throw 'foo'; +} +'''); + } + test_deadBlock_conditionalElse() async { await assertErrorsInCode(r''' f() { @@ -26,6 +72,14 @@ }''', [HintCode.DEAD_CODE]); } + test_deadBlock_conditionalElse_debugConst() async { + await assertNoErrorsInCode(r''' +const bool DEBUG = true; +f() { + DEBUG ? 1 : 2; +}'''); + } + test_deadBlock_conditionalElse_nested() async { // Test that a dead else-statement can't generate additional violations. await assertErrorsInCode(r''' @@ -41,22 +95,6 @@ }''', [HintCode.DEAD_CODE]); } - test_deadBlock_conditionalIf_nested() async { - // Test that a dead then-statement can't generate additional violations. - await assertErrorsInCode(r''' -f() { - false ? false && false : true; -}''', [HintCode.DEAD_CODE]); - } - - test_deadBlock_conditionalElse_debugConst() async { - await assertNoErrorsInCode(r''' -const bool DEBUG = true; -f() { - DEBUG ? 1 : 2; -}'''); - } - test_deadBlock_conditionalIf_debugConst() async { await assertNoErrorsInCode(r''' const bool DEBUG = false; @@ -65,6 +103,14 @@ }'''); } + test_deadBlock_conditionalIf_nested() async { + // Test that a dead then-statement can't generate additional violations. + await assertErrorsInCode(r''' +f() { + false ? false && false : true; +}''', [HintCode.DEAD_CODE]); + } + test_deadBlock_else() async { await assertErrorsInCode(r''' f() { @@ -80,6 +126,21 @@ }'''); } + test_deadBlock_else_nested() async { + // Test that a dead else-statement can't generate additional violations. + await assertErrorsInCode(r''' +f() { + if(true) {} else {if (false) {}} +}''', [HintCode.DEAD_CODE]); + } + + test_deadBlock_if() async { + await assertErrorsInCode(r''' +f() { + if(false) {} +}''', [HintCode.DEAD_CODE]); + } + test_deadBlock_if_debugConst_prefixedIdentifier() async { await assertNoErrorsInCode(r''' class A { @@ -126,21 +187,6 @@ }'''); } - test_deadBlock_else_nested() async { - // Test that a dead else-statement can't generate additional violations. - await assertErrorsInCode(r''' -f() { - if(true) {} else {if (false) {}} -}''', [HintCode.DEAD_CODE]); - } - - test_deadBlock_if() async { - await assertErrorsInCode(r''' -f() { - if(false) {} -}''', [HintCode.DEAD_CODE]); - } - test_deadBlock_if_nested() async { // Test that a dead then-statement can't generate additional violations. await assertErrorsInCode(r''' @@ -156,14 +202,6 @@ }''', [HintCode.DEAD_CODE]); } - test_deadBlock_while_nested() async { - // Test that a dead while body can't generate additional violations. - await assertErrorsInCode(r''' -f() { - while(false) {if(false) {}} -}''', [HintCode.DEAD_CODE]); - } - test_deadBlock_while_debugConst() async { await assertNoErrorsInCode(r''' const bool DEBUG = false; @@ -172,6 +210,14 @@ }'''); } + test_deadBlock_while_nested() async { + // Test that a dead while body can't generate additional violations. + await assertErrorsInCode(r''' +f() { + while(false) {if(false) {}} +}''', [HintCode.DEAD_CODE]); + } + test_deadCatch_catchFollowingCatch() async { await assertErrorsInCode(r''' class A {} @@ -232,20 +278,21 @@ }'''); } - test_afterTryCatch() async { + test_deadFinalBreakInCase() async { await assertNoErrorsInCode(r''' -main() { - try { - return f(); - } catch (e) { - print(e); - } - print('not dead'); -} f() { - throw 'foo'; -} -'''); + switch (true) { + case true: + try { + int a = 1; + } finally { + return; + } + break; + default: + break; + } +}'''); } test_deadFinalReturnInCase() async { @@ -282,23 +329,6 @@ }''', [HintCode.DEAD_CODE]); } - test_deadFinalBreakInCase() async { - await assertNoErrorsInCode(r''' -f() { - switch (true) { - case true: - try { - int a = 1; - } finally { - return; - } - break; - default: - break; - } -}'''); - } - test_deadOperandLHS_and() async { await assertErrorsInCode(r''' f() { @@ -306,6 +336,14 @@ }''', [HintCode.DEAD_CODE]); } + test_deadOperandLHS_and_debugConst() async { + await assertNoErrorsInCode(r''' +const bool DEBUG = false; +f() { + bool b = DEBUG && false; +}'''); + } + test_deadOperandLHS_and_nested() async { await assertErrorsInCode(r''' f() { @@ -320,21 +358,6 @@ }''', [HintCode.DEAD_CODE]); } - test_deadOperandLHS_or_nested() async { - await assertErrorsInCode(r''' -f() { - bool b = true || (false && false); -}''', [HintCode.DEAD_CODE]); - } - - test_deadOperandLHS_and_debugConst() async { - await assertNoErrorsInCode(r''' -const bool DEBUG = false; -f() { - bool b = DEBUG && false; -}'''); - } - test_deadOperandLHS_or_debugConst() async { await assertNoErrorsInCode(r''' const bool DEBUG = true; @@ -343,6 +366,13 @@ }'''); } + test_deadOperandLHS_or_nested() async { + await assertErrorsInCode(r''' +f() { + bool b = true || (false && false); +}''', [HintCode.DEAD_CODE]); + } + test_statementAfterAlwaysThrowsFunction() async { addMetaPackage(); await assertErrorsInCode(r''' @@ -576,36 +606,6 @@ var two = 2; }''', [HintCode.DEAD_CODE]); } - - test_afterForEachWithBreakLabel() async { - await assertNoErrorsInCode(r''' -f() { - named: { - for (var x in [1]) { - if (x == null) - break named; - } - return; - } - print('not dead'); -} -'''); - } - - test_afterForWithBreakLabel() async { - await assertNoErrorsInCode(r''' -f() { - named: { - for (int i = 0; i < 7; i++) { - if (i == null) - break named; - } - return; - } - print('not dead'); -} -'''); - } } @reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/duplicate_import_test.dart b/pkg/analyzer/test/src/diagnostics/duplicate_import_test.dart index 237cf68..428e9b2 100644 --- a/pkg/analyzer/test/src/diagnostics/duplicate_import_test.dart +++ b/pkg/analyzer/test/src/diagnostics/duplicate_import_test.dart
@@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/error/codes.dart'; -import 'package:analyzer/src/test_utilities/package_mixin.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/driver_resolution.dart'; @@ -32,22 +31,6 @@ assertTestErrors([HintCode.DUPLICATE_IMPORT]); } - test_twoDuplicateImports() async { - newFile('/lib2.dart', content: r''' -library L; -import 'lib1.dart'; -import 'lib1.dart'; -import 'lib1.dart'; -A a;'''); - newFile('/lib1.dart', content: r''' -library lib1; -class A {}'''); - - await _resolveTestFile('/lib1.dart'); - await _resolveTestFile('/lib2.dart'); - assertTestErrors([HintCode.DUPLICATE_IMPORT, HintCode.DUPLICATE_IMPORT]); - } - test_importsHaveIdenticalShowHide() async { newFile('/lib2.dart', content: r''' library L; @@ -65,23 +48,6 @@ assertTestErrors([HintCode.DUPLICATE_IMPORT]); } - test_oneImportUsesAs() async { - newFile('/lib2.dart', content: r''' -library L; -import 'lib1.dart'; -import 'lib1.dart' as one; -A a; -one.A a2;'''); - - newFile('/lib1.dart', content: r''' -library lib1; -class A {}'''); - - await _resolveTestFile('/lib1.dart'); - await _resolveTestFile('/lib2.dart'); - assertNoTestErrors(); - } - test_oneImportHasHide() async { newFile('/lib2.dart', content: r''' library L; @@ -118,6 +84,39 @@ assertNoTestErrors(); } + test_oneImportUsesAs() async { + newFile('/lib2.dart', content: r''' +library L; +import 'lib1.dart'; +import 'lib1.dart' as one; +A a; +one.A a2;'''); + + newFile('/lib1.dart', content: r''' +library lib1; +class A {}'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertNoTestErrors(); + } + + test_twoDuplicateImports() async { + newFile('/lib2.dart', content: r''' +library L; +import 'lib1.dart'; +import 'lib1.dart'; +import 'lib1.dart'; +A a;'''); + newFile('/lib1.dart', content: r''' +library lib1; +class A {}'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertTestErrors([HintCode.DUPLICATE_IMPORT, HintCode.DUPLICATE_IMPORT]); + } + /// Resolve the test file at [path]. /// /// Similar to ResolutionTest.resolveTestFile, but a custom path is supported.
diff --git a/pkg/analyzer/test/src/diagnostics/import_deferred_library_with_load_function_test.dart b/pkg/analyzer/test/src/diagnostics/import_deferred_library_with_load_function_test.dart index 0500bcc..93e6065 100644 --- a/pkg/analyzer/test/src/diagnostics/import_deferred_library_with_load_function_test.dart +++ b/pkg/analyzer/test/src/diagnostics/import_deferred_library_with_load_function_test.dart
@@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/error/codes.dart'; -import 'package:analyzer/src/test_utilities/package_mixin.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/driver_resolution.dart'; @@ -32,6 +31,21 @@ assertTestErrors([HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION]); } + test_deferredImport_withoutLoadLibraryFunction() async { + newFile('/pkg1/lib/lib1.dart', content: r''' +library lib1; +f() {}'''); + + newFile('/pkg1/lib/lib2.dart', content: r''' +library root; +import 'lib1.dart' deferred as lib1; +main() { lib1.f(); }'''); + + await _resolveTestFile('/pkg1/lib/lib1.dart'); + await _resolveTestFile('/pkg1/lib/lib2.dart'); + assertNoTestErrors(); + } + test_nonDeferredImport_withLoadLibraryFunction() async { newFile('/pkg1/lib/lib1.dart', content: r''' library lib1; @@ -48,21 +62,6 @@ assertNoTestErrors(); } - test_deferredImport_withoutLoadLibraryFunction() async { - newFile('/pkg1/lib/lib1.dart', content: r''' -library lib1; -f() {}'''); - - newFile('/pkg1/lib/lib2.dart', content: r''' -library root; -import 'lib1.dart' deferred as lib1; -main() { lib1.f(); }'''); - - await _resolveTestFile('/pkg1/lib/lib1.dart'); - await _resolveTestFile('/pkg1/lib/lib2.dart'); - assertNoTestErrors(); - } - /// Resolve the test file at [path]. /// /// Similar to ResolutionTest.resolveTestFile, but a custom path is supported.
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_factory_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_factory_annotation_test.dart new file mode 100644 index 0000000..fc57260 --- /dev/null +++ b/pkg/analyzer/test/src/diagnostics/invalid_factory_annotation_test.dart
@@ -0,0 +1,49 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/src/error/codes.dart'; +import 'package:analyzer/src/test_utilities/package_mixin.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import '../dart/resolution/driver_resolution.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(InvalidFactoryAnnotationTest); + }); +} + +@reflectiveTest +class InvalidFactoryAnnotationTest extends DriverResolutionTest + with PackageMixin { + test_class() async { + addMetaPackage(); + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; +@factory +class X { +} +''', [HintCode.INVALID_FACTORY_ANNOTATION]); + } + + test_field() async { + addMetaPackage(); + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; +class X { + @factory + int x; +} +''', [HintCode.INVALID_FACTORY_ANNOTATION]); + } + + test_topLevelFunction() async { + addMetaPackage(); + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; +@factory +main() { } +''', [HintCode.INVALID_FACTORY_ANNOTATION]); + } +}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_factory_method_impl_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_factory_method_impl_test.dart new file mode 100644 index 0000000..8ba3959 --- /dev/null +++ b/pkg/analyzer/test/src/diagnostics/invalid_factory_method_impl_test.dart
@@ -0,0 +1,143 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/src/error/codes.dart'; +import 'package:analyzer/src/test_utilities/package_mixin.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import '../dart/resolution/driver_resolution.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(InvalidFactoryMethodImplTest); + }); +} + +@reflectiveTest +class InvalidFactoryMethodImplTest extends DriverResolutionTest + with PackageMixin { + test_abstract() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +abstract class Stateful { + @factory + State createState(); +} +class State { } +'''); + } + + test_badReturn() async { + addMetaPackage(); + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; +class Stateful { + State _s = new State(); + + @factory + State createState() => _s; +} +class State { } +''', [HintCode.INVALID_FACTORY_METHOD_IMPL]); + } + + test_block() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class Stateful { + @factory + State createState() { + return new State(); + } +} +class State { } +'''); + } + + test_block_returnNull() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class Stateful { + @factory + State createState() { + return null; + } +} +class State { } +'''); + } + + test_expr() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class Stateful { + @factory + State createState() => new State(); +} +class State { } +'''); + } + + test_expr_returnNull() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class Stateful { + @factory + State createState() => null; +} +class State { } +'''); + } + + test_noReturnType() async { + addMetaPackage(); + // Null return types will get flagged elsewhere, no need to pile on here. + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class Stateful { + @factory + createState() { + return new Stateful(); + } +} +'''); + } + + test_subclass() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +abstract class Stateful { + @factory + State createState(); +} +class MyThing extends Stateful { + @override + State createState() { + print('my state'); + return new MyState(); + } +} +class State { } +class MyState extends State { } +'''); + } + + test_voidReturn() async { + addMetaPackage(); + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; + +class Stateful { + @factory + void createState() {} +} +''', [HintCode.INVALID_FACTORY_METHOD_DECL]); + } +}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_immutable_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_immutable_annotation_test.dart index 8b6e57f..85ee340e 100644 --- a/pkg/analyzer/test/src/diagnostics/invalid_immutable_annotation_test.dart +++ b/pkg/analyzer/test/src/diagnostics/invalid_immutable_annotation_test.dart
@@ -17,17 +17,6 @@ @reflectiveTest class InvalidImmutableAnnotationTest extends DriverResolutionTest with PackageMixin { - test_method() async { - addMetaPackage(); - await assertErrorsInCode(r''' -import 'package:meta/meta.dart'; -class A { - @immutable - void m() {} -} -''', [HintCode.INVALID_IMMUTABLE_ANNOTATION]); - } - test_class() async { addMetaPackage(); await assertNoErrorsInCode(r''' @@ -38,4 +27,15 @@ } '''); } + + test_method() async { + addMetaPackage(); + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @immutable + void m() {} +} +''', [HintCode.INVALID_IMMUTABLE_ANNOTATION]); + } }
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_literal_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_literal_annotation_test.dart index 9751a2b..c9a88ca 100644 --- a/pkg/analyzer/test/src/diagnostics/invalid_literal_annotation_test.dart +++ b/pkg/analyzer/test/src/diagnostics/invalid_literal_annotation_test.dart
@@ -17,6 +17,17 @@ @reflectiveTest class InvalidLiteralAnnotationTest extends DriverResolutionTest with PackageMixin { + test_constConstructor() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @literal + const A(); +} +'''); + } + test_nonConstConstructor() async { addMetaPackage(); await assertErrorsInCode(r''' @@ -38,15 +49,4 @@ } ''', [HintCode.INVALID_LITERAL_ANNOTATION]); } - - test_constConstructor() async { - addMetaPackage(); - await assertNoErrorsInCode(r''' -import 'package:meta/meta.dart'; -class A { - @literal - const A(); -} -'''); - } }
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_use_of_protected_member_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_use_of_protected_member_test.dart new file mode 100644 index 0000000..81c2a4c --- /dev/null +++ b/pkg/analyzer/test/src/diagnostics/invalid_use_of_protected_member_test.dart
@@ -0,0 +1,427 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/src/error/codes.dart'; +import 'package:analyzer/src/test_utilities/package_mixin.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import '../dart/resolution/driver_resolution.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(InvalidUseOfProtectedMemberTest); + }); +} + +@reflectiveTest +class InvalidUseOfProtectedMemberTest extends DriverResolutionTest + with PackageMixin { + test_closure() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; + +class A { + @protected + int a() => 42; +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; + +void main() { + var leak = new A().a; + print(leak); +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); + } + + test_extendingSubclass() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @protected + void a(){ } +} +class B extends A { + void b() => a(); +}'''); + } + + test_field() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @protected + int a = 42; +} +class B extends A { + int b() => a; +} +'''); + } + + test_field_outsideClassAndLibrary() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; +class A { + @protected + int a; +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; +abstract class B { + int b() => new A().a; +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); + } + + test_field_subclassAndSameLibrary() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @protected + int a; +} +abstract class B implements A { + int b() => a; +}'''); + } + + test_fromSuperclassConstraint() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; +abstract class A { + @protected + void foo() {} +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; +mixin M on A { + @override + void foo() { + super.foo(); + } +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertNoTestErrors(); + } + + test_function_outsideClassAndLibrary() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; +class A { + @protected + void a(){ } +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; + +main() { + new A().a(); +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); + } + + test_function_sameLibrary() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @protected + void a(){ } +} +main() { + new A().a(); +}'''); + } + + test_function_subclass() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @protected + int a() => 0; +} + +abstract class B implements A { + int b() => a(); +}'''); + } + + test_getter() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @protected + int get a => 42; +} +class B extends A { + int b() => a; +} +'''); + } + + test_getter_outsideClassAndLibrary() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; +class A { + @protected + int get a => 42; +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; +class B { + A a; + int b() => a.a; +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); + } + + test_getter_subclass() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @protected + int get a => 42; +} +abstract class B implements A { + int b() => a; +}'''); + } + + test_inDocs() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; + +class A { + @protected + int c = 0; + + @protected + int get b => 0; + + @protected + int a() => 0; +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; +/// OK: [A.a], [A.b], [A.c]. +f() {} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertNoTestErrors(); + } + + test_method_outsideClassAndLibrary() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; +class A { + @protected + void a() {} +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; + +class B { + void b() => new A().a(); +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); + } + + test_method_subclass() async { + // https://github.com/dart-lang/linter/issues/257 + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; + +typedef void VoidCallback(); + +class State<E> { + @protected + void setState(VoidCallback fn) {} +} + +class Button extends State<Object> { + void handleSomething() { + setState(() {}); + } +} +'''); + } + + test_mixingIn() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @protected + void a(){ } +} +class B extends Object with A { + void b() => a(); +}'''); + } + + test_mixingIn_asParameter() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @protected m1() {} +} +class B extends A { + static m2(A a) => a.m1(); +}'''); + } + + test_sameLibrary() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @protected + void a(){ } +} +class B extends A { + void a() => a(); +} +main() { + new B().a(); +}'''); + } + + test_setter_outsideClassAndFile() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; +class A { + @protected + void set a(int i) { } +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; +class B { + A a; + b(int i) { + a.a = i; + } +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]); + } + + test_setter_sameClass() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + int _a; + @protected + void set a(int a) { _a = a; } + A(int a) { + this.a = a; + } +} +'''); + } + + test_setter_subclass() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @protected + void set a(int i) { } +} +class B extends A { + void b(int i) { + a = i; + } +} +'''); + } + + test_setter_subclassImplementing() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @protected + void set a(int i) { } +} +abstract class B implements A { + b(int i) { + a = i; + } +}'''); + } + + test_topLevelVariable() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +@protected +int x = 0; +main() { + print(x); +}'''); + // TODO(brianwilkerson) This should produce a hint because the + // annotation is being applied to the wrong kind of declaration. + } + + /// Resolve the test file at [path]. + /// + /// Similar to ResolutionTest.resolveTestFile, but a custom path is supported. + Future<void> _resolveTestFile(String path) async { + result = await resolveFile(convertPath(path)); + } +}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_template_member_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_template_member_test.dart new file mode 100644 index 0000000..71dde80 --- /dev/null +++ b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_template_member_test.dart
@@ -0,0 +1,226 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/file_system/file_system.dart'; +import 'package:analyzer/src/error/codes.dart'; +import 'package:analyzer/src/test_utilities/package_mixin.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import '../dart/resolution/driver_resolution.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(InvalidUseOfVisibleForTemplateMemberTest); + }); +} + +@reflectiveTest +class InvalidUseOfVisibleForTemplateMemberTest extends DriverResolutionTest + with PackageMixin { + void addAngularMetaPackage() { + Folder lib = addPubPackage('angular_meta'); + newFile(join(lib.path, 'angular_meta.dart'), content: r''' +library angular.meta; + +const _VisibleForTemplate visibleForTemplate = const _VisibleForTemplate(); + +class _VisibleForTemplate { + const _VisibleForTemplate(); +} +'''); + } + + test_constructor() async { + addAngularMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:angular_meta/angular_meta.dart'; +class A { + int _x; + + @visibleForTemplate + A.forTemplate(this._x); +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; + +void main() { + new A.forTemplate(0); +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]); + } + + test_export() async { + addAngularMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:angular_meta/angular_meta.dart'; + +@visibleForTemplate +int fn0() => 1; +'''); + newFile('/lib2.dart', content: r''' +export 'lib1.dart' show fn0; +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertNoTestErrors(); + } + + test_method() async { + addAngularMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:angular_meta/angular_meta.dart'; +class A { + @visibleForTemplate + void a(){ } +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; + +class B { + void b() => new A().a(); +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]); + } + + test_method_fromTemplate() async { + addAngularMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:angular_meta/angular_meta.dart'; +class A { + @visibleForTemplate + void a(){ } +} +'''); + addAngularMetaPackage(); + newFile('/lib1.template.dart', content: r''' +import 'lib1.dart'; + +class B { + void b() => new A().a(); +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib1.template.dart'); + assertNoTestErrors(); + } + + test_propertyAccess() async { + addAngularMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:angular_meta/angular_meta.dart'; +class A { + @visibleForTemplate + int get a => 7; + + @visibleForTemplate + set b(_) => 7; +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; + +void main() { + new A().a; + new A().b = 6; +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertTestErrors([ + HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER, + HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER + ]); + } + + test_protectedAndForTemplate_usedAsProtected() async { + addAngularMetaPackage(); + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:angular_meta/angular_meta.dart'; +import 'package:meta/meta.dart'; +class A { + @protected + @visibleForTemplate + void a(){ } +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; +class B extends A { + void b() => new A().a(); +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertNoTestErrors(); + } + + test_protectedAndForTemplate_usedAsTemplate() async { + addAngularMetaPackage(); + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:angular_meta/angular_meta.dart'; +import 'package:meta/meta.dart'; +class A { + @protected + @visibleForTemplate + void a(){ } +} +'''); + addAngularMetaPackage(); + addMetaPackage(); + newFile('/lib1.template.dart', content: r''' +import 'lib1.dart'; +void main() { + new A().a(); +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib1.template.dart'); + assertNoTestErrors(); + } + + test_topLevelFunction() async { + addAngularMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:angular_meta/angular_meta.dart'; + +@visibleForTemplate +int fn0() => 1; +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; + +void main() { + fn0(); +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]); + } + + /// Resolve the test file at [path]. + /// + /// Similar to ResolutionTest.resolveTestFile, but a custom path is supported. + Future<void> _resolveTestFile(String path) async { + result = await resolveFile(convertPath(path)); + } +}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart new file mode 100644 index 0000000..5090d0d --- /dev/null +++ b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart
@@ -0,0 +1,234 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/src/error/codes.dart'; +import 'package:analyzer/src/test_utilities/package_mixin.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import '../dart/resolution/driver_resolution.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(InvalidUseOfVisibleForTestingMemberTest); + }); +} + +@reflectiveTest +class InvalidUseOfVisibleForTestingMemberTest extends DriverResolutionTest + with PackageMixin { + test_constructor() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; +class A { + int _x; + + @visibleForTesting + A.forTesting(this._x); +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; +void main() { + new A.forTesting(0); +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]); + } + + test_export() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; +@visibleForTesting +int fn0() => 1; +'''); + newFile('/lib2.dart', content: r''' +export 'lib1.dart' show fn0; +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertNoTestErrors(); + } + + test_fromTestDirectory() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; +class A { + @visibleForTesting + void a(){ } +} +'''); + newFile('/test/test.dart', content: r''' +import '../lib1.dart'; +class B { + void b() => new A().a(); +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/test/test.dart'); + assertNoTestErrors(); + } + + test_fromTestingDirectory() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; +class A { + @visibleForTesting + void a(){ } +} +'''); + newFile('/testing/lib1.dart', content: r''' +import '../lib1.dart'; +class C { + void b() => new A().a(); +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/testing/lib1.dart'); + assertNoTestErrors(); + } + + test_getter() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; +class A { + @visibleForTesting + int get a => 7; +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; +void main() { + new A().a; +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]); + } + + test_method() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; +class A { + @visibleForTesting + void a(){ } +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; +class B { + void b() => new A().a(); +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]); + } + + test_protectedAndForTesting_usedAsProtected() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; +class A { + @protected + @visibleForTesting + void a(){ } +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; +class B extends A { + void b() => new A().a(); +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertNoTestErrors(); + } + + test_protectedAndForTesting_usedAsTesting() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; +class A { + @protected + @visibleForTesting + void a(){ } +} +'''); + addMetaPackage(); + newFile('/test/test1.dart', content: r''' +import '../lib1.dart'; +void main() { + new A().a(); +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/test/test1.dart'); + assertNoTestErrors(); + } + + test_setter() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; +class A { + @visibleForTesting + set b(_) => 7; +} +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; +void main() { + new A().b = 6; +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]); + } + + test_topLevelFunction() async { + addMetaPackage(); + newFile('/lib1.dart', content: r''' +import 'package:meta/meta.dart'; +@visibleForTesting +int fn0() => 1; +'''); + newFile('/lib2.dart', content: r''' +import 'lib1.dart'; +void main() { + fn0(); +} +'''); + + await _resolveTestFile('/lib1.dart'); + await _resolveTestFile('/lib2.dart'); + assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]); + } + + /// Resolve the test file at [path]. + /// + /// Similar to ResolutionTest.resolveTestFile, but a custom path is supported. + Future<void> _resolveTestFile(String path) async { + result = await resolveFile(convertPath(path)); + } +}
diff --git a/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart b/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart new file mode 100644 index 0000000..d73c1e7 --- /dev/null +++ b/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart
@@ -0,0 +1,171 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/src/error/codes.dart'; +import 'package:analyzer/src/test_utilities/package_mixin.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import '../dart/resolution/driver_resolution.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(MissingRequiredParamTest); + }); +} + +@reflectiveTest +class MissingRequiredParamTest extends DriverResolutionTest with PackageMixin { + test_constructorParam_argumentGiven() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; + +class C { + C({@required int a}) {} +} + +main() { + new C(a: 2); +} +'''); + } + + test_constructorParam_missingArgument() async { + addMetaPackage(); + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; +class C { + C({@Required('must specify an `a`') int a}) {} +} +main() { + new C(); +} +''', [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]); + } + + test_constructorParam_noReason() async { + addMetaPackage(); + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; + +class C { + C({@required int a}) {} +} + +main() { + new C(); +} +''', [HintCode.MISSING_REQUIRED_PARAM]); + } + + test_constructorParam_nullReason() async { + addMetaPackage(); + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; + +class C { + C({@Required(null) int a}) {} +} + +main() { + new C(); +} +''', [HintCode.MISSING_REQUIRED_PARAM]); + } + + test_constructorParam_redirectingConstructorCall() async { + addMetaPackage(); + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; +class C { + C({@required int x}); + C.named() : this(); +} +''', [HintCode.MISSING_REQUIRED_PARAM]); + } + + test_functionParam() async { + addMetaPackage(); + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; + +void f({@Required('must specify an `a`') int a}) {} + +main() { + f(); +} +''', [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]); + } + + test_methodParam() async { + addMetaPackage(); + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + void m({@Required('must specify an `a`') int a}) {} +} +f() { + new A().m(); +} +''', [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]); + } + + test_methodParam_inOtherLib() async { + addMetaPackage(); + newFile('/a_lib.dart', content: r''' +library a_lib; +import 'package:meta/meta.dart'; +class A { + void m({@Required('must specify an `a`') int a}) {} +} +'''); + newFile('/test.dart', content: r''' +import "a_lib.dart"; +f() { + new A().m(); +} +'''); + + await _resolveTestFile('/a_lib.dart'); + await _resolveTestFile('/test.dart'); + assertTestErrors([HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]); + } + + test_requiredConstructor_paramSuperCall() async { + addMetaPackage(); + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; + +class C { + C({@Required('must specify an `a`') int a}) {} +} + +class D extends C { + D() : super(); +} +''', [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]); + } + + test_typedef_functionParam() async { + addMetaPackage(); + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; + +String test(C c) => c.m()(); + +typedef String F({@required String x}); + +class C { + F m() => ({@required String x}) => null; +} +''', [HintCode.MISSING_REQUIRED_PARAM]); + } + + /// Resolve the test file at [path]. + /// + /// Similar to ResolutionTest.resolveTestFile, but a custom path is supported. + Future<void> _resolveTestFile(String path) async { + result = await resolveFile(convertPath(path)); + } +}
diff --git a/pkg/analyzer/test/src/diagnostics/missing_return_test.dart b/pkg/analyzer/test/src/diagnostics/missing_return_test.dart index 5b03a7c..a83bb3a 100644 --- a/pkg/analyzer/test/src/diagnostics/missing_return_test.dart +++ b/pkg/analyzer/test/src/diagnostics/missing_return_test.dart
@@ -16,6 +16,21 @@ @reflectiveTest class MissingReturnTest extends DriverResolutionTest with PackageMixin { + test_alwaysThrows() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; + +@alwaysThrows +void a() { + throw 'msg'; +} + +int f() { + a(); +}'''); + } + test_async() async { await assertErrorsInCode(r''' import 'dart:async'; @@ -23,6 +38,33 @@ ''', [HintCode.MISSING_RETURN]); } + test_async_futureOrVoid() async { + await assertNoErrorsInCode(r''' +import 'dart:async'; +FutureOr<void> f(Future f) async {} +'''); + } + + test_async_futureVoid() async { + await assertNoErrorsInCode(r''' +import 'dart:async'; +Future<void> f() async {} +'''); + } + + test_emptyFunctionBody() async { + await assertNoErrorsInCode(r''' +abstract class A { + int m(); +}'''); + } + + test_expressionFunctionBody() async { + await assertNoErrorsInCode(r''' +int f() => 0; +'''); + } + test_factory() async { await assertErrorsInCode(r''' class A { @@ -55,33 +97,6 @@ ''', [HintCode.MISSING_RETURN]); } - test_emptyFunctionBody() async { - await assertNoErrorsInCode(r''' -abstract class A { - int m(); -}'''); - } - - test_expressionFunctionBody() async { - await assertNoErrorsInCode(r''' -int f() => 0; -'''); - } - - test_async_futureVoid() async { - await assertNoErrorsInCode(r''' -import 'dart:async'; -Future<void> f() async {} -'''); - } - - test_async_futureOrVoid() async { - await assertNoErrorsInCode(r''' -import 'dart:async'; -FutureOr<void> f(Future f) async {} -'''); - } - test_noReturnType() async { await assertNoErrorsInCode(r''' f() {} @@ -93,19 +108,4 @@ void f() {} '''); } - - test_alwaysThrows() async { - addMetaPackage(); - await assertNoErrorsInCode(r''' -import 'package:meta/meta.dart'; - -@alwaysThrows -void a() { - throw 'msg'; -} - -int f() { - a(); -}'''); - } }
diff --git a/pkg/analyzer/test/src/diagnostics/must_be_immutable_test.dart b/pkg/analyzer/test/src/diagnostics/must_be_immutable_test.dart index c444236..2e425d4 100644 --- a/pkg/analyzer/test/src/diagnostics/must_be_immutable_test.dart +++ b/pkg/analyzer/test/src/diagnostics/must_be_immutable_test.dart
@@ -52,6 +52,17 @@ ''', [HintCode.MUST_BE_IMMUTABLE]); } + test_finalField() async { + addMetaPackage(); + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +@immutable +class A { + final x = 7; +} +'''); + } + test_fromMixinWithAnnotation() async { await assertErrorsInCode(r''' import 'package:meta/meta.dart'; @@ -64,16 +75,6 @@ ''', [HintCode.MUST_BE_IMMUTABLE]); } - test_staticField() async { - await assertNoErrorsInCode(r''' -import 'package:meta/meta.dart'; -@immutable -class A { - static int x; -} -'''); - } - test_mixinApplication() async { await assertErrorsInCode(r''' import 'package:meta/meta.dart'; @@ -98,13 +99,12 @@ ''', [HintCode.MUST_BE_IMMUTABLE]); } - test_finalField() async { - addMetaPackage(); + test_staticField() async { await assertNoErrorsInCode(r''' import 'package:meta/meta.dart'; @immutable class A { - final x = 7; + static int x; } '''); }
diff --git a/pkg/analyzer/test/src/diagnostics/must_call_super_test.dart b/pkg/analyzer/test/src/diagnostics/must_call_super_test.dart index d2e6efb..5ef8e97 100644 --- a/pkg/analyzer/test/src/diagnostics/must_call_super_test.dart +++ b/pkg/analyzer/test/src/diagnostics/must_call_super_test.dart
@@ -21,6 +21,22 @@ addMetaPackage(); } + test_containsSuperCall() async { + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @mustCallSuper + void a() {} +} +class C extends A { + @override + void a() { + super.a(); // OK + } +} +'''); + } + test_fromExtendingClass() async { await assertErrorsInCode(r''' import 'package:meta/meta.dart'; @@ -70,22 +86,6 @@ ''', [HintCode.MUST_CALL_SUPER]); } - test_containsSuperCall() async { - await assertNoErrorsInCode(r''' -import 'package:meta/meta.dart'; -class A { - @mustCallSuper - void a() {} -} -class C extends A { - @override - void a() { - super.a(); // OK - } -} -'''); - } - test_overriddenWithFuture() async { // https://github.com/flutter/flutter/issues/11646 await assertNoErrorsInCode(r'''
diff --git a/pkg/analyzer/test/src/diagnostics/non_const_call_to_literal_constructor.dart b/pkg/analyzer/test/src/diagnostics/non_const_call_to_literal_constructor.dart index a0f1591..e4b8eab 100644 --- a/pkg/analyzer/test/src/diagnostics/non_const_call_to_literal_constructor.dart +++ b/pkg/analyzer/test/src/diagnostics/non_const_call_to_literal_constructor.dart
@@ -23,45 +23,6 @@ addMetaPackage(); } - test_nonConstContext() async { - await assertErrorsInCode(r''' -import 'package:meta/meta.dart'; -class A { - @literal - const A(); -} -void main() { - var a = A(); -} -''', [HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR]); - } - - test_usingNew() async { - await assertErrorsInCode(r''' -import 'package:meta/meta.dart'; -class A { - @literal - const A(); -} -void main() { - var a = new A(); -} -''', [HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR_USING_NEW]); - } - - test_namedConstructor() async { - await assertErrorsInCode(r''' -import 'package:meta/meta.dart'; -class A { - @literal - const A.named(); -} -void main() { - var a = A.named(); -} -''', [HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR]); - } - test_constConstructor() async { await assertNoErrorsInCode(r''' import 'package:meta/meta.dart'; @@ -72,20 +33,6 @@ '''); } - test_constCreation() async { - await assertNoErrorsInCode(r''' -import 'package:meta/meta.dart'; -class A { - @literal - const A(); -} - -void main() { - const a = const A(); -} -'''); - } - test_constContextCreation() async { await assertNoErrorsInCode(r''' import 'package:meta/meta.dart'; @@ -100,6 +47,46 @@ '''); } + test_constCreation() async { + await assertNoErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @literal + const A(); +} + +void main() { + const a = const A(); +} +'''); + } + + test_namedConstructor() async { + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @literal + const A.named(); +} +void main() { + var a = A.named(); +} +''', [HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR]); + } + + test_nonConstContext() async { + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @literal + const A(); +} +void main() { + var a = A(); +} +''', [HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR]); + } + test_unconstableCreation() async { await assertNoErrorsInCode(r''' import 'package:meta/meta.dart'; @@ -113,4 +100,17 @@ } '''); } + + test_usingNew() async { + await assertErrorsInCode(r''' +import 'package:meta/meta.dart'; +class A { + @literal + const A(); +} +void main() { + var a = new A(); +} +''', [HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR_USING_NEW]); + } }
diff --git a/pkg/analyzer/test/src/diagnostics/not_null_aware_null_spread_test.dart b/pkg/analyzer/test/src/diagnostics/not_null_aware_null_spread_test.dart new file mode 100644 index 0000000..4a04ab2 --- /dev/null +++ b/pkg/analyzer/test/src/diagnostics/not_null_aware_null_spread_test.dart
@@ -0,0 +1,104 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/src/dart/analysis/experiments.dart'; +import 'package:analyzer/src/error/codes.dart'; +import 'package:analyzer/src/generated/engine.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import '../dart/resolution/driver_resolution.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(NotNullAwareNullSpreadTest); + }); +} + +@reflectiveTest +class NotNullAwareNullSpreadTest extends DriverResolutionTest { + @override + AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl() + ..enabledExperiments = [ + EnableString.control_flow_collections, + EnableString.spread_collections, + ]; + + test_listLiteral_notNullAware_nullLiteral() async { + await assertErrorsInCode(''' +var v = [...null]; +''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]); + } + + test_listLiteral_notNullAware_nullTyped() async { + await assertErrorsInCode(''' +Null a = null; +var v = [...a]; +''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]); + } + + test_listLiteral_nullAware_nullLiteral() async { + await assertNoErrorsInCode(''' +var v = [...?null]; +'''); + } + + test_listLiteral_nullAware_nullTyped() async { + await assertNoErrorsInCode(''' +Null a = null; +var v = [...?a]; +'''); + } + + test_mapLiteral_notNullAware_nullLiteral() async { + await assertErrorsInCode(''' +var v = <int, int>{...null}; +''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]); + } + + test_mapLiteral_notNullAware_nullType() async { + await assertErrorsInCode(''' +Null a = null; +var v = <int, int>{...a}; +''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]); + } + + test_mapLiteral_nullAware_nullLiteral() async { + await assertNoErrorsInCode(''' +var v = <int, int>{...?null}; +'''); + } + + test_mapLiteral_nullAware_nullType() async { + await assertNoErrorsInCode(''' +Null a = null; +var v = <int, int>{...?a}; +'''); + } + + test_setLiteral_notNullAware_nullLiteral() async { + await assertErrorsInCode(''' +var v = <int>{...null}; +''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]); + } + + test_setLiteral_notNullAware_nullTyped() async { + await assertErrorsInCode(''' +Null a = null; +var v = <int>{...a}; +''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]); + } + + test_setLiteral_nullAware_nullLiteral() async { + await assertNoErrorsInCode(''' +var v = <int>{...?null}; +'''); + } + + test_setLiteral_nullAware_nullTyped() async { + await assertNoErrorsInCode(''' +Null a = null; +var v = <int>{...?a}; +'''); + } +}
diff --git a/pkg/analyzer/test/src/diagnostics/null_aware_before_operator_test.dart b/pkg/analyzer/test/src/diagnostics/null_aware_before_operator_test.dart index a5b4154..5505086 100644 --- a/pkg/analyzer/test/src/diagnostics/null_aware_before_operator_test.dart +++ b/pkg/analyzer/test/src/diagnostics/null_aware_before_operator_test.dart
@@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/error/codes.dart'; -import 'package:analyzer/src/test_utilities/package_mixin.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/driver_resolution.dart'; @@ -16,14 +15,6 @@ @reflectiveTest class NullAwareBeforeOperatorTest extends DriverResolutionTest { - test_minus() async { - await assertErrorsInCode(r''' -m(x) { - x?.a - ''; -} -''', [HintCode.NULL_AWARE_BEFORE_OPERATOR]); - } - test_assignment() async { await assertNoErrorsInCode(r''' m(x) { @@ -56,6 +47,14 @@ '''); } + test_minus() async { + await assertErrorsInCode(r''' +m(x) { + x?.a - ''; +} +''', [HintCode.NULL_AWARE_BEFORE_OPERATOR]); + } + test_not_equal() async { await assertNoErrorsInCode(r''' m(x) {
diff --git a/pkg/analyzer/test/src/diagnostics/null_aware_in_condition_test.dart b/pkg/analyzer/test/src/diagnostics/null_aware_in_condition_test.dart index db754f2..18bed78 100644 --- a/pkg/analyzer/test/src/diagnostics/null_aware_in_condition_test.dart +++ b/pkg/analyzer/test/src/diagnostics/null_aware_in_condition_test.dart
@@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/error/codes.dart'; -import 'package:analyzer/src/test_utilities/package_mixin.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/driver_resolution.dart';
diff --git a/pkg/analyzer/test/src/diagnostics/null_aware_in_logical_operator_test.dart b/pkg/analyzer/test/src/diagnostics/null_aware_in_logical_operator_test.dart index e3b48d2..05f7a5e 100644 --- a/pkg/analyzer/test/src/diagnostics/null_aware_in_logical_operator_test.dart +++ b/pkg/analyzer/test/src/diagnostics/null_aware_in_logical_operator_test.dart
@@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/error/codes.dart'; -import 'package:analyzer/src/test_utilities/package_mixin.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/driver_resolution.dart'; @@ -64,14 +63,6 @@ ''', [HintCode.NULL_AWARE_IN_LOGICAL_OPERATOR]); } - test_not() async { - await assertErrorsInCode(r''' -m(x) { - !x?.a; -} -''', [HintCode.NULL_AWARE_IN_LOGICAL_OPERATOR]); - } - test_for_noCondition() async { await assertNoErrorsInCode(r''' m(x) { @@ -87,4 +78,12 @@ } '''); } + + test_not() async { + await assertErrorsInCode(r''' +m(x) { + !x?.a; +} +''', [HintCode.NULL_AWARE_IN_LOGICAL_OPERATOR]); + } }
diff --git a/pkg/analyzer/test/src/diagnostics/override_equals_but_not_hashcode_test.dart b/pkg/analyzer/test/src/diagnostics/override_equals_but_not_hashcode_test.dart index 4a8a42c..898bbe1 100644 --- a/pkg/analyzer/test/src/diagnostics/override_equals_but_not_hashcode_test.dart +++ b/pkg/analyzer/test/src/diagnostics/override_equals_but_not_hashcode_test.dart
@@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/error/codes.dart'; -import 'package:analyzer/src/test_utilities/package_mixin.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/driver_resolution.dart'; @@ -16,14 +15,6 @@ @reflectiveTest class OverrideEqualsButNotHashCodeTest extends DriverResolutionTest { - @failingTest - test_overrideEquals_andNotHashCode() async { - await assertErrorsInCode(r''' -class A { - bool operator ==(x) {} -}''', [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]); - } - test_overrideBoth() async { await assertNoErrorsInCode(r''' class A { @@ -31,4 +22,12 @@ get hashCode => 0; }'''); } + + @failingTest + test_overrideEquals_andNotHashCode() async { + await assertErrorsInCode(r''' +class A { + bool operator ==(x) {} +}''', [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]); + } }
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_field_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_field_test.dart index 3bd7122..8bb0368 100644 --- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_field_test.dart +++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_field_test.dart
@@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/error/codes.dart'; -import 'package:analyzer/src/test_utilities/package_mixin.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/driver_resolution.dart'; @@ -16,16 +15,6 @@ @reflectiveTest class OverrideOnNonOverridingFieldTest extends DriverResolutionTest { - test_invalid() async { - await assertErrorsInCode(r''' -class A { -} -class B extends A { - @override - final int m = 1; -}''', [HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD]); - } - test_inInterface() async { await assertErrorsInCode(r''' class A { @@ -59,4 +48,14 @@ int c; }''', [CompileTimeErrorCode.INVALID_OVERRIDE]); } + + test_invalid() async { + await assertErrorsInCode(r''' +class A { +} +class B extends A { + @override + final int m = 1; +}''', [HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD]); + } }
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart index 7ccce0e..c9b41a6 100644 --- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart +++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart
@@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/error/codes.dart'; -import 'package:analyzer/src/test_utilities/package_mixin.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/driver_resolution.dart'; @@ -16,16 +15,6 @@ @reflectiveTest class OverrideOnNonOverridingGetterTest extends DriverResolutionTest { - test_invalid() async { - await assertErrorsInCode(r''' -class A { -} -class B extends A { - @override - int get m => 1; -}''', [HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER]); - } - test_inInterface() async { await assertNoErrorsInCode(r''' class A { @@ -47,4 +36,14 @@ int get m => 1; }'''); } + + test_invalid() async { + await assertErrorsInCode(r''' +class A { +} +class B extends A { + @override + int get m => 1; +}''', [HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER]); + } }
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart index bc7f3f1..fb6038e 100644 --- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart +++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart
@@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/error/codes.dart'; -import 'package:analyzer/src/test_utilities/package_mixin.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/driver_resolution.dart'; @@ -16,16 +15,6 @@ @reflectiveTest class OverrideOnNonOverridingMethodTest extends DriverResolutionTest { - test_invalid() async { - await assertErrorsInCode(r''' -class A { -} -class B extends A { - @override - int m() => 1; -}''', [HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]); - } - test_inInterface() async { await assertNoErrorsInCode(r''' class A { @@ -74,4 +63,14 @@ int m() => 1; }'''); } + + test_invalid() async { + await assertErrorsInCode(r''' +class A { +} +class B extends A { + @override + int m() => 1; +}''', [HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]); + } }
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart index 2cf04df..a9b4b62 100644 --- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart +++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart
@@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/error/codes.dart'; -import 'package:analyzer/src/test_utilities/package_mixin.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/driver_resolution.dart'; @@ -16,16 +15,6 @@ @reflectiveTest class OverrideOnNonOverridingSetterTest extends DriverResolutionTest { - test_invalid() async { - await assertErrorsInCode(r''' -class A { -} -class B extends A { - @override - set m(int x) {} -}''', [HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER]); - } - test_inInterface() async { await assertNoErrorsInCode(r''' class A { @@ -47,4 +36,14 @@ set m(int x) {} }'''); } + + test_invalid() async { + await assertErrorsInCode(r''' +class A { +} +class B extends A { + @override + set m(int x) {} +}''', [HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER]); + } }
diff --git a/pkg/analyzer/test/src/diagnostics/subtype_of_sealed_class_test.dart b/pkg/analyzer/test/src/diagnostics/subtype_of_sealed_class_test.dart index c0efd81..6801637 100644 --- a/pkg/analyzer/test/src/diagnostics/subtype_of_sealed_class_test.dart +++ b/pkg/analyzer/test/src/diagnostics/subtype_of_sealed_class_test.dart
@@ -66,17 +66,18 @@ assertTestErrors([HintCode.SUBTYPE_OF_SEALED_CLASS]); } - test_mixinImplementsSealedClass() async { + test_mixinApplicationOfSealedMixin() async { addMetaPackage(); _addPackage('foo', r''' import 'package:meta/meta.dart'; -@sealed class Foo {} +@sealed mixin Foo {} '''); _newPubPackageRoot('/pkg1'); newFile('/pkg1/lib/lib1.dart', content: r''' import 'package:foo/foo.dart'; -mixin Bar implements Foo {} +class Bar1 {} +class Bar2 = Bar1 with Foo; '''); await _resolveTestFile('/pkg1/lib/lib1.dart'); assertTestErrors([HintCode.SUBTYPE_OF_SEALED_CLASS]); @@ -98,18 +99,17 @@ assertTestErrors([HintCode.SUBTYPE_OF_SEALED_CLASS]); } - test_mixinApplicationOfSealedMixin() async { + test_mixinImplementsSealedClass() async { addMetaPackage(); _addPackage('foo', r''' import 'package:meta/meta.dart'; -@sealed mixin Foo {} +@sealed class Foo {} '''); _newPubPackageRoot('/pkg1'); newFile('/pkg1/lib/lib1.dart', content: r''' import 'package:foo/foo.dart'; -class Bar1 {} -class Bar2 = Bar1 with Foo; +mixin Bar implements Foo {} '''); await _resolveTestFile('/pkg1/lib/lib1.dart'); assertTestErrors([HintCode.SUBTYPE_OF_SEALED_CLASS]);
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart index 8de2941..7bf4d02 100644 --- a/pkg/analyzer/test/src/diagnostics/test_all.dart +++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -32,6 +32,8 @@ as import_deferred_library_with_load_function; import 'invalid_assignment_test.dart' as invalid_assignment; import 'invalid_cast_new_expr_test.dart' as invalid_cast_new_expr; +import 'invalid_factory_annotation_test.dart' as invalid_factory_annotation; +import 'invalid_factory_method_impl_test.dart' as invalid_factory_method_impl; import 'invalid_immutable_annotation_test.dart' as invalid_immutable_annotation; import 'invalid_literal_annotation_test.dart' as invalid_literal_annotation; import 'invalid_override_different_default_values_named_test.dart' @@ -40,6 +42,12 @@ as invalid_override_different_default_values_positional; import 'invalid_required_param_test.dart' as invalid_required_param; import 'invalid_sealed_annotation_test.dart' as invalid_sealed_annotation; +import 'invalid_use_of_protected_member_test.dart' + as invalid_use_of_protected_member; +import 'invalid_use_of_visible_for_template_member_test.dart' + as invalid_use_of_visible_for_template_member; +import 'invalid_use_of_visible_for_testing_member_test.dart' + as invalid_use_of_visible_for_testing_member; import 'invalid_visibility_annotation_test.dart' as invalid_visibility_annotation; import 'list_element_type_not_assignable_test.dart' @@ -48,6 +56,7 @@ import 'map_key_type_not_assignable_test.dart' as map_key_type_not_assignable; import 'map_value_type_not_assignable_test.dart' as map_value_type_not_assignable; +import 'missing_required_param_test.dart' as missing_required_param; import 'missing_return_test.dart' as missing_return; import 'mixin_on_sealed_class_test.dart' as mixin_on_sealed_class; import 'must_be_immutable_test.dart' as must_be_immutable; @@ -72,6 +81,7 @@ as non_constant_spread_expression_from_deferred_library; import 'not_iterable_spread_test.dart' as not_iterable_spread; import 'not_map_spread_test.dart' as not_map_spread; +import 'not_null_aware_null_spread_test.dart' as not_null_aware_null_spread; import 'null_aware_before_operator_test.dart' as null_aware_before_operator; import 'null_aware_in_condition_test.dart' as null_aware_in_condition; import 'null_aware_in_logical_operator_test.dart' @@ -153,17 +163,23 @@ import_deferred_library_with_load_function.main(); invalid_assignment.main(); invalid_cast_new_expr.main(); + invalid_factory_annotation.main(); + invalid_factory_method_impl.main(); invalid_immutable_annotation.main(); invalid_literal_annotation.main(); invalid_override_different_default_values_named.main(); invalid_override_different_default_values_positional.main(); invalid_required_param.main(); invalid_sealed_annotation.main(); + invalid_use_of_protected_member.main(); + invalid_use_of_visible_for_template_member.main(); + invalid_use_of_visible_for_testing_member.main(); invalid_visibility_annotation.main(); list_element_type_not_assignable.main(); map_entry_not_in_map.main(); map_key_type_not_assignable.main(); map_value_type_not_assignable.main(); + missing_required_param.main(); missing_return.main(); mixin_on_sealed_class.main(); must_be_immutable.main(); @@ -182,6 +198,7 @@ non_constant_spread_expression_from_deferred_library.main(); not_iterable_spread.main(); not_map_spread.main(); + not_null_aware_null_spread.main(); null_aware_before_operator.main(); null_aware_in_condition.main(); null_aware_in_logical_operator.main();
diff --git a/pkg/analyzer/test/src/manifest/manifest_validator_test.dart b/pkg/analyzer/test/src/manifest/manifest_validator_test.dart new file mode 100644 index 0000000..8cd846cc6 --- /dev/null +++ b/pkg/analyzer/test/src/manifest/manifest_validator_test.dart
@@ -0,0 +1,75 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +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/manifest/manifest_validator.dart'; +import 'package:analyzer/src/manifest/manifest_warning_code.dart'; +import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import '../../generated/test_support.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(ManifestValidatorTest); + }); +} + +@reflectiveTest +class ManifestValidatorTest with ResourceProviderMixin { + ManifestValidator validator; + + /** + * Assert that when the validator is used on the given [content] the + * [expectedErrorCodes] are produced. + */ + void assertErrors(String content, List<ErrorCode> expectedErrorCodes) { + List<AnalysisError> errors = validator.validate(content, true); + 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 ManifestFile = getFile('/sample/Manifest.xml'); + Source source = ManifestFile.createSource(); + validator = new ManifestValidator(source); + } + + test_hardwareNotSupported_error() { + assertErrors(''' +<manifest + xmlns:android="http://schemas.android.com/apk/res/android"> + <uses-feature android:name="android.software.home_screen" /> +</manifest> +''', [ManifestWarningCode.UNSUPPORTED_CHROME_OS_HARDWARE]); + } + + test_cameraPermissions_error() { + assertErrors(''' +<manifest + xmlns:android="http://schemas.android.com/apk/res/android"> + <uses-permission android:name="android.permission.CAMERA" /> +</manifest> +''', [ManifestWarningCode.CAMERA_PERMISSIONS_INCOMPATIBLE]); + } + + test_no_errors() { + assertErrors(''' +<manifest + xmlns:android="http://schemas.android.com/apk/res/android"> +</manifest> +''', []); + } +}
diff --git a/pkg/analyzer/test/src/manifest/test_all.dart b/pkg/analyzer/test/src/manifest/test_all.dart new file mode 100644 index 0000000..09e62ac --- /dev/null +++ b/pkg/analyzer/test/src/manifest/test_all.dart
@@ -0,0 +1,13 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import 'manifest_validator_test.dart' as manifest_test; + +main() { + defineReflectiveSuite(() { + manifest_test.main(); + }, name: 'task'); +}
diff --git a/pkg/analyzer/test/src/services/available_declarations_test.dart b/pkg/analyzer/test/src/services/available_declarations_test.dart index 8045e44..206a034 100644 --- a/pkg/analyzer/test/src/services/available_declarations_test.dart +++ b/pkg/analyzer/test/src/services/available_declarations_test.dart
@@ -203,11 +203,18 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/test.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), - _ExpectedDeclaration.class_('C'), - _ExpectedDeclaration.enum_('E'), - _ExpectedDeclaration.enumConstant('v', 'E'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.enum_('E', [ + _ExpectedDeclaration.enumConstant('v'), + ]), ]); } @@ -240,15 +247,23 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/b.dart', declarations: [ - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasNoLibrary('package:test/c.dart'); _assertHasLibrary('package:test/d.dart', declarations: [ - _ExpectedDeclaration.class_('D'), + _ExpectedDeclaration.class_('D', [ + _ExpectedDeclaration.constructor(''), + ]), ]); newFile(c, content: r''' @@ -258,19 +273,33 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/b.dart', declarations: [ - _ExpectedDeclaration.class_('B'), - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/c.dart', declarations: [ - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/d.dart', declarations: [ - _ExpectedDeclaration.class_('D'), + _ExpectedDeclaration.class_('D', [ + _ExpectedDeclaration.constructor(''), + ]), ]); } @@ -285,7 +314,9 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasNoLibrary('package:test/b.dart'); @@ -296,10 +327,14 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/b.dart', declarations: [ - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); var librariesObject = declarationsContext.getLibraries( @@ -327,11 +362,15 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasNoLibrary('package:test/b.dart'); _assertHasLibrary('package:test/c.dart', declarations: [ - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); newFile(b, content: r''' @@ -342,12 +381,18 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasNoLibrary('package:test/b.dart'); _assertHasLibrary('package:test/c.dart', declarations: [ - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); } @@ -382,7 +427,10 @@ await _doAllTrackerWork(); _assertDeclaration( - _getLibrary('package:test/test.dart'), + _getDeclaration( + _getLibrary('package:test/test.dart').declarations, + 'A', + ), 'A', DeclarationKind.CLASS, relevanceTags: ['package:test/test.dart::A'], @@ -394,7 +442,10 @@ await _doAllTrackerWork(); _assertDeclaration( - _getLibrary('package:test/test.dart'), + _getDeclaration( + _getLibrary('package:test/test.dart').declarations, + 'B', + ), 'B', DeclarationKind.CLASS, relevanceTags: ['package:test/test.dart::B'], @@ -426,7 +477,10 @@ await _doAllTrackerWork(); _assertDeclaration( - _getLibrary('package:aaa/a.dart'), + _getDeclaration( + _getLibrary('package:aaa/a.dart').declarations, + 'A', + ), 'A', DeclarationKind.CLASS, relevanceTags: ['package:aaa/a.dart::A'], @@ -438,7 +492,10 @@ await _doAllTrackerWork(); _assertDeclaration( - _getLibrary('package:aaa/a.dart'), + _getDeclaration( + _getLibrary('package:aaa/a.dart').declarations, + 'B', + ), 'B', DeclarationKind.CLASS, relevanceTags: ['package:aaa/a.dart::B'], @@ -457,7 +514,10 @@ await _doAllTrackerWork(); _assertDeclaration( - _getLibrary('dart:math'), + _getDeclaration( + _getLibrary('dart:math').declarations, + 'A', + ), 'A', DeclarationKind.CLASS, relevanceTags: ['dart:math::A'], @@ -469,7 +529,10 @@ await _doAllTrackerWork(); _assertDeclaration( - _getLibrary('dart:math'), + _getDeclaration( + _getLibrary('dart:math').declarations, + 'B', + ), 'B', DeclarationKind.CLASS, relevanceTags: ['dart:math::B'], @@ -500,19 +563,33 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/b.dart', declarations: [ - _ExpectedDeclaration.class_('B'), - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/c.dart', declarations: [ - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/d.dart', declarations: [ - _ExpectedDeclaration.class_('D'), + _ExpectedDeclaration.class_('D', [ + _ExpectedDeclaration.constructor(''), + ]), ]); deleteFile(c); @@ -520,15 +597,23 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/b.dart', declarations: [ - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasNoLibrary('package:test/c.dart'); _assertHasLibrary('package:test/d.dart', declarations: [ - _ExpectedDeclaration.class_('D'), + _ExpectedDeclaration.class_('D', [ + _ExpectedDeclaration.constructor(''), + ]), ]); } @@ -596,11 +681,17 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/c.dart', declarations: [ - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); deleteFile(b); @@ -608,10 +699,14 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/c.dart', declarations: [ - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); } @@ -652,19 +747,33 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/b.dart', declarations: [ - _ExpectedDeclaration.class_('B'), - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/c.dart', declarations: [ - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/d.dart', declarations: [ - _ExpectedDeclaration.class_('D'), + _ExpectedDeclaration.class_('D', [ + _ExpectedDeclaration.constructor(''), + ]), ]); newFile(c, content: r''' @@ -674,19 +783,33 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), - _ExpectedDeclaration.class_('C2'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('C2', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/b.dart', declarations: [ - _ExpectedDeclaration.class_('B'), - _ExpectedDeclaration.class_('C2'), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('C2', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/c.dart', declarations: [ - _ExpectedDeclaration.class_('C2'), + _ExpectedDeclaration.class_('C2', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/d.dart', declarations: [ - _ExpectedDeclaration.class_('D'), + _ExpectedDeclaration.class_('D', [ + _ExpectedDeclaration.constructor(''), + ]), ]); } @@ -704,10 +827,14 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/b.dart', declarations: [ - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); newFile(a, content: r''' @@ -717,10 +844,14 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A2'), + _ExpectedDeclaration.class_('A2', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/b.dart', declarations: [ - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); } @@ -744,11 +875,17 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/c.dart', declarations: [ - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); newFile(b, content: r''' @@ -759,11 +896,17 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B2'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B2', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/c.dart', declarations: [ - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); } @@ -845,27 +988,27 @@ var library = _getLibrary('package:test/test.dart'); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'A'), 'A', DeclarationKind.CLASS, relevanceTags: ['package:test/test.dart::A'], ); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'B'), 'B', DeclarationKind.CLASS, isAbstract: true, relevanceTags: ['package:test/test.dart::B'], ); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'C'), 'C', DeclarationKind.CLASS, isDeprecated: true, relevanceTags: ['package:test/test.dart::C'], ); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'D'), 'D', DeclarationKind.CLASS, docSummary: 'aaa', @@ -894,20 +1037,20 @@ var library = _getLibrary('package:test/test.dart'); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'A'), 'A', DeclarationKind.CLASS_TYPE_ALIAS, relevanceTags: ['package:test/test.dart::A'], ); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'B'), 'B', DeclarationKind.CLASS_TYPE_ALIAS, isDeprecated: true, relevanceTags: ['package:test/test.dart::B'], ); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'C'), 'C', DeclarationKind.CLASS_TYPE_ALIAS, docSummary: 'aaa', @@ -944,49 +1087,69 @@ await _doAllTrackerWork(); var library = _getLibrary('package:test/test.dart'); - _assertDeclaration(library, '', DeclarationKind.CONSTRUCTOR, - name2: 'C', - parameterNames: [], - parameters: '()', - parameterTypes: [], - requiredParameterCount: 0); - _assertDeclaration(library, 'a', DeclarationKind.CONSTRUCTOR, - name2: 'C', - parameterNames: [], - parameters: '()', - parameterTypes: [], - requiredParameterCount: 0); - _assertDeclaration(library, 'b', DeclarationKind.CONSTRUCTOR, - isDeprecated: true, - name2: 'C', - parameters: '()', - parameterNames: [], - parameterTypes: [], - requiredParameterCount: 0); - _assertDeclaration(library, 'c', DeclarationKind.CONSTRUCTOR, - docSummary: 'aaa', - docComplete: 'aaa\n\nbbb bbb', - name2: 'C', - parameters: '()', - parameterNames: [], - parameterTypes: [], - requiredParameterCount: 0); - _assertDeclaration(library, 'd', DeclarationKind.CONSTRUCTOR, - defaultArgumentListString: 'p1, p2', - defaultArgumentListTextRanges: [0, 2, 4, 2], - name2: 'C', - parameters: '(Map<String, int> p1, int p2, {double p3})', - parameterNames: ['p1', 'p2', 'p3'], - parameterTypes: ['Map<String, int>', 'int', 'double'], - requiredParameterCount: 2); - _assertDeclaration(library, 'e', DeclarationKind.CONSTRUCTOR, - defaultArgumentListString: 'f1, f2', - defaultArgumentListTextRanges: [0, 2, 4, 2], - name2: 'C', - parameters: '(this.f1, this.f2)', - parameterNames: ['f1', 'f2'], - parameterTypes: ['', ''], - requiredParameterCount: 2); + var classDeclaration = _getDeclaration(library.declarations, 'C'); + + _assertDeclaration( + _getDeclaration(classDeclaration.children, ''), + '', + DeclarationKind.CONSTRUCTOR, + parameterNames: [], + parameters: '()', + parameterTypes: [], + requiredParameterCount: 0, + ); + _assertDeclaration( + _getDeclaration(classDeclaration.children, 'a'), + 'a', + DeclarationKind.CONSTRUCTOR, + parameterNames: [], + parameters: '()', + parameterTypes: [], + requiredParameterCount: 0, + ); + _assertDeclaration( + _getDeclaration(classDeclaration.children, 'b'), + 'b', + DeclarationKind.CONSTRUCTOR, + isDeprecated: true, + parameters: '()', + parameterNames: [], + parameterTypes: [], + requiredParameterCount: 0, + ); + _assertDeclaration( + _getDeclaration(classDeclaration.children, 'c'), + 'c', + DeclarationKind.CONSTRUCTOR, + docSummary: 'aaa', + docComplete: 'aaa\n\nbbb bbb', + parameters: '()', + parameterNames: [], + parameterTypes: [], + requiredParameterCount: 0, + ); + _assertDeclaration( + _getDeclaration(classDeclaration.children, 'd'), + 'd', + DeclarationKind.CONSTRUCTOR, + defaultArgumentListString: 'p1, p2', + defaultArgumentListTextRanges: [0, 2, 4, 2], + parameters: '(Map<String, int> p1, int p2, {double p3})', + parameterNames: ['p1', 'p2', 'p3'], + parameterTypes: ['Map<String, int>', 'int', 'double'], + requiredParameterCount: 2, + ); + _assertDeclaration( + _getDeclaration(classDeclaration.children, 'e'), + 'e', + DeclarationKind.CONSTRUCTOR, + defaultArgumentListString: 'f1, f2', + defaultArgumentListTextRanges: [0, 2, 4, 2], + parameters: '(this.f1, this.f2)', + parameterNames: ['f1', 'f2'], + parameterTypes: ['', ''], + requiredParameterCount: 2, + ); } test_ENUM() async { @@ -1007,20 +1170,20 @@ var library = _getLibrary('package:test/test.dart'); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'A'), 'A', DeclarationKind.ENUM, relevanceTags: ['package:test/test.dart::A'], ); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'B'), 'B', DeclarationKind.ENUM, isDeprecated: true, relevanceTags: ['package:test/test.dart::B'], ); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'C'), 'C', DeclarationKind.ENUM, docSummary: 'aaa', @@ -1048,28 +1211,27 @@ await _doAllTrackerWork(); var library = _getLibrary('package:test/test.dart'); + var enumDeclaration = _getDeclaration(library.declarations, 'MyEnum'); + _assertDeclaration( - library, + _getDeclaration(enumDeclaration.children, 'a'), 'a', DeclarationKind.ENUM_CONSTANT, - name2: 'MyEnum', relevanceTags: ['package:test/test.dart::MyEnum'], ); _assertDeclaration( - library, + _getDeclaration(enumDeclaration.children, 'b'), 'b', DeclarationKind.ENUM_CONSTANT, isDeprecated: true, - name2: 'MyEnum', relevanceTags: ['package:test/test.dart::MyEnum'], ); _assertDeclaration( - library, + _getDeclaration(enumDeclaration.children, 'c'), 'c', DeclarationKind.ENUM_CONSTANT, docSummary: 'aaa', docComplete: 'aaa\n\nbbb bbb', - name2: 'MyEnum', relevanceTags: ['package:test/test.dart::MyEnum'], ); } @@ -1095,42 +1257,62 @@ await _doAllTrackerWork(); var library = _getLibrary('package:test/test.dart'); - _assertDeclaration(library, 'a', DeclarationKind.FUNCTION, - parameterNames: [], - parameters: '()', - parameterTypes: [], - requiredParameterCount: 0, - returnType: 'void'); - _assertDeclaration(library, 'b', DeclarationKind.FUNCTION, - isDeprecated: true, - parameters: '()', - parameterNames: [], - parameterTypes: [], - requiredParameterCount: 0, - returnType: 'void'); - _assertDeclaration(library, 'c', DeclarationKind.FUNCTION, - docSummary: 'aaa', - docComplete: 'aaa\n\nbbb bbb', - parameters: '()', - parameterNames: [], - parameterTypes: [], - requiredParameterCount: 0, - returnType: 'void'); - _assertDeclaration(library, 'd', DeclarationKind.FUNCTION, - defaultArgumentListString: 'p1, p2', - defaultArgumentListTextRanges: [0, 2, 4, 2], - parameters: '(Map<String, int> p1, int p2, {double p3})', - parameterNames: ['p1', 'p2', 'p3'], - parameterTypes: ['Map<String, int>', 'int', 'double'], - requiredParameterCount: 2, - returnType: 'List<String>'); - _assertDeclaration(library, 'e', DeclarationKind.FUNCTION, - parameters: '()', - parameterNames: [], - parameterTypes: [], - requiredParameterCount: 0, - returnType: 'void', - typeParameters: '<T extends num, U>'); + _assertDeclaration( + _getDeclaration(library.declarations, 'a'), + 'a', + DeclarationKind.FUNCTION, + parameterNames: [], + parameters: '()', + parameterTypes: [], + requiredParameterCount: 0, + returnType: 'void', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'b'), + 'b', + DeclarationKind.FUNCTION, + isDeprecated: true, + parameters: '()', + parameterNames: [], + parameterTypes: [], + requiredParameterCount: 0, + returnType: 'void', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'c'), + 'c', + DeclarationKind.FUNCTION, + docSummary: 'aaa', + docComplete: 'aaa\n\nbbb bbb', + parameters: '()', + parameterNames: [], + parameterTypes: [], + requiredParameterCount: 0, + returnType: 'void', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'd'), + 'd', + DeclarationKind.FUNCTION, + defaultArgumentListString: 'p1, p2', + defaultArgumentListTextRanges: [0, 2, 4, 2], + parameters: '(Map<String, int> p1, int p2, {double p3})', + parameterNames: ['p1', 'p2', 'p3'], + parameterTypes: ['Map<String, int>', 'int', 'double'], + requiredParameterCount: 2, + returnType: 'List<String>', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'e'), + 'e', + DeclarationKind.FUNCTION, + parameters: '()', + parameterNames: [], + parameterTypes: [], + requiredParameterCount: 0, + returnType: 'void', + typeParameters: '<T extends num, U>', + ); } test_FUNCTION_defaultArgumentList() async { @@ -1148,36 +1330,52 @@ await _doAllTrackerWork(); var library = _getLibrary('package:test/test.dart'); - _assertDeclaration(library, 'a', DeclarationKind.FUNCTION, - parameterNames: [], - parameters: '()', - parameterTypes: [], - requiredParameterCount: 0, - returnType: 'void'); - _assertDeclaration(library, 'b', DeclarationKind.FUNCTION, - defaultArgumentListString: 'a, bb, ccc', - defaultArgumentListTextRanges: [0, 1, 3, 2, 7, 3], - parameters: '(int a, double bb, String ccc)', - parameterNames: ['a', 'bb', 'ccc'], - parameterTypes: ['int', 'double', 'String'], - requiredParameterCount: 3, - returnType: 'void'); - _assertDeclaration(library, 'c', DeclarationKind.FUNCTION, - defaultArgumentListString: 'a', - defaultArgumentListTextRanges: [0, 1], - parameters: '(int a, [double b, String c])', - parameterNames: ['a', 'b', 'c'], - parameterTypes: ['int', 'double', 'String'], - requiredParameterCount: 1, - returnType: 'void'); - _assertDeclaration(library, 'd', DeclarationKind.FUNCTION, - defaultArgumentListString: 'a, c: null, d: null', - defaultArgumentListTextRanges: [0, 1, 6, 4, 15, 4], - parameters: '(int a, {int b, @required int c, @required int d, int e})', - parameterNames: ['a', 'b', 'c', 'd', 'e'], - parameterTypes: ['int', 'int', 'int', 'int', 'int'], - requiredParameterCount: 1, - returnType: 'void'); + _assertDeclaration( + _getDeclaration(library.declarations, 'a'), + 'a', + DeclarationKind.FUNCTION, + parameterNames: [], + parameters: '()', + parameterTypes: [], + requiredParameterCount: 0, + returnType: 'void', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'b'), + 'b', + DeclarationKind.FUNCTION, + defaultArgumentListString: 'a, bb, ccc', + defaultArgumentListTextRanges: [0, 1, 3, 2, 7, 3], + parameters: '(int a, double bb, String ccc)', + parameterNames: ['a', 'bb', 'ccc'], + parameterTypes: ['int', 'double', 'String'], + requiredParameterCount: 3, + returnType: 'void', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'c'), + 'c', + DeclarationKind.FUNCTION, + defaultArgumentListString: 'a', + defaultArgumentListTextRanges: [0, 1], + parameters: '(int a, [double b, String c])', + parameterNames: ['a', 'b', 'c'], + parameterTypes: ['int', 'double', 'String'], + requiredParameterCount: 1, + returnType: 'void', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'd'), + 'd', + DeclarationKind.FUNCTION, + defaultArgumentListString: 'a, c: null, d: null', + defaultArgumentListTextRanges: [0, 1, 6, 4, 15, 4], + parameters: '(int a, {int b, @required int c, @required int d, int e})', + parameterNames: ['a', 'b', 'c', 'd', 'e'], + parameterTypes: ['int', 'int', 'int', 'int', 'int'], + requiredParameterCount: 1, + returnType: 'void', + ); } test_FUNCTION_TYPE_ALIAS() async { @@ -1203,52 +1401,88 @@ await _doAllTrackerWork(); var library = _getLibrary('package:test/test.dart'); - _assertDeclaration(library, 'A', DeclarationKind.FUNCTION_TYPE_ALIAS, - parameters: '()', - parameterNames: [], - parameterTypes: [], - relevanceTags: ['package:test/test.dart::A'], - requiredParameterCount: 0, - returnType: 'void'); - _assertDeclaration(library, 'B', DeclarationKind.FUNCTION_TYPE_ALIAS, - isDeprecated: true, - parameters: '()', - parameterNames: [], - parameterTypes: [], - relevanceTags: ['package:test/test.dart::B'], - requiredParameterCount: 0, - returnType: 'void'); - _assertDeclaration(library, 'C', DeclarationKind.FUNCTION_TYPE_ALIAS, - docSummary: 'aaa', - docComplete: 'aaa\n\nbbb bbb', - parameters: '()', - parameterNames: [], - parameterTypes: [], - relevanceTags: ['package:test/test.dart::C'], - requiredParameterCount: 0, - returnType: 'void'); - _assertDeclaration(library, 'D', DeclarationKind.FUNCTION_TYPE_ALIAS, - parameters: '(int p1, [double p2, String p3])', - parameterNames: ['p1', 'p2', 'p3'], - parameterTypes: ['int', 'double', 'String'], - relevanceTags: ['package:test/test.dart::D'], - requiredParameterCount: 1, - returnType: 'int'); - _assertDeclaration(library, 'E', DeclarationKind.FUNCTION_TYPE_ALIAS, - parameters: '(int, double, {String p3})', - parameterNames: ['', '', 'p3'], - parameterTypes: ['int', 'double', 'String'], - relevanceTags: ['package:test/test.dart::E'], - requiredParameterCount: 2, - returnType: 'void'); - _assertDeclaration(library, 'F', DeclarationKind.FUNCTION_TYPE_ALIAS, - parameters: '()', - parameterNames: [], - parameterTypes: [], - requiredParameterCount: 0, - relevanceTags: ['package:test/test.dart::F'], - returnType: 'void', - typeParameters: '<T extends num, U>'); + _assertDeclaration( + _getDeclaration(library.declarations, 'A'), + 'A', + DeclarationKind.FUNCTION_TYPE_ALIAS, + parameters: '()', + parameterNames: [], + parameterTypes: [], + relevanceTags: ['package:test/test.dart::A'], + requiredParameterCount: 0, + returnType: 'void', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'B'), + 'B', + DeclarationKind.FUNCTION_TYPE_ALIAS, + isDeprecated: true, + parameters: '()', + parameterNames: [], + parameterTypes: [], + relevanceTags: ['package:test/test.dart::B'], + requiredParameterCount: 0, + returnType: 'void', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'C'), + 'C', + DeclarationKind.FUNCTION_TYPE_ALIAS, + docSummary: 'aaa', + docComplete: 'aaa\n\nbbb bbb', + parameters: '()', + parameterNames: [], + parameterTypes: [], + relevanceTags: ['package:test/test.dart::C'], + requiredParameterCount: 0, + returnType: 'void', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'D'), + 'D', + DeclarationKind.FUNCTION_TYPE_ALIAS, + parameters: '(int p1, [double p2, String p3])', + parameterNames: ['p1', 'p2', 'p3'], + parameterTypes: ['int', 'double', 'String'], + relevanceTags: ['package:test/test.dart::D'], + requiredParameterCount: 1, + returnType: 'int', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'E'), + 'E', + DeclarationKind.FUNCTION_TYPE_ALIAS, + parameters: '(int, double, {String p3})', + parameterNames: ['', '', 'p3'], + parameterTypes: ['int', 'double', 'String'], + relevanceTags: ['package:test/test.dart::E'], + requiredParameterCount: 2, + returnType: 'void', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'F'), + 'F', + DeclarationKind.FUNCTION_TYPE_ALIAS, + parameters: '()', + parameterNames: [], + parameterTypes: [], + requiredParameterCount: 0, + relevanceTags: ['package:test/test.dart::F'], + returnType: 'void', + typeParameters: '<T extends num, U>', + ); + } + + test_FUNCTION_TYPE_ALIAS_noFunction() async { + newFile('/home/test/lib/test.dart', content: r''' +typedef A = ; +'''); + + tracker.addContext(testAnalysisContext); + await _doAllTrackerWork(); + + var library = _getLibrary('package:test/test.dart'); + _assertNoDeclaration(library, 'A'); } test_GETTER() async { @@ -1268,16 +1502,21 @@ await _doAllTrackerWork(); var library = _getLibrary('package:test/test.dart'); - _assertDeclaration(library, 'a', DeclarationKind.GETTER, returnType: 'int'); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'a'), + 'a', + DeclarationKind.GETTER, + returnType: 'int', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'b'), 'b', DeclarationKind.GETTER, isDeprecated: true, returnType: 'int', ); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'c'), 'c', DeclarationKind.GETTER, docSummary: 'aaa', @@ -1317,7 +1556,7 @@ var library = _getLibrary('package:test/test.dart'); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'A'), 'A', DeclarationKind.CLASS, relevanceTags: ['package:test/test.dart::A'], @@ -1336,7 +1575,7 @@ var library = _getLibrary('package:test/test.dart'); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'A'), 'A', DeclarationKind.CLASS, relevanceTags: ['package:test/test.dart::A'], @@ -1361,9 +1600,15 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/test.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); } @@ -1382,8 +1627,12 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/test.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); } @@ -1402,10 +1651,12 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/test.dart', declarations: [ - _ExpectedDeclaration.enum_('A'), - _ExpectedDeclaration.enumConstant('a', 'A'), - _ExpectedDeclaration.enum_('B'), - _ExpectedDeclaration.enumConstant('b', 'B'), + _ExpectedDeclaration.enum_('A', [ + _ExpectedDeclaration.enumConstant('a'), + ]), + _ExpectedDeclaration.enum_('B', [ + _ExpectedDeclaration.enumConstant('b'), + ]), ]); } @@ -1422,7 +1673,7 @@ var library = _getLibrary('package:test/test.dart'); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'A'), 'A', DeclarationKind.CLASS, locationOffset: code.indexOf('A {}'), @@ -1432,7 +1683,7 @@ relevanceTags: ['package:test/test.dart::A'], ); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'B'), 'B', DeclarationKind.CLASS, locationOffset: code.indexOf('B {}'), @@ -1462,20 +1713,20 @@ var library = _getLibrary('package:test/test.dart'); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'A'), 'A', DeclarationKind.MIXIN, relevanceTags: ['package:test/test.dart::A'], ); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'B'), 'B', DeclarationKind.MIXIN, isDeprecated: true, relevanceTags: ['package:test/test.dart::B'], ); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'C'), 'C', DeclarationKind.MIXIN, docSummary: 'aaa', @@ -1502,7 +1753,7 @@ var library = _getLibrary('package:test/test.dart'); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'a'), 'a', DeclarationKind.SETTER, parameters: '(int value)', @@ -1511,7 +1762,7 @@ requiredParameterCount: 1, ); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'b'), 'b', DeclarationKind.SETTER, isDeprecated: true, @@ -1521,7 +1772,7 @@ requiredParameterCount: 1, ); _assertDeclaration( - library, + _getDeclaration(library.declarations, 'c'), 'c', DeclarationKind.SETTER, docSummary: 'aaa', @@ -1554,18 +1805,43 @@ await _doAllTrackerWork(); var library = _getLibrary('package:test/test.dart'); - _assertDeclaration(library, 'a', DeclarationKind.VARIABLE, - returnType: 'int'); - _assertDeclaration(library, 'b', DeclarationKind.VARIABLE, - isDeprecated: true, returnType: 'int'); - _assertDeclaration(library, 'c', DeclarationKind.VARIABLE, - docSummary: 'aaa', docComplete: 'aaa\n\nbbb bbb', returnType: 'int'); - _assertDeclaration(library, 'd', DeclarationKind.VARIABLE, - isConst: true, relevanceTags: ['dart:core::int'], returnType: ''); - _assertDeclaration(library, 'e', DeclarationKind.VARIABLE, - isFinal: true, - relevanceTags: ['dart:core::double'], - returnType: 'double'); + _assertDeclaration( + _getDeclaration(library.declarations, 'a'), + 'a', + DeclarationKind.VARIABLE, + returnType: 'int', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'b'), + 'b', + DeclarationKind.VARIABLE, + isDeprecated: true, + returnType: 'int', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'c'), + 'c', + DeclarationKind.VARIABLE, + docSummary: 'aaa', + docComplete: 'aaa\n\nbbb bbb', + returnType: 'int', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'd'), + 'd', + DeclarationKind.VARIABLE, + isConst: true, + relevanceTags: ['dart:core::int'], + returnType: '', + ); + _assertDeclaration( + _getDeclaration(library.declarations, 'e'), + 'e', + DeclarationKind.VARIABLE, + isFinal: true, + relevanceTags: ['dart:core::double'], + returnType: 'double', + ); } } @@ -1585,9 +1861,15 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/test.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('C'), - _ExpectedDeclaration.class_('D'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('D', [ + _ExpectedDeclaration.constructor(''), + ]), ]); } @@ -1605,8 +1887,12 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/test.dart', declarations: [ - _ExpectedDeclaration.class_('B'), - _ExpectedDeclaration.class_('D'), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('D', [ + _ExpectedDeclaration.constructor(''), + ]), ]); } @@ -1622,8 +1908,9 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/test.dart', declarations: [ - _ExpectedDeclaration.enum_('E1'), - _ExpectedDeclaration.enumConstant('a', 'E1'), + _ExpectedDeclaration.enum_('E1', [ + _ExpectedDeclaration.enumConstant('a'), + ]), ]); } @@ -1645,19 +1932,33 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/b.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/test.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); } @@ -1670,12 +1971,14 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/test.dart', declarations: [ - _ExpectedDeclaration.enum_('E1'), - _ExpectedDeclaration.enumConstant('a', 'E1'), - _ExpectedDeclaration.enumConstant('b', 'E1'), - _ExpectedDeclaration.enum_('E2'), - _ExpectedDeclaration.enumConstant('a', 'E2'), - _ExpectedDeclaration.enumConstant('b', 'E2'), + _ExpectedDeclaration.enum_('E1', [ + _ExpectedDeclaration.enumConstant('a'), + _ExpectedDeclaration.enumConstant('b'), + ]), + _ExpectedDeclaration.enum_('E2', [ + _ExpectedDeclaration.enumConstant('a'), + _ExpectedDeclaration.enumConstant('b'), + ]), ]); } @@ -1688,7 +1991,9 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/test.dart', declarations: [ - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); } @@ -1709,18 +2014,30 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/b.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/test.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); } @@ -1738,7 +2055,9 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/test.dart', declarations: [ - _ExpectedDeclaration.class_('A'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), _ExpectedDeclaration.mixin('B'), ]); } @@ -1756,9 +2075,15 @@ await _doAllTrackerWork(); _assertHasLibrary('package:test/test.dart', declarations: [ - _ExpectedDeclaration.class_('A'), - _ExpectedDeclaration.class_('B'), - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); } } @@ -1816,28 +2141,38 @@ await _doAllTrackerWork(); _assertHasLibrary('package:aaa/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasNoLibrary('package:aaa/src/a2.dart'); _assertHasLibrary('package:bbb/b.dart', declarations: [ - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasNoLibrary('package:bbb/src/b2.dart'); _assertHasLibrary('package:material_button/button.dart', declarations: [ - _ExpectedDeclaration.class_('MaterialButton'), + _ExpectedDeclaration.class_('MaterialButton', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary( toUriStr('/home/material_button/test/button_test.dart'), declarations: [ - _ExpectedDeclaration.class_('MaterialButtonTest'), + _ExpectedDeclaration.class_('MaterialButtonTest', [ + _ExpectedDeclaration.constructor(''), + ]), ], ); _assertHasLibrary( 'package:material_button_testing/material_button_po.dart', declarations: [ - _ExpectedDeclaration.class_('MaterialButtonPO'), + _ExpectedDeclaration.class_('MaterialButtonPO', [ + _ExpectedDeclaration.constructor(''), + ]), ], ); @@ -2005,29 +2340,41 @@ await _doAllTrackerWork(); _assertHasLibrary('package:aaa/a.dart', declarations: [ - _ExpectedDeclaration.class_('A'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasNoLibrary('package:aaa/src/a2.dart'); _assertHasLibrary('package:bbb/b.dart', declarations: [ - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasNoLibrary('package:bbb/src/b2.dart'); _assertHasLibrary('package:ccc/c.dart', declarations: [ - _ExpectedDeclaration.class_('C'), + _ExpectedDeclaration.class_('C', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasNoLibrary('package:ccc/src/c2.dart'); _assertHasLibrary('package:test/t.dart', declarations: [ - _ExpectedDeclaration.class_('T'), + _ExpectedDeclaration.class_('T', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/src/t2.dart', declarations: [ - _ExpectedDeclaration.class_('T2'), + _ExpectedDeclaration.class_('T2', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:basic/s.dart', declarations: [ - _ExpectedDeclaration.class_('S'), + _ExpectedDeclaration.class_('S', [ + _ExpectedDeclaration.constructor(''), + ]), ]); { @@ -2180,23 +2527,35 @@ await _doAllTrackerWork(); _assertHasLibrary('package:aaa/a.dart', declarations: [ - _ExpectedDeclaration.class_('A1'), - _ExpectedDeclaration.class_('A2'), + _ExpectedDeclaration.class_('A1', [ + _ExpectedDeclaration.constructor(''), + ]), + _ExpectedDeclaration.class_('A2', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasNoLibrary('package:aaa/src/a2.dart'); _assertHasLibrary('package:bbb/b.dart', declarations: [ - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/t.dart', declarations: [ - _ExpectedDeclaration.class_('T'), + _ExpectedDeclaration.class_('T', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary('package:test/src/t2.dart', declarations: [ - _ExpectedDeclaration.class_('T2'), + _ExpectedDeclaration.class_('T2', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary( toUriStr('/home/test/test/t3.dart'), declarations: [ - _ExpectedDeclaration.class_('T3'), + _ExpectedDeclaration.class_('T3', [ + _ExpectedDeclaration.constructor(''), + ]), ], ); @@ -2272,7 +2631,9 @@ await _doAllTrackerWork(); _assertHasLibrary(aUri, declarations: [ - _ExpectedDeclaration.class_('A'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasNoLibrary(bUri); @@ -2293,10 +2654,14 @@ await _doAllTrackerWork(); _assertHasLibrary(aUri, declarations: [ - _ExpectedDeclaration.class_('A'), + _ExpectedDeclaration.class_('A', [ + _ExpectedDeclaration.constructor(''), + ]), ]); _assertHasLibrary(bUri, declarations: [ - _ExpectedDeclaration.class_('B'), + _ExpectedDeclaration.class_('B', [ + _ExpectedDeclaration.constructor(''), + ]), ]); // The package can see package:bbb, but not package:aaa @@ -2344,7 +2709,7 @@ } void _assertDeclaration( - Library library, + Declaration declaration, String name, DeclarationKind kind, { String defaultArgumentListString, @@ -2359,7 +2724,6 @@ String locationPath, int locationStartColumn, int locationStartLine, - String name2, String parameters, List<String> parameterNames, List<String> parameterTypes, @@ -2368,7 +2732,6 @@ String returnType, String typeParameters, }) { - var declaration = _getDeclaration(library, name, name2); expect(declaration.defaultArgumentListString, defaultArgumentListString); expect( declaration.defaultArgumentListTextRanges, @@ -2377,7 +2740,6 @@ expect(declaration.docComplete, docComplete); expect(declaration.docSummary, docSummary); expect(declaration.name, name); - expect(declaration.name2, name2); expect(declaration.kind, kind); expect(declaration.isAbstract, isAbstract); expect(declaration.isConst, isConst); @@ -2398,16 +2760,20 @@ } } - void _assertHasDeclaration(Library library, _ExpectedDeclaration expected) { - expect( - library.declarations, - contains(predicate((Declaration d) { - return d.name == expected.name && - d.name2 == expected.name2 && - d.kind == expected.kind; - })), - reason: '$expected', - ); + void _assertHasDeclaration( + List<Declaration> declarations, _ExpectedDeclaration expected) { + var matching = declarations.where((d) { + return d.name == expected.name && d.kind == expected.kind; + }).toList(); + if (matching.length != 1) { + fail('Expected $expected in\n${declarations.join('\n')}'); + } + + var actual = matching.single; + expect(actual.children, hasLength(expected.children.length)); + for (var expectedChild in expected.children) { + _assertHasDeclaration(actual.children, expectedChild); + } } /// Assert that the current state has the library with the given [uri]. @@ -2421,7 +2787,7 @@ if (declarations != null) { expect(library.declarations, hasLength(declarations.length)); for (var expected in declarations) { - _assertHasDeclaration(library, expected); + _assertHasDeclaration(library.declarations, expected); } } } @@ -2430,6 +2796,13 @@ expect(uriToLibrary, isNot(contains(uri))); } + void _assertNoDeclaration(Library library, String name) { + expect( + library.declarations.where((declaration) => declaration.name == name), + isEmpty, + ); + } + void _createTracker() { uriToLibrary.clear(); @@ -2456,9 +2829,8 @@ await pumpEventQueue(); } - Declaration _getDeclaration(Library library, String name, String name2) { - return library.declarations.singleWhere((declaration) => - declaration.name == name && declaration.name2 == name2); + Declaration _getDeclaration(List<Declaration> declarations, String name) { + return declarations.singleWhere((declaration) => declaration.name == name); } Library _getLibrary(String uriStr) { @@ -2471,40 +2843,38 @@ class _ExpectedDeclaration { final DeclarationKind kind; final String name; - final String name2; + final List<_ExpectedDeclaration> children; - _ExpectedDeclaration(this.kind, this.name, this.name2); + _ExpectedDeclaration(this.kind, this.name, {this.children: const []}); - _ExpectedDeclaration.class_(String name) - : this(DeclarationKind.CLASS, name, null); + _ExpectedDeclaration.class_(String name, List<_ExpectedDeclaration> children) + : this(DeclarationKind.CLASS, name, children: children); _ExpectedDeclaration.classTypeAlias(String name) - : this(DeclarationKind.CLASS_TYPE_ALIAS, name, null); + : this(DeclarationKind.CLASS_TYPE_ALIAS, name); - _ExpectedDeclaration.enum_(String name) - : this(DeclarationKind.ENUM, name, null); + _ExpectedDeclaration.constructor(String name) + : this(DeclarationKind.CONSTRUCTOR, name); - _ExpectedDeclaration.enumConstant(String name, String name2) - : this(DeclarationKind.ENUM_CONSTANT, name, name2); + _ExpectedDeclaration.enum_(String name, List<_ExpectedDeclaration> children) + : this(DeclarationKind.ENUM, name, children: children); + + _ExpectedDeclaration.enumConstant(String name) + : this(DeclarationKind.ENUM_CONSTANT, name); _ExpectedDeclaration.function(String name) - : this(DeclarationKind.FUNCTION, name, null); + : this(DeclarationKind.FUNCTION, name); _ExpectedDeclaration.functionTypeAlias(String name) - : this(DeclarationKind.FUNCTION_TYPE_ALIAS, name, null); + : this(DeclarationKind.FUNCTION_TYPE_ALIAS, name); - _ExpectedDeclaration.mixin(String name) - : this(DeclarationKind.MIXIN, name, null); + _ExpectedDeclaration.mixin(String name) : this(DeclarationKind.MIXIN, name); _ExpectedDeclaration.variable(String name) - : this(DeclarationKind.VARIABLE, name, null); + : this(DeclarationKind.VARIABLE, name); @override String toString() { - if (name2 != null) { - return '($kind, $name, $name2)'; - } else { - return '($kind, $name)'; - } + return '($kind, $name)'; } }
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart index ca7d14f..61c752d 100644 --- a/pkg/analyzer/test/src/summary/element_text.dart +++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -551,6 +551,9 @@ buffer.write(e.keyword.lexeme); buffer.write(' '); } + if (withTypes && e.constructorName.type.typeArguments == null) { + writeInterfaceTypeArgsComment(e); + } writeNode(e.constructorName); writeList('(', ')', e.argumentList.arguments, ', ', writeNode, includeEmpty: true);
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart index 2cf841b..16c94d1 100644 --- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart +++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -10,6 +10,7 @@ import 'package:analyzer/src/generated/type_system.dart'; import 'package:analyzer/src/summary/summary_sdk.dart'; import 'package:analyzer/src/summary2/link.dart'; +import 'package:analyzer/src/summary2/linked_bundle_context.dart'; import 'package:analyzer/src/summary2/linked_element_factory.dart'; import 'package:analyzer/src/summary2/reference.dart'; import 'package:test/test.dart'; @@ -175,8 +176,12 @@ null, rootReference, ); - elementFactory.addBundle(dartCoreResult.bundle); - elementFactory.addBundle(linkResult.bundle); + elementFactory.addBundle( + LinkedBundleContext(elementFactory, dartCoreResult.bundle), + ); + elementFactory.addBundle( + LinkedBundleContext(elementFactory, linkResult.bundle), + ); var dartCore = elementFactory.libraryOfUri('dart:core'); var dartAsync = elementFactory.libraryOfUri('dart:async'); @@ -191,6 +196,74 @@ @override @failingTest + test_class_alias_notSimplyBounded_self() async { + await super.test_class_alias_notSimplyBounded_self(); + } + + @override + @failingTest + test_class_notSimplyBounded_circularity_via_typedef() async { + await super.test_class_notSimplyBounded_circularity_via_typedef(); + } + + @override + @failingTest + test_class_notSimplyBounded_complex_by_cycle() async { + await super.test_class_notSimplyBounded_complex_by_cycle(); + } + + @override + @failingTest + test_class_notSimplyBounded_complex_by_reference_to_cycle() async { + await super.test_class_notSimplyBounded_complex_by_reference_to_cycle(); + } + + @override + @failingTest + test_class_notSimplyBounded_complex_by_use_of_parameter() async { + await super.test_class_notSimplyBounded_complex_by_use_of_parameter(); + } + + @override + @failingTest + test_class_notSimplyBounded_dependency_with_type_params() async { + await super.test_class_notSimplyBounded_dependency_with_type_params(); + } + + @override + @failingTest + test_class_notSimplyBounded_function_typed_bound_complex_via_parameter_type() async { + await super + .test_class_notSimplyBounded_function_typed_bound_complex_via_parameter_type(); + } + + @override + @failingTest + test_class_notSimplyBounded_function_typed_bound_complex_via_return_type() async { + await super + .test_class_notSimplyBounded_function_typed_bound_complex_via_return_type(); + } + + @override + @failingTest + test_class_notSimplyBounded_refers_to_circular_typedef() async { + await super.test_class_notSimplyBounded_refers_to_circular_typedef(); + } + + @override + @failingTest + test_class_notSimplyBounded_self() async { + await super.test_class_notSimplyBounded_self(); + } + + @override + @failingTest + test_class_type_parameters_bound() async { + await super.test_class_type_parameters_bound(); + } + + @override + @failingTest test_class_type_parameters_f_bound_complex() async { await super.test_class_type_parameters_f_bound_complex(); } @@ -209,6 +282,12 @@ @override @failingTest + test_closure_in_variable_declaration_in_part() async { + await super.test_closure_in_variable_declaration_in_part(); + } + + @override + @failingTest test_const_constructor_inferred_args() async { await super.test_const_constructor_inferred_args(); } @@ -259,48 +338,193 @@ @override @failingTest + test_constructor_initializers_assertInvocation() async { + await super.test_constructor_initializers_assertInvocation(); + } + + @override + @failingTest + test_constructor_initializers_assertInvocation_message() async { + await super.test_constructor_initializers_assertInvocation_message(); + } + + @override + @failingTest + test_constructor_initializers_field() async { + await super.test_constructor_initializers_field(); + } + + @override + @failingTest + test_constructor_initializers_field_notConst() async { + await super.test_constructor_initializers_field_notConst(); + } + + @override + @failingTest + test_constructor_initializers_field_withParameter() async { + await super.test_constructor_initializers_field_withParameter(); + } + + @override + @failingTest + test_constructor_initializers_superInvocation_named() async { + await super.test_constructor_initializers_superInvocation_named(); + } + + @override + @failingTest + test_constructor_initializers_superInvocation_named_underscore() async { + await super + .test_constructor_initializers_superInvocation_named_underscore(); + } + + @override + @failingTest + test_constructor_initializers_superInvocation_namedExpression() async { + await super.test_constructor_initializers_superInvocation_namedExpression(); + } + + @override + @failingTest + test_constructor_initializers_superInvocation_unnamed() async { + await super.test_constructor_initializers_superInvocation_unnamed(); + } + + @override + @failingTest + test_constructor_initializers_thisInvocation_named() async { + await super.test_constructor_initializers_thisInvocation_named(); + } + + @override + @failingTest + test_constructor_initializers_thisInvocation_namedExpression() async { + await super.test_constructor_initializers_thisInvocation_namedExpression(); + } + + @override + @failingTest + test_constructor_initializers_thisInvocation_unnamed() async { + await super.test_constructor_initializers_thisInvocation_unnamed(); + } + + @override + @failingTest + test_constructor_redirected_factory_named() async { + await super.test_constructor_redirected_factory_named(); + } + + @override + @failingTest test_constructor_redirected_factory_named_generic() async { await super.test_constructor_redirected_factory_named_generic(); } @override @failingTest + test_constructor_redirected_factory_named_imported() async { + await super.test_constructor_redirected_factory_named_imported(); + } + + @override + @failingTest test_constructor_redirected_factory_named_imported_generic() async { await super.test_constructor_redirected_factory_named_imported_generic(); } @override @failingTest + test_constructor_redirected_factory_named_prefixed() async { + await super.test_constructor_redirected_factory_named_prefixed(); + } + + @override + @failingTest test_constructor_redirected_factory_named_prefixed_generic() async { await super.test_constructor_redirected_factory_named_prefixed_generic(); } @override @failingTest + test_constructor_redirected_factory_unnamed() async { + await super.test_constructor_redirected_factory_unnamed(); + } + + @override + @failingTest test_constructor_redirected_factory_unnamed_generic() async { await super.test_constructor_redirected_factory_unnamed_generic(); } @override @failingTest + test_constructor_redirected_factory_unnamed_imported() async { + await super.test_constructor_redirected_factory_unnamed_imported(); + } + + @override + @failingTest test_constructor_redirected_factory_unnamed_imported_generic() async { await super.test_constructor_redirected_factory_unnamed_imported_generic(); } @override @failingTest + test_constructor_redirected_factory_unnamed_prefixed() async { + await super.test_constructor_redirected_factory_unnamed_prefixed(); + } + + @override + @failingTest test_constructor_redirected_factory_unnamed_prefixed_generic() async { await super.test_constructor_redirected_factory_unnamed_prefixed_generic(); } @override @failingTest + test_constructor_redirected_thisInvocation_named() async { + await super.test_constructor_redirected_thisInvocation_named(); + } + + @override + @failingTest + test_constructor_redirected_thisInvocation_named_generic() async { + await super.test_constructor_redirected_thisInvocation_named_generic(); + } + + @override + @failingTest + test_constructor_redirected_thisInvocation_unnamed() async { + await super.test_constructor_redirected_thisInvocation_unnamed(); + } + + @override + @failingTest + test_constructor_redirected_thisInvocation_unnamed_generic() async { + await super.test_constructor_redirected_thisInvocation_unnamed_generic(); + } + + @override + @failingTest + test_constructor_withCycles_const() async { + await super.test_constructor_withCycles_const(); + } + + @override + @failingTest test_defaultValue_genericFunction() async { await super.test_defaultValue_genericFunction(); } @override @failingTest + test_defaultValue_refersToGenericClass() async { + await super.test_defaultValue_refersToGenericClass(); + } + + @override + @failingTest test_defaultValue_refersToGenericClass_constructor() async { await super.test_defaultValue_refersToGenericClass_constructor(); } @@ -337,6 +561,12 @@ @override @failingTest + test_export_class_type_alias() async { + await super.test_export_class_type_alias(); + } + + @override + @failingTest test_export_configurations_useFirst() async { await super.test_export_configurations_useFirst(); } @@ -379,12 +609,24 @@ @override @failingTest + test_futureOr_inferred() async { + await super.test_futureOr_inferred(); + } + + @override + @failingTest test_getter_inferred_type_nonStatic_implicit_return() async { await super.test_getter_inferred_type_nonStatic_implicit_return(); } @override @failingTest + test_implicitConstructor_named_const() async { + await super.test_implicitConstructor_named_const(); + } + + @override + @failingTest test_import_configurations_useFirst() async { await super.test_import_configurations_useFirst(); } @@ -405,6 +647,12 @@ @override @failingTest + test_infer_generic_typedef_complex() async { + await super.test_infer_generic_typedef_complex(); + } + + @override + @failingTest test_infer_generic_typedef_simple() async { await super.test_infer_generic_typedef_simple(); } @@ -435,6 +683,12 @@ @override @failingTest + test_inferred_type_refers_to_function_typed_param_of_typedef() async { + await super.test_inferred_type_refers_to_function_typed_param_of_typedef(); + } + + @override + @failingTest test_inferred_type_refers_to_function_typed_parameter_type_generic_class() async { await super .test_inferred_type_refers_to_function_typed_parameter_type_generic_class(); @@ -456,6 +710,19 @@ @override @failingTest + test_inferred_type_refers_to_nested_function_typed_param() async { + await super.test_inferred_type_refers_to_nested_function_typed_param(); + } + + @override + @failingTest + test_inferred_type_refers_to_nested_function_typed_param_named() async { + await super + .test_inferred_type_refers_to_nested_function_typed_param_named(); + } + + @override + @failingTest test_inferred_type_refers_to_setter_function_typed_parameter_type() async { await super .test_inferred_type_refers_to_setter_function_typed_parameter_type(); @@ -475,6 +742,47 @@ @override @failingTest + test_initializer_executable_with_return_type_from_closure() async { + await super.test_initializer_executable_with_return_type_from_closure(); + } + + @override + @failingTest + test_initializer_executable_with_return_type_from_closure_await_dynamic() async { + await super + .test_initializer_executable_with_return_type_from_closure_await_dynamic(); + } + + @override + @failingTest + test_initializer_executable_with_return_type_from_closure_await_future3_int() async { + await super + .test_initializer_executable_with_return_type_from_closure_await_future3_int(); + } + + @override + @failingTest + test_initializer_executable_with_return_type_from_closure_await_future_int() async { + await super + .test_initializer_executable_with_return_type_from_closure_await_future_int(); + } + + @override + @failingTest + test_initializer_executable_with_return_type_from_closure_await_future_noArg() async { + await super + .test_initializer_executable_with_return_type_from_closure_await_future_noArg(); + } + + @override + @failingTest + test_initializer_executable_with_return_type_from_closure_field() async { + await super + .test_initializer_executable_with_return_type_from_closure_field(); + } + + @override + @failingTest test_instantiateToBounds_boundRefersToEarlierTypeArgument() async { await super.test_instantiateToBounds_boundRefersToEarlierTypeArgument(); } @@ -511,14 +819,14 @@ @override @failingTest - test_invalid_setterParameter_fieldFormalParameter() async { - await super.test_invalid_setterParameter_fieldFormalParameter(); + test_invalid_nameConflict_imported_exported() async { + await super.test_invalid_nameConflict_imported_exported(); } @override @failingTest - test_invalid_setterParameter_fieldFormalParameter_self() async { - await super.test_invalid_setterParameter_fieldFormalParameter_self(); + test_invalid_nameConflict_local() async { + await super.test_invalid_nameConflict_local(); } @override @@ -547,18 +855,6 @@ @override @failingTest - test_metadata_importDirective() async { - await super.test_metadata_importDirective(); - } - - @override - @failingTest - test_metadata_partDirective() async { - await super.test_metadata_partDirective(); - } - - @override - @failingTest test_method_inferred_type_nonStatic_implicit_param() async { await super.test_method_inferred_type_nonStatic_implicit_param(); } @@ -579,6 +875,24 @@ @override @failingTest + test_new_typedef_notSimplyBounded_self() async { + await super.test_new_typedef_notSimplyBounded_self(); + } + + @override + @failingTest + test_old_typedef_notSimplyBounded_self() async { + await super.test_old_typedef_notSimplyBounded_self(); + } + + @override + @failingTest + test_parameter_covariant() async { + await super.test_parameter_covariant(); + } + + @override + @failingTest test_parameter_covariant_inherited() async { await super.test_parameter_covariant_inherited(); } @@ -591,6 +905,12 @@ @override @failingTest + test_setter_covariant() async { + await super.test_setter_covariant(); + } + + @override + @failingTest test_setter_inferred_type_nonStatic_implicit_param() async { await super.test_setter_inferred_type_nonStatic_implicit_param(); } @@ -603,6 +923,24 @@ @override @failingTest + test_syntheticFunctionType_inGenericClass() async { + await super.test_syntheticFunctionType_inGenericClass(); + } + + @override + @failingTest + test_syntheticFunctionType_noArguments() async { + await super.test_syntheticFunctionType_noArguments(); + } + + @override + @failingTest + test_syntheticFunctionType_withArguments() async { + await super.test_syntheticFunctionType_withArguments(); + } + + @override + @failingTest test_type_inference_based_on_loadLibrary() async { await super.test_type_inference_based_on_loadLibrary(); } @@ -627,6 +965,18 @@ @override @failingTest + test_type_inference_nested_function() async { + await super.test_type_inference_nested_function(); + } + + @override + @failingTest + test_type_inference_nested_function_with_parameter_types() async { + await super.test_type_inference_nested_function_with_parameter_types(); + } + + @override + @failingTest test_type_inference_of_closure_with_default_value() async { await super.test_type_inference_of_closure_with_default_value(); } @@ -645,6 +995,47 @@ @override @failingTest + test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_included() async { + await super + .test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_included(); + } + + @override + @failingTest + test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_omitted() async { + await super + .test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_omitted(); + } + + @override + @failingTest + test_typedef_notSimplyBounded_dependency_via_param_type_old_style() async { + await super + .test_typedef_notSimplyBounded_dependency_via_param_type_old_style(); + } + + @override + @failingTest + test_typedef_notSimplyBounded_dependency_via_return_type_new_style() async { + await super + .test_typedef_notSimplyBounded_dependency_via_return_type_new_style(); + } + + @override + @failingTest + test_typedef_notSimplyBounded_dependency_via_return_type_old_style() async { + await super + .test_typedef_notSimplyBounded_dependency_via_return_type_old_style(); + } + + @override + @failingTest + test_typedef_type_parameters_bound() async { + await super.test_typedef_type_parameters_bound(); + } + + @override + @failingTest test_typedef_type_parameters_bound_recursive() async { await super.test_typedef_type_parameters_bound_recursive(); } @@ -675,6 +1066,12 @@ @override @failingTest + test_unresolved_annotation_instanceCreation_argument_super() async { + await super.test_unresolved_annotation_instanceCreation_argument_super(); + } + + @override + @failingTest test_unresolved_export() async { await super.test_unresolved_export(); } @@ -687,6 +1084,12 @@ @override @failingTest + test_unused_type_parameter() async { + await super.test_unused_type_parameter(); + } + + @override + @failingTest test_variable_propagatedType_final_dep_inLib() async { await super.test_variable_propagatedType_final_dep_inLib(); }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart index de84750..40b6c41 100644 --- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart +++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -40,6 +40,12 @@ @override @failingTest + test_defaultValue_refersToGenericClass() async { + await super.test_defaultValue_refersToGenericClass(); + } + + @override + @failingTest test_syntheticFunctionType_inGenericClass() async { await super.test_syntheticFunctionType_inGenericClass(); }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart index b8f7ab6..77b78c1 100644 --- a/pkg/analyzer/test/src/summary/resynthesize_common.dart +++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -345,6 +345,61 @@ '''); } + test_class_alias_notSimplyBounded_self() async { + var library = await checkLibrary(''' +class C<T extends C> = D with E; +class D {} +class E {} +'''); + checkElementText(library, r''' +notSimplyBounded class alias C<T extends C<dynamic>> extends D with E { + synthetic C() = D; +} +class D { +} +class E { +} +'''); + } + + test_class_alias_notSimplyBounded_simple_no_type_parameter_bound() async { + // If no bounds are specified, then the class is simply bounded by syntax + // alone, so there is no reason to assign it a slot. + var library = await checkLibrary(''' +class C<T> = D with E; +class D {} +class E {} +'''); + checkElementText(library, r''' +class alias C<T> extends D with E { + synthetic C() = D; +} +class D { +} +class E { +} +'''); + } + + test_class_alias_notSimplyBounded_simple_non_generic() async { + // If no type parameters are specified, then the class is simply bounded, so + // there is no reason to assign it a slot. + var library = await checkLibrary(''' +class C = D with E; +class D {} +class E {} +'''); + checkElementText(library, r''' +class alias C extends D with E { + synthetic C() = D; +} +class D { +} +class E { +} +'''); + } + test_class_alias_with_forwarding_constructors() async { addLibrarySource('/a.dart', ''' class Base { @@ -1185,6 +1240,180 @@ '''); } + test_class_notSimplyBounded_circularity_via_typedef() async { + // C's type parameter T is not simply bounded because its bound, F, expands + // to `dynamic F(C)`, which refers to C. + var library = await checkLibrary(''' +class C<T extends F> {} +typedef F(C value); +'''); + checkElementText(library, r''' +notSimplyBounded typedef F = dynamic Function(C<dynamic> value); +notSimplyBounded class C<T extends (C<dynamic>) → dynamic> { +} +'''); + } + + test_class_notSimplyBounded_circularity_with_type_params() async { + // C's type parameter T is simply bounded because even though it refers to + // C, it specifies a bound. + var library = await checkLibrary(''' +class C<T extends C<dynamic>> {} +'''); + checkElementText(library, r''' +class C<T extends C<dynamic>> { +} +'''); + } + + test_class_notSimplyBounded_complex_by_cycle() async { + var library = await checkLibrary(''' +class C<T extends D> {} +class D<T extends C> {} +'''); + checkElementText(library, r''' +notSimplyBounded class C<T extends D<dynamic>> { +} +notSimplyBounded class D<T extends C<D<dynamic>>> { +} +'''); + } + + test_class_notSimplyBounded_complex_by_reference_to_cycle() async { + var library = await checkLibrary(''' +class C<T extends D> {} +class D<T extends D> {} +'''); + checkElementText(library, r''' +notSimplyBounded class C<T extends D<dynamic>> { +} +notSimplyBounded class D<T extends D<dynamic>> { +} +'''); + } + + test_class_notSimplyBounded_complex_by_use_of_parameter() async { + var library = await checkLibrary(''' +class C<T extends D<T>> {} +class D<T> {} +'''); + checkElementText(library, r''' +notSimplyBounded class C<T extends D<T>> { +} +class D<T> { +} +'''); + } + + test_class_notSimplyBounded_dependency_with_type_params() async { + // C's type parameter T is simply bounded because even though it refers to + // non-simply-bounded type D, it specifies a bound. + var library = await checkLibrary(''' +class C<T extends D<dynamic>> {} +class D<T extends D<T>> {} +'''); + checkElementText(library, r''' +class C<T extends D<dynamic>> { +} +notSimplyBounded class D<T extends D<T>> { +} +'''); + } + + test_class_notSimplyBounded_function_typed_bound_complex_via_parameter_type() async { + var library = await checkLibrary(''' +class C<T extends void Function(T)> {} +'''); + checkElementText(library, r''' +notSimplyBounded class C<T extends (T) → void> { +} +'''); + } + + test_class_notSimplyBounded_function_typed_bound_complex_via_return_type() async { + var library = await checkLibrary(''' +class C<T extends T Function()> {} +'''); + checkElementText(library, r''' +notSimplyBounded class C<T extends () → T> { +} +'''); + } + + test_class_notSimplyBounded_function_typed_bound_simple() async { + var library = await checkLibrary(''' +class C<T extends void Function()> {} +'''); + checkElementText(library, r''' +class C<T extends () → void> { +} +'''); + } + + test_class_notSimplyBounded_refers_to_circular_typedef() async { + // C's type parameter T has a bound of F, which is a circular typedef. This + // is illegal in Dart, but we need to make sure it doesn't lead to a crash + // or infinite loop. + var library = await checkLibrary(''' +class C<T extends F> {} +typedef F(G value); +typedef G(F value); +'''); + checkElementText(library, r''' +notSimplyBounded typedef F = dynamic Function(((...) → dynamic) → dynamic value); +notSimplyBounded typedef G = dynamic Function(((...) → dynamic) → dynamic value); +notSimplyBounded class C<T extends ((...) → dynamic) → dynamic> { +} +'''); + } + + test_class_notSimplyBounded_self() async { + var library = await checkLibrary(''' +class C<T extends C> {} +'''); + checkElementText(library, r''' +notSimplyBounded class C<T extends C<dynamic>> { +} +'''); + } + + test_class_notSimplyBounded_simple_because_non_generic() async { + // If no type parameters are specified, then the class is simply bounded, so + // there is no reason to assign it a slot. + var library = await checkLibrary(''' +class C {} +'''); + checkElementText(library, r''' +class C { +} +'''); + } + + test_class_notSimplyBounded_simple_by_lack_of_cycles() async { + var library = await checkLibrary(''' +class C<T extends D> {} +class D<T> {} +'''); + checkElementText(library, r''' +class C<T extends D<dynamic>> { +} +class D<T> { +} +'''); + } + + test_class_notSimplyBounded_simple_by_syntax() async { + // If no bounds are specified, then the class is simply bounded by syntax + // alone, so there is no reason to assign it a slot. + var library = await checkLibrary(''' +class C<T> {} +'''); + checkElementText(library, r''' +class C<T> { +} +'''); + } + test_class_setter_abstract() async { var library = await checkLibrary('abstract class C { void set x(int value); }'); @@ -4527,6 +4756,29 @@ '''); } + test_defaultValue_refersToGenericClass() async { + var library = await checkLibrary(''' +class B<T1, T2> { + const B(); +} +class C { + void foo([B<int, double> b = const B()]) {} +} +'''); + checkElementText( + library, + r''' +class B<T1, T2> { + const B(); +} +class C { + void foo([B<int, double> b = const /*typeArgs=int,double*/ + B/*location: test.dart;B*/()]) {} +} +''', + withTypes: true); + } + test_defaultValue_refersToGenericClass_constructor() async { var library = await checkLibrary(''' class B<T> { @@ -4536,7 +4788,21 @@ const C([B<T> b = const B()]); } '''); - checkElementText(library, r''' + if (isAstBasedSummary) { + checkElementText( + library, + r''' +class B<T> { + const B(); +} +class C<T> { + const C([B<T> b = const /*typeArgs=Null*/ + B/*location: test.dart;B*/()]); +} +''', + withTypes: true); + } else { + checkElementText(library, r''' class B<T> { const B(); } @@ -4545,6 +4811,7 @@ B/*location: test.dart;B*/()]); } '''); + } } test_defaultValue_refersToGenericClass_constructor2() async { @@ -4557,7 +4824,23 @@ const C([A<T> a = const B()]); } '''); - checkElementText(library, r''' + if (isAstBasedSummary) { + checkElementText( + library, + r''' +abstract class A<T> { +} +class B<T> implements A<T> { + const B(); +} +class C<T> implements A<Iterable<T>> { + const C([A<T> a = const /*typeArgs=Null*/ + B/*location: test.dart;B*/()]); +} +''', + withTypes: true); + } else { + checkElementText(library, r''' abstract class A<T> { } class B<T> implements A<T> { @@ -4568,6 +4851,7 @@ B/*location: test.dart;B*/()]); } '''); + } } test_defaultValue_refersToGenericClass_functionG() async { @@ -4577,13 +4861,26 @@ } void foo<T>([B<T> b = const B()]) {} '''); - checkElementText(library, r''' + if (isAstBasedSummary) { + checkElementText( + library, + r''' +class B<T> { + const B(); +} +void foo<T>([B<T> b = const /*typeArgs=Null*/ + B/*location: test.dart;B*/()]) {} +''', + withTypes: true); + } else { + checkElementText(library, r''' class B<T> { const B(); } void foo<T>([B<T> b = const B/*location: test.dart;B*/()]) {} '''); + } } test_defaultValue_refersToGenericClass_methodG() async { @@ -4595,7 +4892,21 @@ void foo<T>([B<T> b = const B()]) {} } '''); - checkElementText(library, r''' + if (isAstBasedSummary) { + checkElementText( + library, + r''' +class B<T> { + const B(); +} +class C { + void foo<T>([B<T> b = const /*typeArgs=Null*/ + B/*location: test.dart;B*/()]) {} +} +''', + withTypes: true); + } else { + checkElementText(library, r''' class B<T> { const B(); } @@ -4604,6 +4915,7 @@ B/*location: test.dart;B*/()]) {} } '''); + } } test_defaultValue_refersToGenericClass_methodG_classG() async { @@ -4615,7 +4927,21 @@ void foo<E2>([B<E1, E2> b = const B()]) {} } '''); - checkElementText(library, r''' + if (isAstBasedSummary) { + checkElementText( + library, + r''' +class B<T1, T2> { + const B(); +} +class C<E1> { + void foo<E2>([B<E1, E2> b = const /*typeArgs=Null,Null*/ + B/*location: test.dart;B*/()]) {} +} +''', + withTypes: true); + } else { + checkElementText(library, r''' class B<T1, T2> { const B(); } @@ -4624,6 +4950,7 @@ B/*location: test.dart;B*/()]) {} } '''); + } } test_defaultValue_refersToGenericClass_methodNG() async { @@ -4635,7 +4962,21 @@ void foo([B<T> b = const B()]) {} } '''); - checkElementText(library, r''' + if (isAstBasedSummary) { + checkElementText( + library, + r''' +class B<T> { + const B(); +} +class C<T> { + void foo([B<T> b = const /*typeArgs=Null*/ + B/*location: test.dart;B*/()]) {} +} +''', + withTypes: true); + } else { + checkElementText(library, r''' class B<T> { const B(); } @@ -4644,6 +4985,7 @@ B/*location: test.dart;B*/()]) {} } '''); + } } test_enum_documented() async { @@ -6616,11 +6958,19 @@ import 'c.dart'; foo([p = V]) {} '''); - checkElementText(library, r''' + if (isAstBasedSummary) { + checkElementText(library, r''' +import 'c.dart'; +dynamic foo([dynamic p = + V/*location: a.dart;V*/]) {} +'''); + } else { + checkElementText(library, r''' import 'c.dart'; dynamic foo([dynamic p = V/*location: null*/]) {} '''); + } } test_invalid_nameConflict_local() async { @@ -6629,12 +6979,21 @@ V() {} var V; '''); - checkElementText(library, r''' + if (isAstBasedSummary) { + checkElementText(library, r''' +dynamic V; +dynamic foo([dynamic p = + V/*location: test.dart;V?*/]) {} +dynamic V() {} +'''); + } else { + checkElementText(library, r''' dynamic V; dynamic foo([dynamic p = V/*location: null*/]) {} dynamic V() {} '''); + } } test_invalid_setterParameter_fieldFormalParameter() async { @@ -7824,6 +8183,58 @@ '''); } + test_new_typedef_notSimplyBounded_self() async { + var library = await checkLibrary(''' +typedef F<T extends F> = void Function(); +'''); + checkElementText(library, r''' +notSimplyBounded typedef F<T extends () → void> = void Function(); +'''); + } + + test_new_typedef_notSimplyBounded_simple_no_bounds() async { + var library = await checkLibrary(''' +typedef F<T> = void Function(); +'''); + checkElementText(library, r''' +typedef F<T> = void Function(); +'''); + } + + test_new_typedef_notSimplyBounded_simple_non_generic() async { + var library = await checkLibrary(''' +typedef F = void Function(); +'''); + checkElementText(library, r''' +typedef F = void Function(); +'''); + } + + test_old_typedef_notSimplyBounded_self() async { + var library = await checkLibrary(''' +typedef void F<T extends F>(); +'''); + checkElementText(library, r''' +notSimplyBounded typedef F<T extends () → void> = void Function(); +'''); + } + + test_old_typedef_notSimplyBounded_simple_because_non_generic() async { + var library = await checkLibrary(''' +typedef void F(); +'''); + checkElementText(library, r''' +typedef F = void Function(); +'''); + } + + test_old_typedef_notSimplyBounded_simple_no_bounds() async { + var library = await checkLibrary('typedef void F<T>();'); + checkElementText(library, r''' +typedef F<T> = void Function(); +'''); + } + test_operator() async { var library = await checkLibrary('class C { C operator+(C other) => null; }'); @@ -8814,6 +9225,76 @@ '''); } + test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_included() async { + // F is considered "not simply bounded" because it expands to a type that + // refers to C, which is not simply bounded. + var library = await checkLibrary(''' +typedef F = void Function(C c); +class C<T extends C<T>> {} +'''); + checkElementText(library, r''' +notSimplyBounded typedef F = void Function(C<C<dynamic>> c); +notSimplyBounded class C<T extends C<T>> { +} +'''); + } + + test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_omitted() async { + // F is considered "not simply bounded" because it expands to a type that + // refers to C, which is not simply bounded. + var library = await checkLibrary(''' +typedef F = void Function(C); +class C<T extends C<T>> {} +'''); + checkElementText(library, r''' +notSimplyBounded typedef F = void Function(C<C<dynamic>> ); +notSimplyBounded class C<T extends C<T>> { +} +'''); + } + + test_typedef_notSimplyBounded_dependency_via_param_type_old_style() async { + // F is considered "not simply bounded" because it expands to a type that + // refers to C, which is not simply bounded. + var library = await checkLibrary(''' +typedef void F(C c); +class C<T extends C<T>> {} +'''); + checkElementText(library, r''' +notSimplyBounded typedef F = void Function(C<C<dynamic>> c); +notSimplyBounded class C<T extends C<T>> { +} +'''); + } + + test_typedef_notSimplyBounded_dependency_via_return_type_new_style() async { + // F is considered "not simply bounded" because it expands to a type that + // refers to C, which is not simply bounded. + var library = await checkLibrary(''' +typedef F = C Function(); +class C<T extends C<T>> {} +'''); + checkElementText(library, r''' +notSimplyBounded typedef F = C<C<dynamic>> Function(); +notSimplyBounded class C<T extends C<T>> { +} +'''); + } + + test_typedef_notSimplyBounded_dependency_via_return_type_old_style() async { + // F is considered "not simply bounded" because it expands to a type that + // refers to C, which is not simply bounded. + var library = await checkLibrary(''' +typedef C F(); +class C<T extends C<T>> {} +'''); + checkElementText(library, r''' +notSimplyBounded typedef F = C<C<dynamic>> Function(); +notSimplyBounded class C<T extends C<T>> { +} +'''); + } + test_typedef_parameter_parameters() async { var library = await checkLibrary('typedef F(g(x, y));'); checkElementText(library, r'''
diff --git a/pkg/analyzer/test/src/summary/top_level_inference_test.dart b/pkg/analyzer/test/src/summary/top_level_inference_test.dart index b4d8961..77990a8 100644 --- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart +++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
@@ -33,9 +33,6 @@ @reflectiveTest class TopLevelInferenceErrorsTest extends AbstractStrongTest { - @override - bool get enableNewAnalysisDriver => true; - test_initializer_additive() async { await _assertErrorOnlyLeft(['+', '-']); }
diff --git a/pkg/analyzer/test/src/summary2/ast_binary_writer_integration_test.dart b/pkg/analyzer/test/src/summary2/ast_binary_writer_integration_test.dart index efe0133..e79a3a7 100644 --- a/pkg/analyzer/test/src/summary2/ast_binary_writer_integration_test.dart +++ b/pkg/analyzer/test/src/summary2/ast_binary_writer_integration_test.dart
@@ -6,6 +6,7 @@ import 'package:analyzer/file_system/physical_file_system.dart'; import 'package:analyzer/source/line_info.dart'; +import 'package:analyzer/src/summary/format.dart'; import 'package:analyzer/src/summary/idl.dart'; import 'package:analyzer/src/summary2/ast_binary_reader.dart'; import 'package:analyzer/src/summary2/ast_binary_writer.dart'; @@ -15,7 +16,6 @@ import 'package:analyzer/src/summary2/linked_unit_context.dart'; import 'package:analyzer/src/summary2/linking_bundle_context.dart'; import 'package:analyzer/src/summary2/reference.dart'; -import 'package:analyzer/src/summary2/tokens_context.dart'; import 'package:analyzer/src/summary2/tokens_writer.dart'; import 'package:front_end/src/testing/package_root.dart' as package_root; import 'package:test/test.dart'; @@ -41,9 +41,7 @@ code = code.replaceAll('\r', '\n'); LineInfo lineInfo; - LinkedNodeReferences nodeReferences; - UnlinkedTokens unlinkedTokens; - LinkedNode unitLinkedNode; + LinkedNodeUnit linkedNodeUnit; { var path = base.newFile('/home/test/lib/test.dart', content: code).path; @@ -73,22 +71,31 @@ var linkingBundleContext = LinkingBundleContext(dynamicRef); var writer = new AstBinaryWriter(linkingBundleContext, tokensContext); - unitLinkedNode = writer.writeNode(originalUnit); + var unitLinkedNode = writer.writeNode(originalUnit); - unlinkedTokens = tokensResult.tokens; - nodeReferences = linkingBundleContext.referencesBuilder; + linkedNodeUnit = LinkedNodeUnitBuilder( + node: unitLinkedNode, + tokens: tokensResult.tokens, + ); } var rootReference = Reference.root(); var bundleContext = LinkedBundleContext( LinkedElementFactory(null, null, rootReference), - nodeReferences, + LinkedNodeBundleBuilder( + references: LinkedNodeReferencesBuilder(name: ['']), + ), ); - var tokensContext = TokensContext(unlinkedTokens); - var unitContext = LinkedUnitContext(bundleContext, tokensContext); + var unitContext = LinkedUnitContext( + bundleContext, + null, + 0, + null, + linkedNodeUnit, + ); var reader = AstBinaryReader(unitContext); - var deserializedUnit = reader.readNode(unitLinkedNode); + var deserializedUnit = reader.readNode(linkedNodeUnit.node); var buffer = StringBuffer(); deserializedUnit.accept(
diff --git a/pkg/analyzer/test/src/summary2/ast_binary_writer_test.dart b/pkg/analyzer/test/src/summary2/ast_binary_writer_test.dart index 53f650d..e23f4c1 100644 --- a/pkg/analyzer/test/src/summary2/ast_binary_writer_test.dart +++ b/pkg/analyzer/test/src/summary2/ast_binary_writer_test.dart
@@ -4,6 +4,7 @@ import 'package:analyzer/src/dart/analysis/experiments.dart'; import 'package:analyzer/src/generated/engine.dart'; +import 'package:analyzer/src/summary/format.dart'; import 'package:analyzer/src/summary2/ast_binary_reader.dart'; import 'package:analyzer/src/summary2/ast_binary_writer.dart'; import 'package:analyzer/src/summary2/linked_bundle_context.dart'; @@ -142,9 +143,20 @@ var bundleContext = LinkedBundleContext( LinkedElementFactory(null, null, rootReference), - linkingBundleContext.referencesBuilder, + LinkedNodeBundleBuilder( + references: LinkedNodeReferencesBuilder(name: ['']), + ), ); - var unitContext = LinkedUnitContext(bundleContext, tokensContext); + var unitContext = LinkedUnitContext( + bundleContext, + null, + 0, + null, + LinkedNodeUnitBuilder( + node: builder, + tokens: tokensResult.tokens, + ), + ); var reader = AstBinaryReader(unitContext); var deserializedUnit = reader.readNode(builder);
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart index 93af17b..5aef022 100644 --- a/pkg/analyzer/test/src/task/options_test.dart +++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -125,6 +125,24 @@ List<String> names = analysisOptions.enabledPluginNames; expect(names, ['angular2']); } + + test_configure_chromeos_checks() { + configureContext(''' +analyzer: + optional-checks: + chrome-os-manifest-checks +'''); + expect(true, analysisOptions.chromeOsManifestChecks); + } + + test_configure_chromeos_checks_map() { + configureContext(''' +analyzer: + optional-checks: + chrome-os-manifest-checks : true +'''); + expect(true, analysisOptions.chromeOsManifestChecks); + } } @reflectiveTest @@ -463,6 +481,22 @@ ''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE]); } + test_chromeos_manifest_checks() { + validate(''' +analyzer: + optional-checks: + chrome-os-manifest-checks +''', []); + } + + test_chromeos_manifest_checks_invalid() { + validate(''' +analyzer: + optional-checks: + chromeos-manifest +''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE]); + } + void validate(String source, List<ErrorCode> expected) { var options = optionsProvider.getOptionsFromString(source); var errors = validator.validate(options);
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart index 972e5ad..49432eb 100644 --- a/pkg/analyzer/test/src/task/strong/checker_test.dart +++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/dart/analysis/experiments.dart'; +import 'package:analyzer/src/test_utilities/package_mixin.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import 'strong_test_helper.dart'; @@ -15,10 +16,7 @@ } @reflectiveTest -class CheckerTest extends AbstractStrongTest { - @override - bool get enableNewAnalysisDriver => true; - +class CheckerTest extends AbstractStrongTest with PackageMixin { test_awaitForInCastsStreamElementToVariable() async { await checkFile(''' import 'dart:async'; @@ -375,7 +373,6 @@ '''); } - @failingTest // See dartbug.com/32918 test_constantGenericTypeArg_infer() async { // Regression test for https://github.com/dart-lang/sdk/issues/26141 await checkFile(''' @@ -3774,11 +3771,7 @@ } test_strictRawTypes_classes_optionalTypeArgs() async { - addFile(r''' -class _OptionalTypeArgs { const _OptionalTypeArgs(); } -const optionalTypeArgs = _OptionalTypeArgs(); - ''', name: 'package:meta/meta.dart'); - + addMetaPackage(); addFile(r''' import 'package:meta/meta.dart'; @optionalTypeArgs @@ -3864,11 +3857,7 @@ } test_strictRawTypes_typedefs_optionalTypeArgs() async { - addFile(r''' -class _OptionalTypeArgs { const _OptionalTypeArgs(); } -const optionalTypeArgs = _OptionalTypeArgs(); - ''', name: 'package:meta/meta.dart'); - + addMetaPackage(); addFile(r''' import 'package:meta/meta.dart'; @@ -4520,9 +4509,6 @@ List<String> get enabledExperiments => [EnableString.spread_collections, EnableString.control_flow_collections]; - @override - bool get enableNewAnalysisDriver => true; - test_list_ifElement_dynamicCondition_disableImplicitCasts() async { addFile(r''' dynamic c; @@ -4997,7 +4983,7 @@ @failingTest test_spread_dynamicInList_disableImplicitCasts() async { - // TODO(mfairhurst) fix this, see https://github.com/dart-lang/sdk/issues/35569 + // TODO(mfairhurst) fix this, see https://github.com/dart-lang/sdk/issues/36267 addFile(r''' dynamic dyn; void main() { @@ -5019,7 +5005,7 @@ @failingTest test_spread_dynamicInMap_disableImplicitCasts() async { - // TODO(mfairhurst) fix this, see https://github.com/dart-lang/sdk/issues/35569 + // TODO(mfairhurst) fix this, see https://github.com/dart-lang/sdk/issues/36267 addFile(r''' dynamic dyn; void main() { @@ -5041,7 +5027,7 @@ @failingTest test_spread_dynamicInSet_disableImplicitCasts() async { - // TODO(mfairhurst) fix this, see https://github.com/dart-lang/sdk/issues/35569 + // TODO(mfairhurst) fix this, see https://github.com/dart-lang/sdk/issues/36267 addFile(r''' dynamic dyn; void main() {
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart index a6da936..4a036db 100644 --- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart +++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -4393,9 +4393,6 @@ @reflectiveTest class InferredTypeTest extends AbstractStrongTest with InferredTypeMixin { @override - bool get enableNewAnalysisDriver => true; - - @override bool get hasExtraTaskModelPass => false; @override @@ -4426,9 +4423,6 @@ class InferredTypeTest_SetLiterals extends AbstractStrongTest with InferredTypeMixin { @override - bool get enableNewAnalysisDriver => true; - - @override bool get hasExtraTaskModelPass => false; @override
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart index 9589973..7ea6be3 100644 --- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart +++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -12,7 +12,6 @@ import 'package:analyzer/dart/ast/token.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/error/error.dart'; -import 'package:analyzer/error/listener.dart'; import 'package:analyzer/file_system/file_system.dart'; import 'package:analyzer/file_system/memory_file_system.dart'; import 'package:analyzer/source/error_processor.dart'; @@ -25,6 +24,7 @@ import 'package:analyzer/src/file_system/file_system.dart'; import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/generated/source.dart'; +import 'package:analyzer/src/source/package_map_resolver.dart'; import 'package:analyzer/src/test_utilities/mock_sdk.dart'; import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart'; import 'package:source_span/source_span.dart'; @@ -78,7 +78,7 @@ } void _expectErrors(AnalysisOptions analysisOptions, CompilationUnit unit, - List<AnalysisError> actualErrors) { + Iterable<AnalysisError> actualErrors) { var expectedErrors = _findExpectedErrors(unit.beginToken); var actualMap = new SplayTreeMap<int, List<AnalysisError>>(); @@ -245,7 +245,7 @@ List<String> get enabledExperiments => []; - bool get enableNewAnalysisDriver => false; + Map<String, List<Folder>> packageMap; /// Adds a file to check. The file should contain: /// @@ -297,43 +297,48 @@ var mockSdk = new MockSdk(resourceProvider: resourceProvider); mockSdk.context.analysisOptions = analysisOptions; - SourceFactory sourceFactory; - { - var uriResolver = new _TestUriResolver(resourceProvider); - sourceFactory = - new SourceFactory([new DartUriResolver(mockSdk), uriResolver]); - } + SourceFactory sourceFactory = new SourceFactory([ + new DartUriResolver(mockSdk), + new PackageMapUriResolver(resourceProvider, packageMap), + new ResourceUriResolver(resourceProvider), + ]); CompilationUnit mainUnit; - if (enableNewAnalysisDriver) { - StringBuffer logBuffer = new StringBuffer(); - FileContentOverlay fileContentOverlay = new FileContentOverlay(); - PerformanceLog log = new PerformanceLog(logBuffer); - AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(log); - _driver = new AnalysisDriver( - scheduler, - log, - resourceProvider, - new MemoryByteStore(), - fileContentOverlay, - null, - sourceFactory, - analysisOptions); - scheduler.start(); + StringBuffer logBuffer = new StringBuffer(); + FileContentOverlay fileContentOverlay = new FileContentOverlay(); + PerformanceLog log = new PerformanceLog(logBuffer); + AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(log); + _driver = new AnalysisDriver( + scheduler, + log, + resourceProvider, + new MemoryByteStore(), + fileContentOverlay, + null, + sourceFactory, + analysisOptions); + scheduler.start(); - mainUnit = (await _driver.getResult(mainFile.path)).unit; - } else { - _context = AnalysisEngine.instance.createAnalysisContext(); - _context.analysisOptions = analysisOptions; - _context.sourceFactory = sourceFactory; + mainUnit = (await _driver.getResult(mainFile.path)).unit; - // Run the checker on /main.dart. - Source mainSource = sourceFactory.forUri2(mainFile.toUri()); - mainUnit = _context.resolveCompilationUnit2(mainSource, mainSource); + bool isRelevantError(AnalysisError error) { + var code = error.errorCode; + // We don't care about these. + if (code == HintCode.UNUSED_ELEMENT || + code == HintCode.UNUSED_FIELD || + code == HintCode.UNUSED_IMPORT || + code == HintCode.UNUSED_LOCAL_VARIABLE || + code == TodoCode.TODO) { + return false; + } + if (strictRawTypes) { + // When testing strict-raw-types, ignore anything else. + return code.errorSeverity.ordinal > ErrorSeverity.INFO.ordinal || + code == HintCode.STRICT_RAW_TYPE; + } + return true; } - var collector = new _ErrorCollector(analysisOptions); - // Extract expectations from the comments in the test files, and // check that all errors we emit are included in the expected map. LibraryElement mainLibrary = @@ -341,9 +346,6 @@ Set<LibraryElement> allLibraries = _reachableLibraries(mainLibrary); for (LibraryElement library in allLibraries) { for (CompilationUnitElement unit in library.units) { - var errors = <AnalysisError>[]; - collector.errors = errors; - var source = unit.source; if (source.uri.scheme == 'dart') { continue; @@ -351,18 +353,8 @@ var analysisResult = await _resolve(source); - errors.addAll(analysisResult.errors.where((e) => - // We don't care about any of these: - e.errorCode != HintCode.UNUSED_ELEMENT && - e.errorCode != HintCode.UNUSED_FIELD && - e.errorCode != HintCode.UNUSED_IMPORT && - e.errorCode != HintCode.UNUSED_LOCAL_VARIABLE && - e.errorCode != TodoCode.TODO && - // If testing strict-raw-types, ignore other (unrelated) hints. - (!strictRawTypes || - e.errorCode.errorSeverity.ordinal > - ErrorSeverity.INFO.ordinal || - e.errorCode == HintCode.STRICT_RAW_TYPE))); + Iterable<AnalysisError> errors = + analysisResult.errors.where(isRelevantError); _expectErrors(analysisOptions, analysisResult.unit, errors); } } @@ -382,7 +374,11 @@ ); } - void setUp() {} + void setUp() { + packageMap = { + 'meta': [getFolder('/.pub-cache/meta/lib')], + }; + } void tearDown() { // This is a sanity check, in case only addFile is called. @@ -393,31 +389,8 @@ } Future<_TestAnalysisResult> _resolve(Source source) async { - if (enableNewAnalysisDriver) { - var result = await _driver.getResult(source.fullName); - return new _TestAnalysisResult(source, result.unit, result.errors); - } else { - List<Source> libraries = _context.getLibrariesContaining(source); - var unit = _context.resolveCompilationUnit2(source, libraries.single); - var errors = _context.computeErrors(source); - return new _TestAnalysisResult(source, unit, errors); - } - } -} - -class _ErrorCollector implements AnalysisErrorListener { - final AnalysisOptions analysisOptions; - List<AnalysisError> errors; - final bool hints; - - _ErrorCollector(this.analysisOptions, {this.hints: true}); - - void onError(AnalysisError error) { - // Unless DDC hints are requested, filter them out. - var HINT = ErrorSeverity.INFO.ordinal; - if (hints || _errorSeverity(analysisOptions, error).ordinal > HINT) { - errors.add(error); - } + var result = await _driver.getResult(source.fullName); + return new _TestAnalysisResult(source, result.unit, result.errors); } } @@ -471,20 +444,3 @@ final List<AnalysisError> errors; _TestAnalysisResult(this.source, this.unit, this.errors); } - -class _TestUriResolver extends ResourceUriResolver { - final MemoryResourceProvider provider; - _TestUriResolver(provider) - : provider = provider, - super(provider); - - @override - Source resolveAbsolute(Uri uri, [Uri actualUri]) { - if (uri.scheme == 'package') { - return (provider.getResource( - provider.convertPath('/packages/' + uri.path)) as File) - .createSource(uri); - } - return super.resolveAbsolute(uri, actualUri); - } -}
diff --git a/pkg/analyzer/test/src/test_all.dart b/pkg/analyzer/test/src/test_all.dart index 90a00db..80fbf6b 100644 --- a/pkg/analyzer/test/src/test_all.dart +++ b/pkg/analyzer/test/src/test_all.dart
@@ -12,6 +12,7 @@ import 'fasta/test_all.dart' as fasta; import 'hint/test_all.dart' as hint; import 'lint/test_all.dart' as lint; +import 'manifest/test_all.dart' as manifest; import 'options/test_all.dart' as options; import 'pubspec/test_all.dart' as pubspec; import 'services/test_all.dart' as services; @@ -32,6 +33,7 @@ fasta.main(); hint.main(); lint.main(); + manifest.main(); options.main(); pubspec.main(); services.main();
diff --git a/pkg/analyzer/test/src/workspace/gn_test.dart b/pkg/analyzer/test/src/workspace/gn_test.dart index 8cd0a5b..5d15441 100644 --- a/pkg/analyzer/test/src/workspace/gn_test.dart +++ b/pkg/analyzer/test/src/workspace/gn_test.dart
@@ -42,8 +42,7 @@ newFolder('/workspace/some/code'); newFile('/workspace/some/code/pubspec.yaml'); String buildDir = convertPath('out/debug-x87_128'); - newFile('/workspace/.config', - content: 'FOO=foo\n' + 'FUCHSIA_BUILD_DIR="$buildDir"\n' + 'BAR=bar\n'); + newFile('/workspace/.fx-build-dir', content: '$buildDir\n'); newFile('/workspace/out/debug-x87_128/dartlang/gen/some/code/foo.packages'); GnWorkspace workspace = GnWorkspace.find(resourceProvider, convertPath('/workspace/some/code')); @@ -56,8 +55,7 @@ newFolder('/workspace/some/code'); newFile('/workspace/some/code/pubspec.yaml'); String buildDir = convertPath('out/debug-x87_128'); - newFile('/workspace/.config', - content: 'FOO=foo\n' + 'FUCHSIA_BUILD_DIR="$buildDir"\n' + 'BAR=bar\n'); + newFile('/workspace/.fx-build-dir', content: '$buildDir\n'); String packageLocation = convertPath('/workspace/this/is/the/package'); Uri packageUri = resourceProvider.pathContext.toUri(packageLocation); newFile('/workspace/out/debug-x87_128/dartlang/gen/some/code/foo.packages', @@ -75,8 +73,7 @@ newFolder('/workspace/some/code'); newFile('/workspace/some/code/pubspec.yaml'); String buildDir = convertPath('/workspace/out/debug-x87_128'); - newFile('/workspace/.config', - content: 'FOO=foo\n' + 'FUCHSIA_BUILD_DIR="$buildDir"\n' + 'BAR=bar\n'); + newFile('/workspace/.fx-build-dir', content: '$buildDir\n'); String packageLocation = convertPath('/workspace/this/is/the/package'); Uri packageUri = resourceProvider.pathContext.toUri(packageLocation); newFile('/workspace/out/debug-x87_128/dartlang/gen/some/code/foo.packages', @@ -109,7 +106,7 @@ newFolder('/workspace/.jiri_root'); newFolder('/workspace/some/code'); newFile('/workspace/some/code/pubspec.yaml'); - newFile('/workspace/.config', content: 'FOO=foo\n' + 'BAR=bar\n'); + newFile('/workspace/.fx-build-dir', content: ''); String packageLocation = convertPath('/workspace/this/is/the/package'); Uri packageUri = resourceProvider.pathContext.toUri(packageLocation); newFile('/workspace/out/debug-x87_128/dartlang/gen/some/code/foo.packages', @@ -127,8 +124,7 @@ newFolder('/workspace/some/code'); newFile('/workspace/some/code/pubspec.yaml'); String buildDir = convertPath('out/release-y22_256'); - newFile('/workspace/.config', - content: 'FOO=foo\n' + 'FUCHSIA_BUILD_DIR="$buildDir"\n' + 'BAR=bar\n'); + newFile('/workspace/.fx-build-dir', content: '$buildDir\n'); String packageLocation = convertPath('/workspace/this/is/the/package'); Uri packageUri = resourceProvider.pathContext.toUri(packageLocation); newFile('/workspace/out/debug-x87_128/dartlang/gen/some/code/foo.packages', @@ -152,8 +148,7 @@ newFolder('/workspace/some/code'); newFile('/workspace/some/code/pubspec.yaml'); String buildDir = convertPath('out/debug-x87_128'); - newFile('/workspace/.config', - content: 'FOO=foo\n' + 'FUCHSIA_BUILD_DIR=$buildDir\n' + 'BAR=bar\n'); + newFile('/workspace/.fx-build-dir', content: '$buildDir\n'); String packageOneLocation = convertPath('/workspace/this/is/the/package'); Uri packageOneUri = resourceProvider.pathContext.toUri(packageOneLocation); newFile('/workspace/out/debug-x87_128/dartlang/gen/some/code/foo.packages', @@ -179,8 +174,7 @@ GnWorkspace _buildStandardGnWorkspace() { newFolder('/ws/.jiri_root'); String buildDir = convertPath('out/debug-x87_128'); - newFile('/ws/.config', - content: 'FOO=foo\n' + 'FUCHSIA_BUILD_DIR="$buildDir"\n' + 'BAR=bar\n'); + newFile('/ws/.fx-build-dir', content: '$buildDir\n'); newFile('/ws/out/debug-x87_128/dartlang/gen/some/code/foo.packages'); newFolder('/ws/some/code'); return GnWorkspace.find(resourceProvider, convertPath('/ws/some/code'));
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart index f8a77f4..798e369 100644 --- a/pkg/analyzer/tool/summary/generate.dart +++ b/pkg/analyzer/tool/summary/generate.dart
@@ -2,21 +2,19 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -/** - * This file contains code to generate serialization/deserialization logic for - * summaries based on an "IDL" description of the summary format (written in - * stylized Dart). - * - * For each class in the "IDL" input, two corresponding classes are generated: - * - A class with the same name which represents deserialized summary data in - * memory. This class has read-only semantics. - * - A "builder" class which can be used to generate serialized summary data. - * This class has write-only semantics. - * - * Each of the "builder" classes has a single `finish` method which writes - * the entity being built into the given FlatBuffer and returns the `Offset` - * reference to it. - */ +/// This file contains code to generate serialization/deserialization logic for +/// summaries based on an "IDL" description of the summary format (written in +/// stylized Dart). +/// +/// For each class in the "IDL" input, two corresponding classes are generated: +/// - A class with the same name which represents deserialized summary data in +/// memory. This class has read-only semantics. +/// - A "builder" class which can be used to generate serialized summary data. +/// This class has write-only semantics. +/// +/// Each of the "builder" classes has a single `finish` method which writes +/// the entity being built into the given FlatBuffer and returns the `Offset` +/// reference to it. import 'dart:convert'; import 'dart:io'; @@ -60,19 +58,13 @@ static const String _throwDeprecated = "throw new UnimplementedError('attempt to access deprecated field')"; - /** - * Buffer in which generated code is accumulated. - */ + /// Buffer in which generated code is accumulated. final StringBuffer _outBuffer = new StringBuffer(); - /** - * Current indentation level. - */ + /// Current indentation level. String _indentation = ''; - /** - * Semantic model of the "IDL" input file. - */ + /// Semantic model of the "IDL" input file. idlModel.Idl _idl; _CodeGenerator(String idlPath) { @@ -90,10 +82,8 @@ checkIdl(); } - /** - * Perform basic sanity checking of the IDL (over and above that done by - * [extractIdl]). - */ + /// Perform basic sanity checking of the IDL (over and above that done by + /// [extractIdl]). void checkIdl() { _idl.classes.forEach((String name, idlModel.ClassDeclaration cls) { if (cls.fileIdentifier != null) { @@ -143,10 +133,8 @@ }); } - /** - * Generate a string representing the Dart type which should be used to - * represent [type] when deserialized. - */ + /// Generate a string representing the Dart type which should be used to + /// represent [type] when deserialized. String dartType(idlModel.FieldType type) { String baseType = idlPrefix(type.typeName); if (type.isList) { @@ -156,13 +144,11 @@ } } - /** - * Generate a Dart expression representing the default value for a field - * having the given [type], or `null` if there is no default value. - * - * If [builder] is `true`, the returned type should be appropriate for use in - * a builder class. - */ + /// Generate a Dart expression representing the default value for a field + /// having the given [type], or `null` if there is no default value. + /// + /// If [builder] is `true`, the returned type should be appropriate for use in + /// a builder class. String defaultValue(idlModel.FieldType type, bool builder) { if (type.isList) { if (builder) { @@ -188,10 +174,8 @@ } } - /** - * Generate a string representing the Dart type which should be used to - * represent [type] while building a serialized data structure. - */ + /// Generate a string representing the Dart type which should be used to + /// represent [type] while building a serialized data structure. String encodedType(idlModel.FieldType type) { String typeStr; if (_idl.classes.containsKey(type.typeName)) { @@ -206,10 +190,8 @@ } } - /** - * Process the AST in [idlParsed] and store the resulting semantic model in - * [_idl]. Also perform some error checking. - */ + /// Process the AST in [idlParsed] and store the resulting semantic model in + /// [_idl]. Also perform some error checking. void extractIdl(CompilationUnit idlParsed) { _idl = new idlModel.Idl(); for (CompilationUnitMember decl in idlParsed.declarations) { @@ -301,10 +283,8 @@ } } - /** - * Generate a string representing the FlatBuffer schema type which should be - * used to represent [type]. - */ + /// Generate a string representing the FlatBuffer schema type which should be + /// used to represent [type]. String fbsType(idlModel.FieldType type) { String typeStr; switch (type.typeName) { @@ -337,9 +317,7 @@ } } - /** - * Entry point to the code generator when generating the "format.fbs" file. - */ + /// Entry point to the code generator when generating the "format.fbs" file. void generateFlatBufferSchema() { outputHeader(); for (idlModel.EnumDeclaration enm in _idl.enums.values) { @@ -392,9 +370,7 @@ } } - /** - * Entry point to the code generator when generating the "format.dart" file. - */ + /// Entry point to the code generator when generating the "format.dart" file. void generateFormatCode() { outputHeader(); out('library analyzer.src.summary.format;'); @@ -430,10 +406,8 @@ } } - /** - * Add the prefix `idl.` to a type name, unless that type name is the name of - * a built-in type. - */ + /// Add the prefix `idl.` to a type name, unless that type name is the name of + /// a built-in type. String idlPrefix(String s) { switch (s) { case 'bool': @@ -446,9 +420,7 @@ } } - /** - * Execute [callback] with two spaces added to [_indentation]. - */ + /// Execute [callback] with two spaces added to [_indentation]. void indent(void callback()) { String oldIndentation = _indentation; try { @@ -459,10 +431,8 @@ } } - /** - * Add the string [s] to the output as a single line, indenting as - * appropriate. - */ + /// Add the string [s] to the output as a single line, indenting as + /// appropriate. void out([String s = '']) { if (s == '') { _outBuffer.writeln(''); @@ -489,9 +459,7 @@ out(); } - /** - * Enclose [s] in quotes, escaping as necessary. - */ + /// Enclose [s] in quotes, escaping as necessary. String quoted(String s) { return json.encode(s); } @@ -713,7 +681,7 @@ if (field.variantMap != null) { for (var logicalName in field.variantMap.keys) { var variants = field.variantMap[logicalName]; - out('void set $logicalName($typeStr value) {'); + out('set $logicalName($typeStr value) {'); indent(() { out(_variantAssertStatement(cls, variants)); _generateNonNegativeInt(fieldType); @@ -723,7 +691,7 @@ out(); } } else { - out('void set $fieldName($typeStr value) {'); + out('set $fieldName($typeStr value) {'); indent(() { _generateNonNegativeInt(fieldType); out('this._$fieldName = value;'); @@ -782,9 +750,7 @@ // Generate flushInformative(). { out(); - out('/**'); - out(' * Flush [informative] data recursively.'); - out(' */'); + out('/// Flush [informative] data recursively.'); out('void flushInformative() {'); indent(() { for (idlModel.FieldDeclaration field in cls.fields) { @@ -806,9 +772,7 @@ // Generate collectApiSignature(). { out(); - out('/**'); - out(' * Accumulate non-[informative] data into [signature].'); - out(' */'); + out('/// Accumulate non-[informative] data into [signature].'); out('void collectApiSignature(api_sig.ApiSignature signature) {'); indent(() { List<idlModel.FieldDeclaration> sortedFields = cls.fields.toList() @@ -1241,12 +1205,10 @@ out('}'); } - /** - * Generate a call to the appropriate method of [ApiSignature] for the type - * [typeName], using the data named by [ref]. If [couldBeNull] is `true`, - * generate code to handle the possibility that [ref] is `null` (substituting - * in the appropriate default value). - */ + /// Generate a call to the appropriate method of [ApiSignature] for the type + /// [typeName], using the data named by [ref]. If [couldBeNull] is `true`, + /// generate code to handle the possibility that [ref] is `null` (substituting + /// in the appropriate default value). void _generateSignatureCall(String typeName, String ref, bool couldBeNull) { if (_idl.enums.containsKey(typeName)) { if (couldBeNull) { @@ -1291,10 +1253,8 @@ } } - /** - * Return the documentation text of the given [node], or `null` if the [node] - * does not have a comment. Each line is `\n` separated. - */ + /// Return the documentation text of the given [node], or `null` if the [node] + /// does not have a comment. Each line is `\n` separated. String _getNodeDoc(AnnotatedNode node) { Comment comment = node.documentationComment; if (comment != null && comment.isDocumentation) {
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart index f35495b..50519469 100644 --- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart +++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart
@@ -21,17 +21,17 @@ String eol = null; /** - * The change that is being built. - */ - final SourceChange _change = new SourceChange(''); - - /** * A table mapping group ids to the associated linked edit groups. */ final Map<String, LinkedEditGroup> _linkedEditGroups = <String, LinkedEditGroup>{}; /** + * The source change selection or `null` if none. + */ + Position _selection; + + /** * The range of the selection for the change being built, or `null` if there * is no selection. */ @@ -44,6 +44,11 @@ final Set<Position> _lockedPositions = new HashSet<Position>.identity(); /** + * A map of absolute normalized path to file edit builder. + */ + final _fileEditBuilders = <String, FileEditBuilderImpl>{}; + + /** * Initialize a newly created change builder. */ ChangeBuilderImpl(); @@ -53,27 +58,34 @@ @override SourceChange get sourceChange { + final SourceChange change = new SourceChange(''); + for (var builder in _fileEditBuilders.values) { + if (builder.hasEdits) { + change.addFileEdit(builder.fileEdit); + builder.finalize(); + } + } _linkedEditGroups.forEach((String name, LinkedEditGroup group) { - _change.addLinkedEditGroup(group); + change.addLinkedEditGroup(group); }); - _linkedEditGroups.clear(); - return _change; + if (_selection != null) { + change.selection = _selection; + } + return change; } @override Future<void> addFileEdit( String path, void buildFileEdit(FileEditBuilder builder)) async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; - FileEditBuilderImpl builder = await createFileEditBuilder(path); + FileEditBuilderImpl builder = _fileEditBuilders[path]; if (builder == null) { - return; + builder = await createFileEditBuilder(path); + if (builder != null) { + _fileEditBuilders[path] = builder; + } } - - buildFileEdit(builder); - if (builder.hasEdits) { - _change.addFileEdit(builder.fileEdit); - await builder.finalize(); + if (builder != null) { + buildFileEdit(builder); } } @@ -102,7 +114,7 @@ @override void setSelection(Position position) { - _change.selection = position; + _selection = position; } void _setSelectionRange(SourceRange range) { @@ -126,9 +138,8 @@ _updatePosition(position); } } - Position selection = _change.selection; - if (selection != null) { - _updatePosition(selection); + if (_selection != null) { + _updatePosition(_selection); } } } @@ -349,9 +360,7 @@ /** * Finalize the source file edit that is being built. */ - Future<void> finalize() async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; + void finalize() { // Nothing to do. }
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart index 785a0f3..86a386f 100644 --- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart +++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -72,7 +72,24 @@ throw new AnalysisException('Cannot analyze "$path"'); } int timeStamp = state == ResultState.VALID ? 0 : -1; - return DartFileEditBuilderImpl(this, path, timeStamp, session, result.unit); + + CompilationUnit unit = result.unit; + CompilationUnitElement declaredUnit = unit.declaredElement; + CompilationUnitElement libraryUnit = + declaredUnit.library.definingCompilationUnit; + + DartFileEditBuilderImpl libraryEditBuilder; + if (libraryUnit != declaredUnit) { + // If the receiver is a part file builder, then proactively cache the + // library file builder so that imports can be finalized synchronously. + await addFileEdit(libraryUnit.source.fullName, + (DartFileEditBuilder builder) { + libraryEditBuilder = builder as DartFileEditBuilderImpl; + }); + } + + return DartFileEditBuilderImpl( + this, path, timeStamp, session, unit, libraryEditBuilder); } } @@ -1123,6 +1140,12 @@ final LibraryElement libraryElement; /** + * The change builder for the library + * or `null` if the receiver is the builder for the library. + */ + final DartFileEditBuilderImpl libraryChangeBuilder; + + /** * The optional generator of prefixes for new imports. */ ImportPrefixGenerator importPrefixGenerator; @@ -1134,17 +1157,27 @@ Map<Uri, _LibraryToImport> librariesToImport = {}; /** + * A mapping from libraries that need to be imported relatively in order to + * make visible the names used in generated code, to information about these + * imports. + */ + Map<String, _LibraryToImport> librariesToRelativelyImport = {}; + + /** * Initialize a newly created builder to build a source file edit within the * change being built by the given [changeBuilder]. The file being edited has * the given [path] and [timeStamp], and the given fully resolved [unit]. */ DartFileEditBuilderImpl(DartChangeBuilderImpl changeBuilder, String path, - int timeStamp, this.session, this.unit) + int timeStamp, this.session, this.unit, this.libraryChangeBuilder) : libraryElement = unit.declaredElement.library, super(changeBuilder, path, timeStamp); @override - bool get hasEdits => super.hasEdits || librariesToImport.isNotEmpty; + bool get hasEdits => + super.hasEdits || + librariesToImport.isNotEmpty || + librariesToRelativelyImport.isNotEmpty; @override void addInsertion(int offset, void buildEdit(DartEditBuilder builder)) => @@ -1181,21 +1214,12 @@ } @override - Future<void> finalize() async { - // TODO(brianwilkerson) Determine whether this await is necessary. - await null; + void finalize() { if (librariesToImport.isNotEmpty) { - CompilationUnitElement definingUnitElement = - libraryElement.definingCompilationUnit; - if (definingUnitElement == unit.declaredElement) { - _addLibraryImports(librariesToImport.values); - } else { - await (changeBuilder as DartChangeBuilder).addFileEdit( - definingUnitElement.source.fullName, (DartFileEditBuilder builder) { - (builder as DartFileEditBuilderImpl) - ._addLibraryImports(librariesToImport.values); - }); - } + _addLibraryImports(librariesToImport.values); + } + if (librariesToRelativelyImport.isNotEmpty) { + _addLibraryImports(librariesToRelativelyImport.values); } } @@ -1204,6 +1228,10 @@ return _importLibrary(uri).uriText; } + String importLibraryWithRelativeUri(String uriText, [String prefix = null]) { + return _importLibraryWithRelativeUri(uriText, prefix).uriText; + } + @override ImportLibraryElementResult importLibraryElement({ @required ResolvedLibraryResult targetLibrary, @@ -1212,7 +1240,8 @@ @required LibraryElement requestedLibrary, @required Element requestedElement, }) { - if (librariesToImport.isNotEmpty) { + if (librariesToImport.isNotEmpty || + librariesToRelativelyImport.isNotEmpty) { throw StateError('Only one library can be safely imported.'); } @@ -1227,7 +1256,8 @@ var prefix = request.prefix; if (request.uri != null) { var uriText = _getLibraryUriText(request.uri); - librariesToImport[request.uri] = _LibraryToImport(uriText, prefix); + (libraryChangeBuilder ?? this).librariesToImport[request.uri] = + _LibraryToImport(uriText, prefix); } return ImportLibraryElementResultImpl(prefix); @@ -1462,31 +1492,45 @@ } /** - * Computes the best URI to import [what] into the target library. + * Computes the best URI to import [uri] into the target library. */ - String _getLibraryUriText(Uri what) { - if (what.scheme == 'file') { + String _getLibraryUriText(Uri uri) { + if (uri.scheme == 'file') { var pathContext = session.resourceProvider.pathContext; - String whatPath = pathContext.fromUri(what); + String whatPath = pathContext.fromUri(uri); String libraryPath = libraryElement.source.fullName; String libraryFolder = pathContext.dirname(libraryPath); String relativeFile = pathContext.relative(whatPath, from: libraryFolder); return pathContext.split(relativeFile).join('/'); } - return what.toString(); + return uri.toString(); } /** * Arrange to have an import added for the library with the given [uri]. */ _LibraryToImport _importLibrary(Uri uri) { - var import = librariesToImport[uri]; + var import = (libraryChangeBuilder ?? this).librariesToImport[uri]; if (import == null) { String uriText = _getLibraryUriText(uri); String prefix = importPrefixGenerator != null ? importPrefixGenerator(uri) : null; import = new _LibraryToImport(uriText, prefix); - librariesToImport[uri] = import; + (libraryChangeBuilder ?? this).librariesToImport[uri] = import; + } + return import; + } + + /** + * Arrange to have an import added for the library with the given relative + * [uriText]. + */ + _LibraryToImport _importLibraryWithRelativeUri(String uriText, + [String prefix = null]) { + var import = librariesToRelativelyImport[uriText]; + if (import == null) { + import = new _LibraryToImport(uriText, prefix); + librariesToRelativelyImport[uriText] = import; } return import; }
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart index 1739677..2f545d1 100644 --- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart +++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart
@@ -225,6 +225,20 @@ _visitClassOrMixinMembers(node); } + @override + void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { + // `TypeName^` is recovered as `<noType> TypeName;`, remove the name. + var variableList = node.variables; + if (variableList.keyword == null && variableList.type == null) { + for (var variable in variableList.variables) { + names.remove(variable.name.name); + } + return; + } + + super.visitTopLevelVariableDeclaration(node); + } + void _addForLoopParts(ForLoopParts forLoopParts, AstNode body) { if (forLoopParts is ForEachPartsWithDeclaration) { if (_isCoveredBy(body)) { @@ -260,9 +274,10 @@ } void _addName(SimpleIdentifier node) { - if (node != null) { - names.add(node.name); - } + if (node == null) return; + if (node.end == offset) return; + + names.add(node.name); } void _addTypeParameters(TypeParameterList typeParameterList) {
diff --git a/pkg/analyzer_plugin/pubspec.yaml b/pkg/analyzer_plugin/pubspec.yaml index 277eda1..5ac22f2 100644 --- a/pkg/analyzer_plugin/pubspec.yaml +++ b/pkg/analyzer_plugin/pubspec.yaml
@@ -10,7 +10,7 @@ dependencies: analyzer: '^0.35.3' charcode: '^1.1.0' - html: '^0.13.1' + html: '>=0.13.1 <0.15.0' meta: ^1.0.2 path: '^1.4.1' pub_semver: '^1.3.2'
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart index 51cc21e..8873d2e 100644 --- a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart +++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
@@ -16,6 +16,7 @@ defineReflectiveSuite(() { defineReflectiveTests(ImportLibraryElementTest); defineReflectiveTests(ImportLibraryElement_existingImport_Test); + defineReflectiveTests(ImportLibraryElement_incompleteCode_Test); defineReflectiveTests(ImportLibraryElement_newImport_withoutPrefix_Test); defineReflectiveTests(ImportLibraryElement_newImport_withPrefix_Test); }); @@ -159,6 +160,47 @@ } @reflectiveTest +class ImportLibraryElement_incompleteCode_Test extends _Base { + test_formalParameter() async { + newFile('/home/test/lib/a.dart', content: 'class A {}'); + newFile('/home/test/lib/b.dart', content: r''' +export 'a.dart'; +'''); + await _assertImportLibraryElement( + initialCode: r''' +f(A^) {} +''', + uriStr: 'package:test/a.dart', + name: 'A', + expectedCode: r''' +import 'package:test/a.dart'; + +f(A) {} +''', + ); + } + + test_topLevelVariable() async { + newFile('/home/test/lib/a.dart', content: 'class A {}'); + newFile('/home/test/lib/b.dart', content: r''' +export 'a.dart'; +'''); + await _assertImportLibraryElement( + initialCode: r''' +A^ +''', + uriStr: 'package:test/a.dart', + name: 'A', + expectedCode: r''' +import 'package:test/a.dart'; + +A +''', + ); + } +} + +@reflectiveTest class ImportLibraryElement_newImport_withoutPrefix_Test extends _Base { test_exported() async { newFile('/home/test/lib/a.dart', content: 'class A {}');
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart index 8598e78..03f5b05 100644 --- a/pkg/compiler/lib/src/compiler.dart +++ b/pkg/compiler/lib/src/compiler.dart
@@ -78,7 +78,7 @@ api.CompilerOutput get outputProvider => _outputProvider; - Uri _mainLibraryUri; + List<CodeLocation> _userCodeLocations = <CodeLocation>[]; JClosedWorld backendClosedWorldForTesting; @@ -231,20 +231,7 @@ }); Future runInternal(Uri uri) async { - // TODO(ahe): This prevents memory leaks when invoking the compiler - // multiple times. Implement a better mechanism where we can store - // such caches in the compiler and get access to them through a - // suitably maintained static reference to the current compiler. - clearStringTokenCanonicalizer(); - Selector.canonicalizedValues.clear(); - - // The selector objects held in static fields must remain canonical. - for (Selector selector in Selectors.ALL) { - Selector.canonicalizedValues - .putIfAbsent(selector.hashCode, () => <Selector>[]) - .add(selector); - } - + clearState(); assert(uri != null); // As far as I can tell, this branch is only used by test code. reporter.log('Compiling $uri (${options.buildId})'); @@ -265,7 +252,6 @@ return; } if (options.cfeOnly) return; - _mainLibraryUri = result.rootLibraryUri; frontendStrategy.registerLoadedLibraries(result); for (Uri uri in result.libraries) { @@ -287,6 +273,23 @@ } } + /// Clear the internal compiler state to prevent memory leaks when invoking + /// the compiler multiple times (e.g. in batch mode). + // TODO(ahe): implement a better mechanism where we can store + // such caches in the compiler and get access to them through a + // suitably maintained static reference to the current compiler. + void clearState() { + clearStringTokenCanonicalizer(); + Selector.canonicalizedValues.clear(); + + // The selector objects held in static fields must remain canonical. + for (Selector selector in Selectors.ALL) { + Selector.canonicalizedValues + .putIfAbsent(selector.hashCode, () => <Selector>[]) + .add(selector); + } + } + /// Starts the resolution phase, creating the [ResolutionEnqueuer] if not /// already created. /// @@ -396,6 +399,7 @@ } void compileFromKernel(Uri rootLibraryUri, Iterable<Uri> libraries) { + _userCodeLocations.add(new CodeLocation(rootLibraryUri)); selfTask.measureSubtask("compileFromKernel", () { JClosedWorld closedWorld = selfTask.measureSubtask("computeClosedWorld", () => computeClosedWorld(rootLibraryUri, libraries)); @@ -567,25 +571,11 @@ if (element == null) return assumeInUserCode; Uri libraryUri = _uriFromElement(element); if (libraryUri == null) return false; - Iterable<CodeLocation> userCodeLocations = - computeUserCodeLocations(assumeInUserCode: assumeInUserCode); - return userCodeLocations.any( + if (_userCodeLocations.isEmpty && assumeInUserCode) return true; + return _userCodeLocations.any( (CodeLocation codeLocation) => codeLocation.inSameLocation(libraryUri)); } - Iterable<CodeLocation> computeUserCodeLocations( - {bool assumeInUserCode: false}) { - List<CodeLocation> userCodeLocations = <CodeLocation>[]; - if (_mainLibraryUri != null) { - userCodeLocations.add(new CodeLocation(_mainLibraryUri)); - } - if (userCodeLocations.isEmpty && assumeInUserCode) { - // Assume in user code since [mainApp] has not been set yet. - userCodeLocations.add(const AnyLocation()); - } - return userCodeLocations; - } - /// Return a canonical URI for the source of [element]. /// /// For a package library with canonical URI 'package:foo/bar/baz.dart' the
diff --git a/pkg/compiler/lib/src/constants/constant_system.dart b/pkg/compiler/lib/src/constants/constant_system.dart index 40ef21c..2d154b7 100644 --- a/pkg/compiler/lib/src/constants/constant_system.dart +++ b/pkg/compiler/lib/src/constants/constant_system.dart
@@ -845,7 +845,7 @@ // In order to preserve runtime semantics which says that NaN !== NaN // don't constant fold NaN === NaN. Otherwise the output depends on // inlined variables and other optimizations. - if (left.isNaN && right.isNaN) return null; + if (left.isNaN && right.isNaN) return new FalseConstantValue(); return createBool(left == right); }
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart index b3098c9..585c560 100644 --- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart +++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -14,6 +14,7 @@ import '../elements/types.dart'; import '../inferrer/abstract_value_domain.dart'; import '../inferrer/types.dart'; +import '../ir/constants.dart'; import '../ir/static_type_provider.dart'; import '../ir/util.dart'; import '../js_backend/backend.dart'; @@ -1127,9 +1128,13 @@ int _findLength(ir.Arguments arguments) { ir.Expression firstArgument = arguments.positional.first; if (firstArgument is ir.ConstantExpression && - firstArgument.constant is ir.IntConstant) { - ir.IntConstant constant = firstArgument.constant; - return constant.value; + firstArgument.constant is ir.DoubleConstant) { + ir.DoubleConstant constant = firstArgument.constant; + double doubleValue = constant.value; + int truncatedValue = doubleValue.truncate(); + if (doubleValue == truncatedValue) { + return truncatedValue; + } } else if (firstArgument is ir.IntLiteral) { return firstArgument.value; } else if (firstArgument is ir.StaticGet) { @@ -2165,51 +2170,3 @@ return sb.toString(); } } - -/// Class to represent a reference to a constant in allocation nodes. -/// -/// This class is needed in order to support serialization of references to -/// constant nodes. Since the constant nodes are not [ir.TreeNode]s we can only -/// serialize the constants as values which would bypass by the canonicalization -/// performed by the CFE. This class extends only as a trick to easily pass -/// it through serialization. -/// -/// By adding a reference to the constant expression in which the constant -/// occurred, we can serialize references to constants in two steps: a reference -/// to the constant expression followed by an index of the referred constant -/// in the traversal order of the constant held by the constant expression. -/// -/// This is used for list, map, and set literals. -class ConstantReference extends ir.TreeNode { - final ir.ConstantExpression expression; - final ir.Constant constant; - - ConstantReference(this.expression, this.constant); - - @override - void visitChildren(ir.Visitor v) { - throw new UnsupportedError("ConstantReference.visitChildren"); - } - - @override - accept(ir.TreeVisitor v) { - throw new UnsupportedError("ConstantReference.accept"); - } - - @override - transformChildren(ir.Transformer v) { - throw new UnsupportedError("ConstantReference.transformChildren"); - } - - @override - int get hashCode => 13 * constant.hashCode; - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - return other is ConstantReference && constant == other.constant; - } - - @override - String toString() => 'ConstantReference(constant=$constant)'; -}
diff --git a/pkg/compiler/lib/src/ir/constants.dart b/pkg/compiler/lib/src/ir/constants.dart index bf36eee..06a6eb3 100644 --- a/pkg/compiler/lib/src/ir/constants.dart +++ b/pkg/compiler/lib/src/ir/constants.dart
@@ -139,3 +139,51 @@ return false; } } + +/// Class to represent a reference to a constant in allocation nodes. +/// +/// This class is needed in order to support serialization of references to +/// constant nodes. Since the constant nodes are not [ir.TreeNode]s we can only +/// serialize the constants as values which would bypass by the canonicalization +/// performed by the CFE. This class extends only as a trick to easily pass +/// it through serialization. +/// +/// By adding a reference to the constant expression in which the constant +/// occurred, we can serialize references to constants in two steps: a reference +/// to the constant expression followed by an index of the referred constant +/// in the traversal order of the constant held by the constant expression. +/// +/// This is used for list, map, and set literals. +class ConstantReference extends ir.TreeNode { + final ir.ConstantExpression expression; + final ir.Constant constant; + + ConstantReference(this.expression, this.constant); + + @override + void visitChildren(ir.Visitor v) { + throw new UnsupportedError("ConstantReference.visitChildren"); + } + + @override + accept(ir.TreeVisitor v) { + throw new UnsupportedError("ConstantReference.accept"); + } + + @override + transformChildren(ir.Transformer v) { + throw new UnsupportedError("ConstantReference.transformChildren"); + } + + @override + int get hashCode => 13 * constant.hashCode; + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + return other is ConstantReference && constant == other.constant; + } + + @override + String toString() => 'ConstantReference(constant=$constant)'; +}
diff --git a/pkg/compiler/lib/src/ir/impact.dart b/pkg/compiler/lib/src/ir/impact.dart index 66a527e..d635b78 100644 --- a/pkg/compiler/lib/src/ir/impact.dart +++ b/pkg/compiler/lib/src/ir/impact.dart
@@ -10,6 +10,7 @@ import 'package:kernel/type_environment.dart' as ir; import '../common.dart'; +import 'constants.dart'; import 'impact_data.dart'; import 'runtime_type_analysis.dart'; import 'scope.dart'; @@ -90,6 +91,9 @@ void registerFieldInitialization(ir.Field node); + void registerFieldConstantInitialization( + ir.Field node, ConstantReference constant); + void registerLoadLibrary(); void registerRedirectingInitializer( @@ -655,7 +659,7 @@ @override void handleConstantExpression(ir.ConstantExpression node) { ir.LibraryDependency import = getDeferredImport(node); - node.constant.accept(new ConstantImpactVisitor(this, import)); + node.constant.accept(new ConstantImpactVisitor(this, import, node)); } } @@ -698,8 +702,9 @@ class ConstantImpactVisitor implements ir.ConstantVisitor<void> { final ImpactRegistry registry; final ir.LibraryDependency import; + final ir.ConstantExpression expression; - ConstantImpactVisitor(this.registry, this.import); + ConstantImpactVisitor(this.registry, this.import, this.expression); @override void defaultConstant(ir.Constant node) { @@ -736,7 +741,8 @@ node.classNode, node.typeArguments, import); node.fieldValues.forEach((ir.Reference reference, ir.Constant value) { ir.Field field = reference.asField; - registry.registerFieldInitialization(field); + registry.registerFieldConstantInitialization( + field, new ConstantReference(expression, value)); value.accept(this); }); }
diff --git a/pkg/compiler/lib/src/ir/impact_data.dart b/pkg/compiler/lib/src/ir/impact_data.dart index 1d0abe6..543d3ed 100644 --- a/pkg/compiler/lib/src/ir/impact_data.dart +++ b/pkg/compiler/lib/src/ir/impact_data.dart
@@ -8,6 +8,7 @@ import '../serialization/serialization.dart'; import '../util/enumset.dart'; +import 'constants.dart'; import 'impact.dart'; import 'runtime_type_analysis.dart'; import 'static_type.dart'; @@ -230,6 +231,13 @@ } @override + void registerFieldConstantInitialization( + ir.Field node, ConstantReference constant) { + _data._fieldConstantInitializers ??= {}; + _data._fieldConstantInitializers.putIfAbsent(node, () => []).add(constant); + } + + @override void registerTypeLiteral(ir.DartType type, ir.LibraryDependency import) { _data._typeLiterals ??= []; _data._typeLiterals.add(new _TypeLiteral(type, import)); @@ -482,6 +490,7 @@ List<_TypeUse> _typeUses; List<_RedirectingInitializer> _redirectingInitializers; List<ir.Field> _fieldInitializers; + Map<ir.Field, List<ConstantReference>> _fieldConstantInitializers; List<_TypeLiteral> _typeLiterals; List<ir.TreeNode> _localFunctions; List<_GenericInstantiation> _genericInstantiations; @@ -555,6 +564,8 @@ () => new _RedirectingInitializer.fromDataSource(source), emptyAsNull: true); _fieldInitializers = source.readMemberNodes(emptyAsNull: true); + _fieldConstantInitializers = + source.readMemberMap(() => source.readTreeNodes(), emptyAsNull: true); _typeLiterals = source.readList( () => new _TypeLiteral.fromDataSource(source), emptyAsNull: true); @@ -649,6 +660,8 @@ (_RedirectingInitializer o) => o.toDataSink(sink), allowNull: true); sink.writeMemberNodes(_fieldInitializers, allowNull: true); + sink.writeMemberNodeMap(_fieldConstantInitializers, sink.writeTreeNodes, + allowNull: true); sink.writeList(_typeLiterals, (_TypeLiteral o) => o.toDataSink(sink), allowNull: true); sink.writeTreeNodes(_localFunctions, allowNull: true); @@ -896,6 +909,14 @@ registry.registerFieldInitialization(data); } } + if (_fieldConstantInitializers != null) { + _fieldConstantInitializers + .forEach((ir.Field field, List<ConstantReference> constants) { + for (ConstantReference constant in constants) { + registry.registerFieldConstantInitialization(field, constant); + } + }); + } if (_typeLiterals != null) { for (_TypeLiteral data in _typeLiterals) { registry.registerTypeLiteral(data.type, data.import);
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart index 6907520..7aee79e 100644 --- a/pkg/compiler/lib/src/ir/static_type.dart +++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -164,6 +164,9 @@ while (type is ir.TypeParameterType) { type = (type as ir.TypeParameterType).parameter.bound; } + if (type == typeEnvironment.nullType) { + return superclass.bottomType; + } if (type is ir.InterfaceType) { ir.InterfaceType upcastType = typeEnvironment.getTypeAsInstanceOf(type, superclass); @@ -171,6 +174,7 @@ } else if (type is ir.BottomType) { return superclass.bottomType; } + // TODO(johnniwinther): Should we assert that this doesn't happen? return superclass.rawType; }
diff --git a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart index 9682f5b..751295e 100644 --- a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart +++ b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
@@ -127,6 +127,7 @@ const CheckedModeHelper('doubleTypeCheck'), const CheckedModeHelper('numTypeCast'), const CheckedModeHelper('numTypeCheck'), + const CheckedModeHelper('boolConversionCheck'), const CheckedModeHelper('boolTypeCast'), const CheckedModeHelper('boolTypeCheck'), const CheckedModeHelper('intTypeCast'),
diff --git a/pkg/compiler/lib/src/js_backend/field_analysis.dart b/pkg/compiler/lib/src/js_backend/field_analysis.dart index 915dd48..7349b4d 100644 --- a/pkg/compiler/lib/src/js_backend/field_analysis.dart +++ b/pkg/compiler/lib/src/js_backend/field_analysis.dart
@@ -163,6 +163,11 @@ final Map<KConstructor, Initializer> initializers = {}; AllocatorData(this.initialValue); + + @override + String toString() => + 'AllocatorData(initialValue=${initialValue?.toStructuredText()},' + 'initializers=$initializers)'; } enum InitializerKind { @@ -284,6 +289,8 @@ } } + memberUsage.initialConstants.forEach(includeInitialValue); + bool inAllConstructors = true; for (KConstructor constructor in classData.constructors) { if (isTooComplex) { @@ -292,7 +299,10 @@ MemberUsage constructorUsage = closedWorld.liveMemberUsage[constructor]; - if (constructorUsage == null) return; + if (constructorUsage == null) { + // This constructor isn't called. + continue; + } ParameterStructure invokedParameters = closedWorld.annotationsData.hasNoElision(constructor) ? constructor.parameterStructure
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart index e5132c6..5094315 100644 --- a/pkg/compiler/lib/src/js_backend/runtime_types.dart +++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -2073,6 +2073,7 @@ classUse.instance = true; }); + Set<ClassEntity> visitedSuperClasses = {}; codegenWorldBuilder.instantiatedTypes.forEach((InterfaceType type) { liveTypeVisitor.visitType(type, TypeVisitorState.direct); ClassUse classUse = @@ -2082,6 +2083,28 @@ if (callType != null) { liveTypeVisitor.visitType(callType, TypeVisitorState.direct); } + + // Superclass might make classes live as type arguments. For instance + // + // class A {} + // class B<T> {} + // class C implements B<A> {} + // main() => new C(); + // + // Here `A` is live as a type argument through the liveness of `C`. + for (InterfaceType supertype + in _closedWorld.dartTypes.getSupertypes(type.element)) { + if (supertype.typeArguments.isEmpty && + visitedSuperClasses.contains(supertype.element)) { + // If [superclass] is not generic then a second visit cannot add more + // information that the first. In the example above, visiting `C` + // twice can only result in a second registration of `A` as live + // type argument. + break; + } + visitedSuperClasses.add(supertype.element); + liveTypeVisitor.visitType(supertype, TypeVisitorState.direct); + } }); for (FunctionEntity element
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 bbf43e4..f5b5b0c 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
@@ -765,7 +765,13 @@ assert(!field.needsUncheckedSetter); FieldEntity element = field.element; js.Expression code = _generatedCode[element]; - assert(code != null); + if (code == null) { + // TODO(johnniwinther): Static types are not honoured in the dynamic + // uses created in codegen, leading to dead code, as known by the + // closed world computation, being triggered by the codegen + // enqueuer. We cautiously generate an empty function for this case. + code = js.js("function() {}"); + } js.Name name = _namer.deriveSetterName(field.accessorName); checkedSetters.add(_buildStubMethod(name, code, element: element)); }
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart index a1ba755..1cac12f 100644 --- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart +++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -1084,12 +1084,10 @@ if (field.isElided) { ConstantValue constantValue = field.constantValue; if (constantValue == null) { - assert(_closedWorld.abstractValueDomain is TrivialAbstractValueDomain); - // Since static types are not used in invocation/access of instance - // members in codegen, we see dynamic uses in codegen that are not - // present in resolution when using the trivial abstract value domain. - // This means that resolution can determine that a field is never read - // but codegen thinks it is read. + // TODO(johnniwinther): Static types are not honoured in the dynamic + // uses created in codegen, leading to dead code, as known by the closed + // world computation, being triggered by the codegen enqueuer. We + // cautiously generate a null constant for this case. constantValue = new NullConstantValue(); } code = js.js(
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart index 6497bf4..3233491 100644 --- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart +++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -37,7 +37,6 @@ import '../../common_elements.dart' show CommonElements; import '../../elements/entities.dart'; import '../../hash/sha1.dart' show Hasher; -import '../../inferrer/trivial.dart'; import '../../io/code_output.dart'; import '../../io/location_provider.dart' show LocationCollector; import '../../io/source_map_builder.dart' show SourceMapBuilder;
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart index 0353f59..7a2b12a 100644 --- a/pkg/compiler/lib/src/kernel/element_map_impl.dart +++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -77,6 +77,7 @@ ir.TypeEnvironment _typeEnvironment; ir.ClassHierarchy _classHierarchy; Dart2jsConstantEvaluator _constantEvaluator; + ConstantValuefier _constantValuefier; /// Library environment. Used for fast lookup. KProgramEnv env = new KProgramEnv(); @@ -125,6 +126,7 @@ _constantEnvironment = new KernelConstantEnvironment(this, _environment); _typeConverter = new DartTypeConverter(this); _types = new KernelDartTypes(this); + _constantValuefier = new ConstantValuefier(this); } @override @@ -1031,7 +1033,7 @@ } return null; } else { - return constant.accept(new ConstantValuefier(this)); + return constant.accept(_constantValuefier); } } @@ -1370,12 +1372,18 @@ } ImpactData impactData = impactBuilderData.impactData; memberData.staticTypes = impactBuilderData.cachedStaticTypes; - KernelImpactConverter converter = - new KernelImpactConverter(this, member, reporter, options); + KernelImpactConverter converter = new KernelImpactConverter( + this, member, reporter, options, _constantValuefier); return converter.convert(impactData); } else { KernelImpactBuilder builder = new KernelImpactBuilder( - this, member, reporter, options, variableScopeModel, annotations); + this, + member, + reporter, + options, + variableScopeModel, + annotations, + _constantValuefier); if (retainDataForTesting) { typeMapsForTesting ??= {}; typeMapsForTesting[member] = builder.typeMapsForTesting = {};
diff --git a/pkg/compiler/lib/src/kernel/kernel_impact.dart b/pkg/compiler/lib/src/kernel/kernel_impact.dart index 4de44d7..e32ea87 100644 --- a/pkg/compiler/lib/src/kernel/kernel_impact.dart +++ b/pkg/compiler/lib/src/kernel/kernel_impact.dart
@@ -13,12 +13,14 @@ import '../constants/values.dart'; import '../elements/entities.dart'; import '../elements/types.dart'; +import '../ir/constants.dart'; +import '../ir/impact.dart'; +import '../ir/impact_data.dart'; import '../ir/runtime_type_analysis.dart'; import '../ir/scope.dart'; import '../ir/static_type.dart'; -import '../ir/impact.dart'; -import '../ir/impact_data.dart'; import '../ir/util.dart'; +import '../ir/visitors.dart'; import '../js_backend/annotations.dart'; import '../js_backend/native_data.dart'; import '../native/behavior.dart'; @@ -45,9 +47,17 @@ @override final MemberEntity currentMember; final Set<PragmaAnnotation> _annotations; + @override + final ConstantValuefier _constantValuefier; - KernelImpactBuilder(this.elementMap, this.currentMember, this.reporter, - this._options, VariableScopeModel variableScopeModel, this._annotations) + KernelImpactBuilder( + this.elementMap, + this.currentMember, + this.reporter, + this._options, + VariableScopeModel variableScopeModel, + this._annotations, + this._constantValuefier) : this.impactBuilder = new ResolutionWorldImpactBuilder('${currentMember}'), super(elementMap.typeEnvironment, elementMap.classHierarchy, @@ -80,9 +90,11 @@ final CompilerOptions _options; @override final MemberEntity currentMember; + @override + final ConstantValuefier _constantValuefier; - KernelImpactConverter( - this.elementMap, this.currentMember, this.reporter, this._options) + KernelImpactConverter(this.elementMap, this.currentMember, this.reporter, + this._options, this._constantValuefier) : this.impactBuilder = new ResolutionWorldImpactBuilder('${currentMember}'); @@ -114,6 +126,7 @@ ir.TypeEnvironment get typeEnvironment; CommonElements get commonElements; NativeBasicData get _nativeBasicData; + ConstantValuefier get _constantValuefier; Object _computeReceiverConstraint( ir.DartType receiverType, ClassRelation relation) { @@ -781,6 +794,14 @@ } @override + void registerFieldConstantInitialization( + ir.Field node, ConstantReference constant) { + impactBuilder.registerStaticUse(new StaticUse.fieldConstantInit( + elementMap.getField(node), + constant.constant.accept(_constantValuefier))); + } + + @override void registerRedirectingInitializer( ir.Constructor constructor, int positionalArguments,
diff --git a/pkg/compiler/lib/src/kernel/loader.dart b/pkg/compiler/lib/src/kernel/loader.dart index bfdf6ee..d1cd03c 100644 --- a/pkg/compiler/lib/src/kernel/loader.dart +++ b/pkg/compiler/lib/src/kernel/loader.dart
@@ -105,7 +105,8 @@ _options.librariesSpecificationUri, dependencies, _options.packageConfig, - experimentalFlags: _options.languageExperiments); + experimentalFlags: _options.languageExperiments, + enableAsserts: _options.enableUserAssertions); component = await fe.compile( initializedCompilerState, false,
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart index 83db5ad2..7cb0278 100644 --- a/pkg/compiler/lib/src/options.dart +++ b/pkg/compiler/lib/src/options.dart
@@ -267,6 +267,13 @@ /// This is an internal configuration option derived from other flags. CheckPolicy implicitDowncastCheckPolicy; + /// What the compiler should do with a boolean value in a condition context + /// when the language specification says it is a runtime error for it to be + /// null. + /// + /// This is an internal configuration option derived from other flags. + CheckPolicy conditionCheckPolicy; + /// Whether to generate code compliant with content security policy (CSP). bool useContentSecurityPolicy = false; @@ -462,9 +469,11 @@ if (omitImplicitChecks) { parameterCheckPolicy = CheckPolicy.trusted; implicitDowncastCheckPolicy = CheckPolicy.trusted; + conditionCheckPolicy = CheckPolicy.trusted; } else { parameterCheckPolicy = CheckPolicy.checked; implicitDowncastCheckPolicy = CheckPolicy.checked; + conditionCheckPolicy = CheckPolicy.checked; } if (_disableMinification) {
diff --git a/pkg/compiler/lib/src/serialization/mixins.dart b/pkg/compiler/lib/src/serialization/mixins.dart index 385c282..695d112 100644 --- a/pkg/compiler/lib/src/serialization/mixins.dart +++ b/pkg/compiler/lib/src/serialization/mixins.dart
@@ -156,6 +156,20 @@ } @override + Map<K, V> readMemberNodeMap<K extends ir.Member, V>(V f(), + {bool emptyAsNull: false}) { + int count = readInt(); + if (count == 0 && emptyAsNull) return null; + Map<K, V> map = {}; + for (int i = 0; i < count; i++) { + ir.Member node = readMemberNode(); + V value = f(); + map[node] = value; + } + return map; + } + + @override Map<K, V> readTreeNodeMap<K extends ir.TreeNode, V>(V f(), {bool emptyAsNull: false}) { int count = readInt(); @@ -542,6 +556,21 @@ } @override + void writeMemberNodeMap<V>(Map<ir.Member, V> map, void f(V value), + {bool allowNull: false}) { + if (map == null) { + assert(allowNull); + writeInt(0); + } else { + writeInt(map.length); + map.forEach((ir.Member key, V value) { + writeMemberNode(key); + f(value); + }); + } + } + + @override void writeTreeNodeMap<V>(Map<ir.TreeNode, V> map, void f(V value), {bool allowNull: false}) { if (map == null) {
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart index 65276b3..8623f87 100644 --- a/pkg/compiler/lib/src/serialization/serialization.dart +++ b/pkg/compiler/lib/src/serialization/serialization.dart
@@ -15,7 +15,7 @@ import '../elements/entities.dart'; import '../elements/indexed.dart'; import '../elements/types.dart'; -import '../inferrer/builder_kernel.dart'; +import '../ir/constants.dart'; import '../ir/static_type_base.dart'; import '../js_model/closure.dart'; import '../js_model/locals.dart'; @@ -139,6 +139,15 @@ /// [DataSource.readMemberNodes]. void writeMemberNodes(Iterable<ir.Member> values, {bool allowNull: false}); + /// Writes the [map] from references to kernel member nodes to [V] values to + /// this data sink, calling [f] to write each value to the data sink. If + /// [allowNull] is `true`, [map] is allowed to be `null`. + /// + /// This is a convenience method to be used together with + /// [DataSource.readMemberNodeMap]. + void writeMemberNodeMap<V>(Map<ir.Member, V> map, void f(V value), + {bool allowNull: false}); + /// Writes a kernel name node to this data sink. void writeName(ir.Name value); @@ -480,6 +489,15 @@ List<ir.Member> readMemberNodes<E extends ir.Member>( {bool emptyAsNull: false}); + /// Reads a map from kernel member nodes to [V] values from this data source, + /// calling [f] to read each value from the data source. If [emptyAsNull] is + /// `true`, `null` is returned instead of an empty map. + /// + /// This is a convenience method to be used together with + /// [DataSink.writeMemberNodeMap]. + Map<K, V> readMemberNodeMap<K extends ir.Member, V>(V f(), + {bool emptyAsNull: false}); + /// Reads a kernel name node from this data source. ir.Name readName();
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart index 844bdb4..d8f8ff5 100644 --- a/pkg/compiler/lib/src/ssa/builder_kernel.dart +++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -410,9 +410,7 @@ HInstruction popBoolified() { HInstruction value = pop(); if (typeBuilder.checkOrTrustTypes) { - InterfaceType type = commonElements.boolType; - return typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(value, type, - kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); + return typeBuilder.potentiallyCheckOrTrustTypeOfCondition(value); } HInstruction result = new HBoolify(value, abstractValueDomain.boolType); add(result);
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart index 9ba2e51..bb7e4ed 100644 --- a/pkg/compiler/lib/src/ssa/type_builder.dart +++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -122,6 +122,20 @@ return checkedOrTrusted; } + HInstruction potentiallyCheckOrTrustTypeOfCondition(HInstruction original) { + DartType boolType = builder.commonElements.boolType; + HInstruction checkedOrTrusted = original; + if (builder.options.conditionCheckPolicy.isTrusted) { + checkedOrTrusted = _trustType(original, boolType); + } else if (builder.options.conditionCheckPolicy.isEmitted) { + checkedOrTrusted = _checkType( + original, boolType, HTypeConversion.BOOLEAN_CONVERSION_CHECK); + } + if (checkedOrTrusted == original) return original; + builder.add(checkedOrTrusted); + return checkedOrTrusted; + } + ClassTypeVariableAccess computeTypeVariableAccess(MemberEntity member); /// Helper to create an instruction that gets the value of a type variable.
diff --git a/pkg/compiler/lib/src/universe/codegen_world_builder.dart b/pkg/compiler/lib/src/universe/codegen_world_builder.dart index 8ab3ae4..eb54121 100644 --- a/pkg/compiler/lib/src/universe/codegen_world_builder.dart +++ b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
@@ -400,7 +400,8 @@ case StaticUseKind.INVOKE: case StaticUseKind.GET: case StaticUseKind.SET: - case StaticUseKind.INIT: + case StaticUseKind.FIELD_INIT: + case StaticUseKind.FIELD_CONSTANT_INIT: break; } } @@ -441,7 +442,8 @@ case StaticUseKind.SUPER_TEAR_OFF: case StaticUseKind.GET: case StaticUseKind.SET: - case StaticUseKind.INIT: + case StaticUseKind.FIELD_INIT: + case StaticUseKind.FIELD_CONSTANT_INIT: useSet.addAll(usage.normalUse()); break; case StaticUseKind.CONSTRUCTOR_INVOKE:
diff --git a/pkg/compiler/lib/src/universe/member_usage.dart b/pkg/compiler/lib/src/universe/member_usage.dart index 1eb99bb..e368cbb 100644 --- a/pkg/compiler/lib/src/universe/member_usage.dart +++ b/pkg/compiler/lib/src/universe/member_usage.dart
@@ -5,6 +5,7 @@ import 'dart:math' as Math; import '../common.dart'; +import '../constants/values.dart'; import '../elements/entities.dart'; import '../js_model/elements.dart' show JSignatureMethod; import '../util/enumset.dart'; @@ -75,6 +76,8 @@ /// `true` if [entity] has been initialized. bool get hasInit => true; + Iterable<ConstantValue> get initialConstants => null; + /// `true` if [entity] has been read as a value. For a field this is a normal /// read access, for a function this is a closurization. bool get hasRead => false; @@ -120,6 +123,13 @@ /// no-op. EnumSet<MemberUse> init() => MemberUses.NONE; + /// Registers the [entity] has been initialized with [constant] and returns + /// the new [MemberUse]s that it caused. + /// + /// For a field this is the initial write access, for a function this is a + /// no-op. + EnumSet<MemberUse> constantInit(ConstantValue constant) => MemberUses.NONE; + /// Registers a read of the value of [entity] and returns the new [MemberUse]s /// that it caused. /// @@ -183,6 +193,8 @@ @override bool hasWrite; + List<ConstantValue> _initialConstants; + FieldUsage.cloned(FieldEntity field, EnumSet<MemberUse> pendingUse, {this.hasInit, this.hasRead, this.hasWrite}) : super.cloned(field, pendingUse); @@ -199,6 +211,9 @@ } @override + Iterable<ConstantValue> get initialConstants => _initialConstants ?? const []; + + @override bool get hasPendingNormalUse => !fullyUsed; @override @@ -218,6 +233,13 @@ } @override + EnumSet<MemberUse> constantInit(ConstantValue constant) { + _initialConstants ??= []; + _initialConstants.add(constant); + return init(); + } + + @override EnumSet<MemberUse> read() { if (hasRead) { return MemberUses.NONE; @@ -263,7 +285,8 @@ @override String toString() => 'FieldUsage($entity,hasInit=$hasInit,hasRead=$hasRead,' - 'hasWrite=$hasWrite,pendingUse=${_pendingUse.iterable(MemberUse.values)}'; + 'hasWrite=$hasWrite,pendingUse=${_pendingUse.iterable(MemberUse.values)},' + 'initialConstants=${initialConstants.map((c) => c.toStructuredText())})'; } class FinalFieldUsage extends MemberUsage { @@ -272,6 +295,8 @@ @override bool hasRead; + List<ConstantValue> _initialConstants; + FinalFieldUsage.cloned(FieldEntity field, EnumSet<MemberUse> pendingUse, {this.hasInit, this.hasRead}) : super.cloned(field, pendingUse); @@ -286,6 +311,9 @@ } @override + Iterable<ConstantValue> get initialConstants => _initialConstants ?? const []; + + @override bool get hasPendingNormalUse => !fullyUsed; @override @@ -305,6 +333,13 @@ } @override + EnumSet<MemberUse> constantInit(ConstantValue constant) { + _initialConstants ??= []; + _initialConstants.add(constant); + return init(); + } + + @override EnumSet<MemberUse> read() { if (hasRead) { return MemberUses.NONE; @@ -337,7 +372,8 @@ @override String toString() => 'FinalFieldUsage($entity,hasInit=$hasInit,' - 'hasRead=$hasRead,pendingUse=${_pendingUse.iterable(MemberUse.values)}'; + 'hasRead=$hasRead,pendingUse=${_pendingUse.iterable(MemberUse.values)},' + 'initialConstants=${initialConstants.map((c) => c.toStructuredText())})'; } class FunctionUsage extends MemberUsage { @@ -817,6 +853,9 @@ EnumSet<MemberUse> init() => normalUse(); @override + EnumSet<MemberUse> constantInit(ConstantValue constant) => normalUse(); + + @override EnumSet<MemberUse> read() => tearOff(); @override @@ -829,6 +868,9 @@ EnumSet<MemberUse> fullyUse() => normalUse(); @override + Iterable<ConstantValue> get initialConstants => null; + + @override bool get hasPendingNormalUse => _pendingUse.contains(MemberUse.NORMAL); @override
diff --git a/pkg/compiler/lib/src/universe/resolution_world_builder.dart b/pkg/compiler/lib/src/universe/resolution_world_builder.dart index 008a742..7415ea2 100644 --- a/pkg/compiler/lib/src/universe/resolution_world_builder.dart +++ b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
@@ -776,9 +776,12 @@ case StaticUseKind.SET: useSet.addAll(usage.write()); break; - case StaticUseKind.INIT: + case StaticUseKind.FIELD_INIT: useSet.addAll(usage.init()); break; + case StaticUseKind.FIELD_CONSTANT_INIT: + useSet.addAll(usage.constantInit(staticUse.constant)); + break; case StaticUseKind.INVOKE: registerStaticInvocation(staticUse); useSet.addAll(usage.invoke(staticUse.callStructure));
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart index c8984b2..01b0d07 100644 --- a/pkg/compiler/lib/src/universe/use.dart +++ b/pkg/compiler/lib/src/universe/use.dart
@@ -160,7 +160,8 @@ INVOKE, GET, SET, - INIT, + FIELD_INIT, + FIELD_CONSTANT_INIT, } /// Statically known use of an [Entity]. @@ -174,12 +175,14 @@ final InterfaceType type; final CallStructure callStructure; final ImportEntity deferredImport; + final ConstantValue constant; StaticUse.internal(Entity element, this.kind, {this.type, this.callStructure, this.deferredImport, - typeArgumentsHash: 0}) + typeArgumentsHash: 0, + this.constant}) : this.element = element, this.hashCode = Hashing.listHash([ element, @@ -187,7 +190,8 @@ type, typeArgumentsHash, callStructure, - deferredImport + deferredImport, + constant ]); /// Short textual representation use for testing. @@ -199,7 +203,7 @@ case StaticUseKind.SET: sb.write('set:'); break; - case StaticUseKind.INIT: + case StaticUseKind.FIELD_INIT: sb.write('init:'); break; case StaticUseKind.CLOSURE: @@ -238,6 +242,10 @@ sb.write(deferredImport.name); sb.write('}'); } + if (constant != null) { + sb.write('='); + sb.write(constant.toStructuredText()); + } return sb.toString(); } @@ -321,7 +329,7 @@ "or static method.")); assert(element.isField, failedAt(element, "Static init element $element must be a field.")); - return new StaticUse.internal(element, StaticUseKind.INIT); + return new StaticUse.internal(element, StaticUseKind.FIELD_INIT); } /// Invocation of a super method [element] with the given [callStructure]. @@ -541,7 +549,18 @@ element.isInstanceMember, failedAt( element, "Field init element $element must be an instance field.")); - return new StaticUse.internal(element, StaticUseKind.INIT); + return new StaticUse.internal(element, StaticUseKind.FIELD_INIT); + } + + /// Constant initialization of an instance field [element]. + factory StaticUse.fieldConstantInit( + FieldEntity element, ConstantValue constant) { + assert( + element.isInstanceMember, + failedAt( + element, "Field init element $element must be an instance field.")); + return new StaticUse.internal(element, StaticUseKind.FIELD_CONSTANT_INIT, + constant: constant); } /// Read access of an instance field or boxed field [element]. @@ -603,12 +622,14 @@ @override bool operator ==(other) { if (identical(this, other)) return true; - if (other is! StaticUse) return false; - return element == other.element && + return other is StaticUse && + element == other.element && kind == other.kind && type == other.type && callStructure == other.callStructure && - equalElements(typeArguments, other.typeArguments); + equalElements(typeArguments, other.typeArguments) && + deferredImport == other.deferredImport && + constant == other.constant; } @override
diff --git a/pkg/dartfix/lib/src/driver.dart b/pkg/dartfix/lib/src/driver.dart index ba7cea7..42bec0e 100644 --- a/pkg/dartfix/lib/src/driver.dart +++ b/pkg/dartfix/lib/src/driver.dart
@@ -179,10 +179,8 @@ if (shouldApplyChanges(result)) { for (SourceFileEdit fileEdit in result.edits) { final file = new File(fileEdit.file); - String code = await file.readAsString(); - for (SourceEdit edit in fileEdit.edits) { - code = edit.apply(code); - } + String code = file.existsSync() ? file.readAsStringSync() : ''; + code = SourceEdit.applySequence(code, fileEdit.edits); await file.writeAsString(code); } logger.stdout(ansi.emphasized('Changes applied.'));
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart index 676be05..7a76be5 100644 --- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart +++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -2754,17 +2754,18 @@ body, parameters.parameters.last.declaredElement)); JS.Block code = isSync - ? _emitFunctionBody(element, parameters, body) - : JS.Block([ - _emitGeneratorFunction(element, parameters, body).toReturn() - ..sourceInformation = _nodeStart(body) - ]); + ? _emitSyncFunctionBody(element, parameters, body) + : _emitGeneratorFunctionBody(element, parameters, body); code = super.exitFunction(element.name, formals, code); return JS.Fun(formals, code); } - JS.Block _emitFunctionBody(ExecutableElement element, + /// Emits a `sync` function body (the default in Dart) + /// + /// To emit an `async`, `sync*`, or `async*` function body, use + /// [_emitGeneratorFunctionBody] instead. + JS.Block _emitSyncFunctionBody(ExecutableElement element, FormalParameterList parameters, FunctionBody body) { var savedFunction = _currentFunction; _currentFunction = body; @@ -2785,6 +2786,40 @@ return block; } + /// Emits an `async`, `sync*`, or `async*` function body. + /// + /// The body will perform these steps: + /// + /// - Run the argument initializers. These must be run synchronously + /// (e.g. covariance checks), and this helps performance. + /// - Return the generator function, wrapped with the appropriate type + /// (`Future`, `Itearble`, and `Stream` respectively). + /// + /// To emit a `sync` function body (the default in Dart), use + /// [_emitSyncFunctionBody] instead. + JS.Block _emitGeneratorFunctionBody(ExecutableElement element, + FormalParameterList parameters, FunctionBody body) { + var savedFunction = _currentFunction; + _currentFunction = body; + + var initArgs = _emitArgumentInitializers(element, parameters); + var block = JS.Block([ + _emitGeneratorFunction(element, parameters, body).toReturn() + ..sourceInformation = _nodeStart(body) + ]); + if (initArgs != null) block = JS.Block([initArgs, block]); + + _currentFunction = savedFunction; + + if (block.isScope) { + // TODO(jmesserly: JS AST printer does not understand the need to emit a + // nested scoped block in a JS function. So we need to add a non-scoped + // wrapper to ensure it gets printed. + block = JS.Block([block]); + } + return block; + } + JS.Block _emitFunctionScopedBody( FunctionBody body, ExecutableElement element) { var block = body.accept(this) as JS.Block; @@ -2830,9 +2865,13 @@ // Visit the body with our async* controller set. // - // TODO(jmesserly): this will emit argument initializers (for default - // values) inside the generator function body. Is that the best place? - var jsBody = _emitFunctionBody(element, parameters, body); + // Note: we intentionally don't emit argument initializers here, because + // they were already emitted outside of the generator expression. + var savedFunction = _currentFunction; + _currentFunction = body; + var jsBody = _emitFunctionScopedBody(body, element); + _currentFunction = savedFunction; + var genFn = JS.Fun(jsParams, jsBody, isGenerator: true); // Name the function if possible, to get better stack traces.
diff --git a/pkg/dev_compiler/lib/src/compiler/js_utils.dart b/pkg/dev_compiler/lib/src/compiler/js_utils.dart index a0275c6..74820eb 100644 --- a/pkg/dev_compiler/lib/src/compiler/js_utils.dart +++ b/pkg/dev_compiler/lib/src/compiler/js_utils.dart
@@ -25,18 +25,20 @@ return fn; } -Set<Identifier> findMutatedVariables(Node scope) { +Set<String> findMutatedVariables(Node scope) { var v = MutationVisitor(); scope.accept(v); return v.mutated; } class MutationVisitor extends BaseVisitor { - final mutated = Set<Identifier>(); + /// Using Identifier names instead of a more precise key may result in + /// mutations being imprecisely reported when variables shadow each other. + final mutated = Set<String>(); @override visitAssignment(node) { var id = node.leftHandSide; - if (id is Identifier) mutated.add(id); + if (id is Identifier) mutated.add(id.name); super.visitAssignment(node); } }
diff --git a/pkg/dev_compiler/lib/src/js_ast/builder.dart b/pkg/dev_compiler/lib/src/js_ast/builder.dart index d81f7e3..fc44cb9 100644 --- a/pkg/dev_compiler/lib/src/js_ast/builder.dart +++ b/pkg/dev_compiler/lib/src/js_ast/builder.dart
@@ -293,59 +293,99 @@ return Template.withStatementResult(ast); } - /// Creates a literal js string from [value]. + /// Creates a literal js string from [value], escaped for use in a UTF-8 + /// output. LiteralString escapedString(String value, [String quote = '"']) { - // Start by escaping the backslashes. - String escaped = value.replaceAll('\\', '\\\\'); + int otherEscapes = 0; + int unpairedSurrogates = 0; - // Replace $ in template strings: - // http://www.ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components - var quoteReplace = quote == '`' ? r'`$' : quote; + int quoteRune = quote.codeUnitAt(0); - // http://www.ecma-international.org/ecma-262/6.0/#sec-literals-string-literals - // > All code points may appear literally in a string literal except for the - // > closing quote code points, U+005C (REVERSE SOLIDUS), - // > U+000D (CARRIAGE RETURN), U+2028 (LINE SEPARATOR), - // > U+2029 (PARAGRAPH SEPARATOR), and U+000A (LINE FEED). - var re = RegExp('[\n\r$quoteReplace\b\f\t\v\u2028\u2029]'); - escaped = escaped.replaceAllMapped(re, (m) { - switch (m.group(0)) { - case "\n": - return r"\n"; - case "\r": - return r"\r"; - case "\u2028": - return r"\u2028"; - case "\u2029": - return r"\u2029"; - // Quotes and $ are only replaced if they conflict with the containing - // quote, see regex above. - case '"': - return r'\"'; - case "'": - return r"\'"; - case "`": - return r"\`"; - case r"$": - return r"\$"; - // TODO(jmesserly): these don't need to be escaped for correctness, - // but they are conventionally escaped. - case "\b": - return r"\b"; - case "\t": - return r"\t"; - case "\f": - return r"\f"; - case "\v": - return r"\v"; + for (int rune in value.runes) { + if (rune == charCodes.$BACKSLASH) { + ++otherEscapes; + } else if (rune == charCodes.$LF || + rune == charCodes.$CR || + rune == charCodes.$LS || + rune == charCodes.$PS) { + // Line terminators. + ++otherEscapes; + } else if (rune == charCodes.$BS || + rune == charCodes.$TAB || + rune == charCodes.$VTAB || + rune == charCodes.$FF) { + ++otherEscapes; + } else if (rune == quoteRune || + rune == charCodes.$$ && quoteRune == charCodes.$BACKPING) { + ++otherEscapes; + } else if (_isUnpairedSurrogate(rune)) { + ++unpairedSurrogates; } - throw 'unreachable'; - }); - LiteralString result = LiteralString('$quote$escaped$quote'); - // We don't escape quotes of a different style under the assumption that the - // string is wrapped into quotes. Verify that assumption. - assert(result.value.codeUnitAt(0) == quote.codeUnitAt(0)); - return result; + } + + if (otherEscapes == 0 && unpairedSurrogates == 0) { + return string(value, quote); + } + + var sb = new StringBuffer(); + + for (int rune in value.runes) { + String escape = _irregularEscape(rune, quote); + if (escape != null) { + sb.write(escape); + continue; + } + if (rune == charCodes.$LS || + rune == charCodes.$PS || + _isUnpairedSurrogate(rune)) { + if (rune < 0x100) { + sb.write(r'\x'); + sb.write(rune.toRadixString(16).padLeft(2, '0')); + } else if (rune < 0x10000) { + sb.write(r'\u'); + sb.write(rune.toRadixString(16).padLeft(4, '0')); + } else { + sb.write(r'\u{'); + sb.write(rune.toRadixString(16)); + sb.write('}'); + } + } else { + sb.writeCharCode(rune); + } + } + + return string(sb.toString(), quote); + } + + static bool _isUnpairedSurrogate(int code) => (code & 0xFFFFF800) == 0xD800; + + static String _irregularEscape(int code, String quote) { + switch (code) { + case charCodes.$SQ: + return quote == "'" ? r"\'" : "'"; + case charCodes.$DQ: + return quote == '"' ? r'\"' : '"'; + case charCodes.$BACKPING: + return quote == '`' ? r'\`' : '`'; + case charCodes.$$: + // Escape $ inside of template strings. + return quote == '`' ? r'\$' : r'$'; + case charCodes.$BACKSLASH: + return r'\\'; + case charCodes.$BS: + return r'\b'; + case charCodes.$TAB: + return r'\t'; + case charCodes.$LF: + return r'\n'; + case charCodes.$VTAB: + return r'\v'; + case charCodes.$FF: + return r'\f'; + case charCodes.$CR: + return r'\r'; + } + return null; } /// Creates a literal js string from [value].
diff --git a/pkg/dev_compiler/lib/src/js_ast/nodes.dart b/pkg/dev_compiler/lib/src/js_ast/nodes.dart index 68d15cd..9cd3b7b 100644 --- a/pkg/dev_compiler/lib/src/js_ast/nodes.dart +++ b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
@@ -889,6 +889,8 @@ @override int get precedenceLevel => PRIMARY; @override + String get parameterName => name.name; + @override Node _clone() => DestructuredVariable( name: name, property: property, @@ -1146,7 +1148,9 @@ int get precedenceLevel => UNARY; } -abstract class Parameter implements Expression, VariableBinding {} +abstract class Parameter implements Expression, VariableBinding { + String get parameterName; +} class Identifier extends Expression implements Parameter { final String name; @@ -1164,6 +1168,7 @@ Identifier _clone() => Identifier(name, allowRename: allowRename); T accept<T>(NodeVisitor<T> visitor) => visitor.visitIdentifier(this); int get precedenceLevel => PRIMARY; + String get parameterName => name; void visitChildren(NodeVisitor visitor) {} } @@ -1182,6 +1187,7 @@ } int get precedenceLevel => PRIMARY; + String get parameterName => parameter.parameterName; } class This extends Expression { @@ -1641,6 +1647,10 @@ throw "InterpolatedParameter.name must not be invoked"; } + String get parameterName { + throw "InterpolatedParameter.parameterName must not be invoked"; + } + bool shadows(Set<String> names) => false; bool get allowRename => false; @@ -1718,6 +1728,8 @@ int get precedenceLevel => PRIMARY; String get name => throw '$runtimeType does not support this member.'; + String get parameterName => + throw '$runtimeType does not support this member.'; bool get allowRename => false; }
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart index 6076be4..55f5c10 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -1811,8 +1811,20 @@ if (isUnsupportedFactoryConstructor(node)) return null; var function = node.function; + + /// Note: factory constructors can't use `sync*`/`async*`/`async` bodies + /// because it would return the wrong type, so we can assume `sync` here. + /// + /// We can also skip the logic in [_emitFunction] related to operator + /// methods like ==, as well as generic method parameters. + /// + /// If a future Dart version allows factory constructors to take their + /// own type parameters, this will need to be changed to call + /// [_emitFunction] instead. + var jsBody = _emitSyncFunctionBody(function); + return JS.Method(_constructorName(node.name.name), - JS.Fun(_emitParameters(function), _emitFunctionBody(function)), + JS.Fun(_emitParameters(function), jsBody), isStatic: true) ..sourceInformation = _nodeEnd(node.fileEndOffset); } @@ -2653,16 +2665,11 @@ // potentially mutated in Kernel. For now we assume all parameters are. super.enterFunction(name, formals, () => true); - JS.Block code = isSync - ? _emitFunctionBody(f) - : JS.Block([ - _emitGeneratorFunction(f, name).toReturn() - ..sourceInformation = _nodeStart(f) - ]); + JS.Block block = + isSync ? _emitSyncFunctionBody(f) : _emitGeneratorFunctionBody(f, name); - code = super.exitFunction(name, formals, code); - - return JS.Fun(formals, code); + block = super.exitFunction(name, formals, block); + return JS.Fun(formals, block); } List<JS.Parameter> _emitParameters(FunctionNode f) { @@ -2692,10 +2699,13 @@ .toList(); } - JS.Expression _emitGeneratorFunction(FunctionNode function, String name) { - // Transforms `sync*` `async` and `async*` function bodies - // using ES6 generators. - + /// Transforms `sync*` `async` and `async*` function bodies + /// using ES6 generators. + /// + /// This is an internal part of [_emitGeneratorFunctionBody] and should not be + /// called directly. + JS.Expression _emitGeneratorFunctionExpression( + FunctionNode function, String name) { emitGeneratorFn(List<JS.Parameter> getParameters(JS.Block jsBody)) { var savedController = _asyncStarController; _asyncStarController = function.asyncMarker == AsyncMarker.AsyncStar @@ -2706,9 +2716,10 @@ _superDisallowed(() { // Visit the body with our async* controller set. // - // TODO(jmesserly): this will emit argument initializers (for default - // values) inside the generator function body. Is that the best place? - var jsBody = _emitFunctionBody(function); + // Note: we intentionally don't emit argument initializers here, because + // they were already emitted outside of the generator expression. + var jsBody = JS.Block(_withCurrentFunction( + function, () => [_emitFunctionScopedBody(function)])); var genFn = JS.Fun(getParameters(jsBody), jsBody, isGenerator: true); // Name the function if possible, to get better stack traces. @@ -2746,9 +2757,16 @@ // In the future, we might be able to simplify this, see: // https://github.com/dart-lang/sdk/issues/28320 var jsParams = _emitParameters(function); - var gen = emitGeneratorFn((fnBody) => jsParams = - jsParams.where(JS.findMutatedVariables(fnBody).contains).toList()); - if (jsParams.isNotEmpty) gen = js.call('() => #(#)', [gen, jsParams]); + var mutatedParams = jsParams; + var gen = emitGeneratorFn((fnBody) { + var mutatedVars = JS.findMutatedVariables(fnBody); + mutatedParams = jsParams + .where((id) => mutatedVars.contains(id.parameterName)) + .toList(); + return mutatedParams; + }); + if (mutatedParams.isNotEmpty) + gen = js.call('() => #(#)', [gen, mutatedParams]); var returnType = _getExpectedReturnType(function, coreTypes.iterableClass); @@ -2801,8 +2819,16 @@ return const DynamicType(); } - JS.Block _emitFunctionBody(FunctionNode f) { + /// Emits a `sync` function body (the default in Dart) + /// + /// To emit an `async`, `sync*`, or `async*` function body, use + /// [_emitGeneratorFunctionBody] instead. + JS.Block _emitSyncFunctionBody(FunctionNode f) { + assert(f.asyncMarker == AsyncMarker.Sync); + var block = _withCurrentFunction(f, () { + /// For (normal) `sync` bodies, execute the function body immediately + /// after the argument initializers. var block = _emitArgumentInitializers(f); block.add(_emitFunctionScopedBody(f)); return block; @@ -2811,6 +2837,27 @@ return JS.Block(block); } + /// Emits an `async`, `sync*`, or `async*` function body. + /// + /// The body will perform these steps: + /// + /// - Run the argument initializers. These must be run synchronously + /// (e.g. covariance checks), and this helps performance. + /// - Return the generator function, wrapped with the appropriate type + /// (`Future`, `Itearble`, and `Stream` respectively). + /// + /// To emit a `sync` function body (the default in Dart), use + /// [_emitSyncFunctionBody] instead. + JS.Block _emitGeneratorFunctionBody(FunctionNode f, String name) { + assert(f.asyncMarker != AsyncMarker.Sync); + + var statements = + _withCurrentFunction(f, () => _emitArgumentInitializers(f)); + statements.add(_emitGeneratorFunctionExpression(f, name).toReturn() + ..sourceInformation = _nodeStart(f)); + return JS.Block(statements); + } + List<JS.Statement> _withCurrentFunction( FunctionNode fn, List<JS.Statement> action()) { var savedFunction = _currentFunction; @@ -3093,7 +3140,7 @@ // // NOTE: we do sometimes need to handle this because Dart and JS rules are // slightly different (in Dart, there is a nested scope), but that's handled - // by _emitFunctionBody. + // by _emitSyncFunctionBody. var isScope = !identical(node.parent, _currentFunction); return JS.Block(node.statements.map(_visitStatement).toList(), isScope: isScope); @@ -4745,6 +4792,12 @@ } @override + visitInstanceCreation(InstanceCreation node) { + // Only occurs inside unevaluated constants. + throw new UnsupportedError("Instance creation"); + } + + @override visitIsExpression(IsExpression node) { return _emitIsExpression(node.operand, node.type); }
diff --git a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart index 76b6570..1ecdfc0 100644 --- a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart +++ b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
@@ -230,7 +230,9 @@ @override visitConstantExpression(ConstantExpression node) { var c = node.constant; - return c is PrimitiveConstant && c.value == null; + if (c is UnevaluatedConstant) return c.expression.accept(this); + if (c is PrimitiveConstant) return c.value == null; + return false; } @override
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb index ea3a7a5..b5cb2fa 100755 --- a/pkg/dev_compiler/tool/ddb +++ b/pkg/dev_compiler/tool/ddb
@@ -40,6 +40,8 @@ abbr: 'p', help: 'Run with the corresponding chrome/V8 debugging port open.', defaultsTo: '9222') + ..addOption('enable-experiment', + help: 'Run with specified experiments enabled.', defaultsTo: '') ..addOption('binary', abbr: 'b', help: 'Runtime binary path.'); var options = parser.parse(args); @@ -53,6 +55,7 @@ var debug = options['debug'] as bool; var kernel = options['kernel'] as bool; var binary = options['binary'] as String; + var experiment = options['enable-experiment'] as String; var port = int.parse(options['port'] as String); var dartBinary = Platform.resolvedExecutable; @@ -121,6 +124,7 @@ '--kernel', '--modules=$mod', '--dart-sdk-summary=$ddcSdk', + '--enable-experiment=$experiment', '-o', '$libRoot/$basename.js', entry @@ -130,6 +134,7 @@ '--modules=$mod', '--dart-sdk-summary=$ddcSdk', '--library-root=$libRoot', + '--enable-experiment=$experiment', '-o', '$libRoot/$basename.js', entry
diff --git a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart index 4f0b8a3..6f37ab2 100644 --- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart +++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -89,7 +89,8 @@ ..librariesSpecificationUri = librariesSpecificationUri ..target = target ..fileSystem = fileSystem - ..omitPlatform = true; + ..omitPlatform = true + ..environmentDefines = const {}; processedOpts = new ProcessedOptions(options: options); cachedSdkInput = WorkerInputComponent( @@ -190,7 +191,8 @@ ..inputSummaries = summaryInputs ..linkedDependencies = linkedInputs ..target = target - ..fileSystem = fileSystem; + ..fileSystem = fileSystem + ..environmentDefines = const {}; ProcessedOptions processedOpts = new ProcessedOptions(options: options);
diff --git a/pkg/front_end/lib/src/api_unstable/dart2js.dart b/pkg/front_end/lib/src/api_unstable/dart2js.dart index 7b95a51..8ec174d 100644 --- a/pkg/front_end/lib/src/api_unstable/dart2js.dart +++ b/pkg/front_end/lib/src/api_unstable/dart2js.dart
@@ -114,7 +114,8 @@ Uri packagesFileUri, {List<Uri> dependencies, Map<ExperimentalFlag, bool> experimentalFlags, - bool verify: false}) { + bool verify: false, + bool enableAsserts: false}) { bool mapEqual(Map<ExperimentalFlag, bool> a, Map<ExperimentalFlag, bool> b) { if (a == null || b == null) return a == b; if (a.length != b.length) return false; @@ -149,7 +150,8 @@ ..librariesSpecificationUri = librariesSpecificationUri ..packagesFileUri = packagesFileUri ..experimentalFlags = experimentalFlags - ..verify = verify; + ..verify = verify + ..enableAsserts = enableAsserts; ProcessedOptions processedOpts = new ProcessedOptions(options: options);
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 828f7a4..de4fb58 100644 --- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart +++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -1102,6 +1102,36 @@ } // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Template< + Message Function( + Constant + _constant)> templateConstEvalElementImplementsEqual = const Template< + Message Function(Constant _constant)>( + messageTemplate: + r"""The element '#constant' does not have a primitive operator '=='.""", + withArguments: _withArgumentsConstEvalElementImplementsEqual); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code<Message Function(Constant _constant)> + codeConstEvalElementImplementsEqual = + const Code<Message Function(Constant _constant)>( + "ConstEvalElementImplementsEqual", + templateConstEvalElementImplementsEqual, + analyzerCodes: <String>["CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS"]); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +Message _withArgumentsConstEvalElementImplementsEqual(Constant _constant) { + TypeLabeler labeler = new TypeLabeler(); + List<Object> constantParts = labeler.labelConstant(_constant); + String constant = constantParts.join(); + return new Message(codeConstEvalElementImplementsEqual, + message: + """The element '${constant}' does not have a primitive operator '=='.""" + + labeler.originMessages, + arguments: {'constant': _constant}); +} + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Code<Null> codeConstEvalFailedAssertion = messageConstEvalFailedAssertion; // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. @@ -1212,6 +1242,40 @@ // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Template< Message Function( + Constant _constant, + DartType + _type)> templateConstEvalInvalidEqualsOperandType = const Template< + Message Function(Constant _constant, DartType _type)>( + messageTemplate: + r"""Binary operator '==' requires receiver constant '#constant' of type 'Null', 'bool', 'int', 'double', or 'String', but was of type '#type'.""", + withArguments: _withArgumentsConstEvalInvalidEqualsOperandType); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code<Message Function(Constant _constant, DartType _type)> + codeConstEvalInvalidEqualsOperandType = + const Code<Message Function(Constant _constant, DartType _type)>( + "ConstEvalInvalidEqualsOperandType", + templateConstEvalInvalidEqualsOperandType, +); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +Message _withArgumentsConstEvalInvalidEqualsOperandType( + Constant _constant, DartType _type) { + TypeLabeler labeler = new TypeLabeler(); + List<Object> constantParts = labeler.labelConstant(_constant); + List<Object> typeParts = labeler.labelType(_type); + String constant = constantParts.join(); + String type = typeParts.join(); + return new Message(codeConstEvalInvalidEqualsOperandType, + message: + """Binary operator '==' requires receiver constant '${constant}' of type 'Null', 'bool', 'int', 'double', or 'String', but was of type '${type}'.""" + + labeler.originMessages, + arguments: {'constant': _constant, 'type': _type}); +} + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Template< + Message Function( String string, Constant _constant)> templateConstEvalInvalidMethodInvocation = const Template< @@ -1429,6 +1493,35 @@ message: r"""Iteration can't be used in a constant set."""); // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Template<Message Function(Constant _constant)> + templateConstEvalKeyImplementsEqual = + const Template<Message Function(Constant _constant)>( + messageTemplate: + r"""The key '#constant' does not have a primitive operator '=='.""", + withArguments: _withArgumentsConstEvalKeyImplementsEqual); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code<Message Function(Constant _constant)> + codeConstEvalKeyImplementsEqual = + const Code<Message Function(Constant _constant)>( + "ConstEvalKeyImplementsEqual", templateConstEvalKeyImplementsEqual, + analyzerCodes: <String>[ + "CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS" + ]); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +Message _withArgumentsConstEvalKeyImplementsEqual(Constant _constant) { + TypeLabeler labeler = new TypeLabeler(); + List<Object> constantParts = labeler.labelConstant(_constant); + String constant = constantParts.join(); + return new Message(codeConstEvalKeyImplementsEqual, + message: + """The key '${constant}' does not have a primitive operator '=='.""" + + labeler.originMessages, + arguments: {'constant': _constant}); +} + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Template< Message Function( String string, @@ -2539,7 +2632,7 @@ const Template<Message Function(Token token)> templateDuplicatedModifier = const Template<Message Function(Token token)>( messageTemplate: r"""The modifier '#lexeme' was already specified.""", - tipTemplate: r"""Try removing all but one occurance of the modifier.""", + tipTemplate: r"""Try removing all but one occurence of the modifier.""", withArguments: _withArgumentsDuplicatedModifier); // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. @@ -2553,7 +2646,7 @@ String lexeme = token.lexeme; return new Message(codeDuplicatedModifier, message: """The modifier '${lexeme}' was already specified.""", - tip: """Try removing all but one occurance of the modifier.""", + tip: """Try removing all but one occurence of the modifier.""", arguments: {'token': token}); } @@ -3159,7 +3252,7 @@ // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const MessageCode messageExportAfterPart = const MessageCode("ExportAfterPart", index: 75, - message: r"""Export directives must preceed part directives.""", + message: r"""Export directives must precede part directives.""", tip: r"""Try moving the export directives before the part directives."""); // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. @@ -4415,7 +4508,7 @@ // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const MessageCode messageImportAfterPart = const MessageCode("ImportAfterPart", index: 10, - message: r"""Import directives must preceed part directives.""", + message: r"""Import directives must precede part directives.""", tip: r"""Try moving the import directives before the part directives."""); // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. @@ -6693,7 +6786,7 @@ "MissingOperatorKeyword", index: 31, message: - r"""Operator declarations must be preceeded by the keyword 'operator'.""", + r"""Operator declarations must be preceded by the keyword 'operator'.""", tip: r"""Try adding the keyword 'operator'."""); // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. @@ -9211,6 +9304,16 @@ } // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code<Null> codeTypeBeforeFactory = messageTypeBeforeFactory; + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const MessageCode messageTypeBeforeFactory = const MessageCode( + "TypeBeforeFactory", + index: 97, + message: r"""Factory constructors cannot have a return type.""", + tip: r"""Try removing the type appearing before 'factory'."""); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Template<Message Function(String name)> templateTypeNotFound = const Template<Message Function(String name)>( messageTemplate: r"""Type '#name' not found.""",
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart index 203386b..e360c2e 100644 --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -68,14 +68,10 @@ import 'collections.dart' show - ForElement, - ForInElement, - ForInMapEntry, - ForMapEntry, - IfElement, - IfMapEntry, SpreadElement, - SpreadMapEntry; + SpreadMapEntry, + convertToMapEntry, + isConvertibleToMapEntry; import 'constness.dart' show Constness; @@ -914,10 +910,22 @@ void resolveRedirectingFactoryTargets() { for (StaticInvocation invocation in redirectingFactoryInvocations) { - // If the invocation was invalid, it has already been desugared into - // an exception throwing expression. There is nothing to resolve anymore. - if (invocation.parent == null) { - continue; + // If the invocation was invalid, it or its parent has already been + // desugared into an exception throwing expression. There is nothing to + // resolve anymore. Note that in the case where the invocation's parent + // was invalid, type inference won't reach the invocation node and won't + // set its inferredType field. If type inference is disabled, reach to + // the outtermost parent to check if the node is a dead code. + if (invocation.parent == null) continue; + if (_typeInferrer != null) { + if (invocation is FactoryConstructorInvocationJudgment && + invocation.inferredType == null) { + continue; + } + } else { + TreeNode parent = invocation.parent; + while (parent is! Component && parent != null) parent = parent.parent; + if (parent == null) continue; } Procedure initialTarget = invocation.target; @@ -2308,10 +2316,6 @@ push(invalidCollectionElement); return; } - if (entry == invalidCollectionElement) { - push(invalidCollectionElement); - return; - } transformCollections = true; List<VariableDeclaration> variables = buildVariableDeclarations(variableOrExpression); @@ -2545,7 +2549,7 @@ if (setOrMapEntries[i] is MapEntry) { mapEntries[i] = setOrMapEntries[i]; } else { - mapEntries[i] = convertToMapEntry(setOrMapEntries[i]); + mapEntries[i] = convertToMapEntry(setOrMapEntries[i], this); } } buildLiteralMap(typeArguments, constKeyword, leftBrace, mapEntries); @@ -2572,56 +2576,6 @@ push(forest.literalNull(token)); } - bool isConvertibleToMapEntry(Expression element) { - if (element is SpreadElement) return true; - if (element is IfElement) { - return isConvertibleToMapEntry(element.then) && - (element.otherwise == null || - isConvertibleToMapEntry(element.otherwise)); - } - if (element is ForElement) { - return isConvertibleToMapEntry(element.body); - } - if (element is ForInElement) { - return isConvertibleToMapEntry(element.body); - } - return false; - } - - MapEntry convertToMapEntry(Expression element) { - if (element is SpreadElement) { - return new SpreadMapEntry(element.expression, element.isNullAware) - ..fileOffset = element.expression.fileOffset; - } - if (element is IfElement) { - return new IfMapEntry( - element.condition, - convertToMapEntry(element.then), - element.otherwise == null - ? null - : convertToMapEntry(element.otherwise)) - ..fileOffset = element.fileOffset; - } - if (element is ForElement) { - return new ForMapEntry(element.variables, element.condition, - element.updates, convertToMapEntry(element.body)) - ..fileOffset = element.fileOffset; - } - if (element is ForInElement) { - return new ForInMapEntry(element.variable, element.iterable, - element.prologue, convertToMapEntry(element.body), element.problem) - ..fileOffset = element.fileOffset; - } - return new MapEntry( - desugarSyntheticExpression(buildProblem( - fasta.templateExpectedAfterButGot.withArguments(':'), - element.fileOffset, - // TODO(danrubel): what is the length of the expression? - 1, - )), - new NullLiteral()); - } - void buildLiteralMap(List<UnresolvedType<KernelTypeBuilder>> typeArguments, Token constKeyword, Token leftBrace, List<MapEntry> entries) { DartType keyType; @@ -3726,13 +3680,25 @@ token.next, token.offset, Constness.explicitConst); } + @override void beginIfControlFlow(Token ifToken) { // TODO(danrubel): consider removing this when control flow support is added // if the ifToken is not needed for error reporting push(ifToken); } - void handleElseControlFlow(Token elseToken) {} + @override + void beginThenControlFlow(Token token) { + Expression condition = popForValue(); + enterThenForTypePromotion(condition); + push(condition); + super.beginThenControlFlow(token); + } + + @override + void handleElseControlFlow(Token elseToken) { + typePromoter?.enterElse(); + } @override void endIfControlFlow(Token token) { @@ -3740,6 +3706,8 @@ var entry = pop(); var condition = pop(); // parenthesized expression Token ifToken = pop(); + typePromoter?.enterElse(); + typePromoter?.exitConditional(); if (!library.loader.target.enableControlFlowCollections) { // TODO(danrubel): Report a more user friendly error message // when an experiment is not enabled @@ -3750,10 +3718,6 @@ push(invalidCollectionElement); return; } - if (entry == invalidCollectionElement) { - push(invalidCollectionElement); - return; - } transformCollections = true; if (entry is MapEntry) { push(forest.ifMapEntry(toValue(condition), entry, null, ifToken)); @@ -3769,6 +3733,7 @@ var thenEntry = pop(); // then entry var condition = pop(); // parenthesized expression Token ifToken = pop(); + typePromoter?.exitConditional(); if (!library.loader.target.enableControlFlowCollections) { // TODO(danrubel): Report a more user friendly error message // when an experiment is not enabled @@ -3779,11 +3744,6 @@ push(invalidCollectionElement); return; } - if (thenEntry == invalidCollectionElement || - elseEntry == invalidCollectionElement) { - push(invalidCollectionElement); - return; - } transformCollections = true; if (thenEntry is MapEntry) { if (elseEntry is MapEntry) { @@ -3796,7 +3756,16 @@ new SpreadMapEntry(elseEntry.expression, elseEntry.isNullAware), ifToken)); } else { - push(invalidCollectionElement); + int offset = elseEntry is Expression + ? elseEntry.fileOffset + : offsetForToken(ifToken); + push(new MapEntry( + desugarSyntheticExpression(buildProblem( + fasta.templateExpectedAfterButGot.withArguments(':'), + offset, + 1)), + new NullLiteral()) + ..fileOffset = offsetForToken(ifToken)); } } else if (elseEntry is MapEntry) { if (thenEntry is SpreadElement) { @@ -3806,7 +3775,16 @@ elseEntry, ifToken)); } else { - push(invalidCollectionElement); + int offset = thenEntry is Expression + ? thenEntry.fileOffset + : offsetForToken(ifToken); + push(new MapEntry( + desugarSyntheticExpression(buildProblem( + fasta.templateExpectedAfterButGot.withArguments(':'), + offset, + 1)), + new NullLiteral()) + ..fileOffset = offsetForToken(ifToken)); } } else { push(forest.ifElement( @@ -4137,10 +4115,6 @@ push(invalidCollectionElement); return; } - if (entry == invalidCollectionElement) { - push(invalidCollectionElement); - return; - } transformCollections = true; VariableDeclaration variable = buildForInVariable(lvalue); Expression problem = checkForInVariable(lvalue, variable, forToken);
diff --git a/pkg/front_end/lib/src/fasta/kernel/collections.dart b/pkg/front_end/lib/src/fasta/kernel/collections.dart index c3a79d1..a943ece 100644 --- a/pkg/front_end/lib/src/fasta/kernel/collections.dart +++ b/pkg/front_end/lib/src/fasta/kernel/collections.dart
@@ -10,11 +10,12 @@ DartType, Expression, MapEntry, - setParents, + NullLiteral, Statement, - transformList, TreeNode, VariableDeclaration, + setParents, + transformList, visitList; import 'package:kernel/type_environment.dart' show TypeEnvironment; @@ -27,8 +28,13 @@ TreeVisitor, Visitor; +import '../messages.dart' + show templateExpectedAfterButGot, templateExpectedButGot; + import '../problems.dart' show getFileUri, unsupported; +import '../type_inference/inference_helper.dart' show InferenceHelper; + /// Mixin for spread and control-flow elements. /// /// Spread and control-flow elements are not truly expressions and they cannot @@ -55,6 +61,11 @@ class SpreadElement extends Expression with ControlFlowElement { Expression expression; bool isNullAware; + + /// The type of the elements of the collection that [expression] evaluates to. + /// + /// It is set during type inference and is used to add appropriate type casts + /// during the desugaring. DartType elementType; SpreadElement(this.expression, this.isNullAware) { @@ -228,6 +239,11 @@ class SpreadMapEntry extends TreeNode with ControlFlowMapEntry { Expression expression; bool isNullAware; + + /// The type of the map entries of the map that [expression] evaluates to. + /// + /// It is set during type inference and is used to add appropriate type casts + /// during the desugaring. DartType entryType; SpreadMapEntry(this.expression, this.isNullAware) { @@ -371,3 +387,90 @@ } } } + +Expression convertToElement(MapEntry entry, InferenceHelper helper) { + if (entry is SpreadMapEntry) { + return new SpreadElement(entry.expression, entry.isNullAware) + ..fileOffset = entry.expression.fileOffset; + } + if (entry is IfMapEntry) { + return new IfElement( + entry.condition, + convertToElement(entry.then, helper), + entry.otherwise == null + ? null + : convertToElement(entry.otherwise, helper)) + ..fileOffset = entry.fileOffset; + } + if (entry is ForMapEntry) { + return new ForElement(entry.variables, entry.condition, entry.updates, + convertToElement(entry.body, helper)) + ..fileOffset = entry.fileOffset; + } + if (entry is ForInMapEntry) { + return new ForInElement(entry.variable, entry.iterable, entry.prologue, + convertToElement(entry.body, helper), entry.problem, + isAsync: entry.isAsync) + ..fileOffset = entry.fileOffset; + } + return helper.desugarSyntheticExpression(helper.buildProblem( + templateExpectedButGot.withArguments(','), + entry.fileOffset, + 1, + )); +} + +bool isConvertibleToMapEntry(Expression element) { + if (element is SpreadElement) return true; + if (element is IfElement) { + return isConvertibleToMapEntry(element.then) && + (element.otherwise == null || + isConvertibleToMapEntry(element.otherwise)); + } + if (element is ForElement) { + return isConvertibleToMapEntry(element.body); + } + if (element is ForInElement) { + return isConvertibleToMapEntry(element.body); + } + return false; +} + +MapEntry convertToMapEntry(Expression element, InferenceHelper helper) { + if (element is SpreadElement) { + return new SpreadMapEntry(element.expression, element.isNullAware) + ..fileOffset = element.expression.fileOffset; + } + if (element is IfElement) { + return new IfMapEntry( + element.condition, + convertToMapEntry(element.then, helper), + element.otherwise == null + ? null + : convertToMapEntry(element.otherwise, helper)) + ..fileOffset = element.fileOffset; + } + if (element is ForElement) { + return new ForMapEntry(element.variables, element.condition, + element.updates, convertToMapEntry(element.body, helper)) + ..fileOffset = element.fileOffset; + } + if (element is ForInElement) { + return new ForInMapEntry( + element.variable, + element.iterable, + element.prologue, + convertToMapEntry(element.body, helper), + element.problem, + isAsync: element.isAsync) + ..fileOffset = element.fileOffset; + } + return new MapEntry( + helper.desugarSyntheticExpression(helper.buildProblem( + templateExpectedAfterButGot.withArguments(':'), + element.fileOffset, + // TODO(danrubel): what is the length of the expression? + 1, + )), + new NullLiteral()); +}
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart index 85c5de0..d35150d 100644 --- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart +++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -49,15 +49,18 @@ templateConstEvalDeferredLibrary, templateConstEvalDuplicateElement, templateConstEvalDuplicateKey, + templateConstEvalElementImplementsEqual, templateConstEvalFailedAssertionWithMessage, templateConstEvalFreeTypeParameter, templateConstEvalInvalidType, templateConstEvalInvalidBinaryOperandType, + templateConstEvalInvalidEqualsOperandType, templateConstEvalInvalidMethodInvocation, templateConstEvalInvalidPropertyGet, templateConstEvalInvalidStaticInvocation, templateConstEvalInvalidStringInterpolationOperand, templateConstEvalInvalidSymbolName, + templateConstEvalKeyImplementsEqual, templateConstEvalNegativeShift, templateConstEvalNonConstantLiteral, templateConstEvalNonConstantVariableGet, @@ -122,6 +125,22 @@ } } +class JavaScriptIntConstant extends DoubleConstant { + final BigInt bigIntValue; + JavaScriptIntConstant(int value) : this.fromBigInt(BigInt.from(value)); + JavaScriptIntConstant.fromDouble(double value) + : bigIntValue = BigInt.from(value), + super(value); + JavaScriptIntConstant.fromBigInt(this.bigIntValue) + : super(bigIntValue.toDouble()); + JavaScriptIntConstant.fromUInt64(int value) + : this.fromBigInt(BigInt.from(value).toUnsigned(64)); + + DartType getType(TypeEnvironment types) => types.intType; + + String toString() => '$bigIntValue'; +} + class ConstantsTransformer extends Transformer { final ConstantEvaluator constantEvaluator; final TypeEnvironment typeEnvironment; @@ -245,7 +264,7 @@ void transformExpressions(List<Expression> nodes, TreeNode parent) { constantEvaluator.withNewEnvironment(() { for (int i = 0; i < nodes.length; ++i) { - nodes[i] = tryEvaluateAndTransformWithContext(parent, nodes[i]) + nodes[i] = evaluateAndTransformWithContext(parent, nodes[i]) ..parent = parent; } }); @@ -260,7 +279,7 @@ transformAnnotations(variable.annotations, variable); if (variable.initializer != null) { variable.initializer = - tryEvaluateAndTransformWithContext(variable, variable.initializer) + evaluateAndTransformWithContext(variable, variable.initializer) ..parent = variable; } } @@ -268,7 +287,7 @@ transformAnnotations(variable.annotations, variable); if (variable.initializer != null) { variable.initializer = - tryEvaluateAndTransformWithContext(variable, variable.initializer) + evaluateAndTransformWithContext(variable, variable.initializer) ..parent = variable; } } @@ -283,26 +302,20 @@ if (node.initializer != null) { if (node.isConst) { - final Constant constant = - tryEvaluateWithContext(node, node.initializer); + final Constant constant = evaluateWithContext(node, node.initializer); + constantEvaluator.env.addVariableValue(node, constant); - // If there was a constant evaluation error we will not continue and - // simply keep the old [node]. - if (constant != null) { - constantEvaluator.env.addVariableValue(node, constant); - - if (keepVariables) { - // So the value of the variable is still available for debugging - // purposes we convert the constant variable to be a final variable - // initialized to the evaluated constant expression. - node.initializer = makeConstantExpression(constant)..parent = node; - node.isFinal = true; - node.isConst = false; - } else { - // Since we convert all use-sites of constants, the constant - // [VariableDeclaration] is unused and we'll therefore remove it. - return null; - } + if (keepVariables) { + // So the value of the variable is still available for debugging + // purposes we convert the constant variable to be a final variable + // initialized to the evaluated constant expression. + node.initializer = makeConstantExpression(constant)..parent = node; + node.isFinal = true; + node.isConst = false; + } else { + // Since we convert all use-sites of constants, the constant + // [VariableDeclaration] is unused and we'll therefore remove it. + return null; } } else { node.initializer = node.initializer.accept(this)..parent = node; @@ -325,7 +338,7 @@ transformAnnotations(node.annotations, node); if (node.initializer != null) { node.initializer = - tryEvaluateAndTransformWithContext(node, node.initializer) + evaluateAndTransformWithContext(node, node.initializer) ..parent = node; } } else { @@ -347,11 +360,9 @@ visitStaticGet(StaticGet node) { final Member target = node.target; if (target is Field && target.isConst) { - final Constant constant = - tryEvaluateWithContext(node, target.initializer); - return constant != null ? makeConstantExpression(constant) : node; + return evaluateAndTransformWithContext(node, target.initializer); } else if (target is Procedure && target.kind == ProcedureKind.Method) { - return tryEvaluateAndTransformWithContext(node, node); + return evaluateAndTransformWithContext(node, node); } return super.visitStaticGet(node); } @@ -363,42 +374,42 @@ visitVariableGet(VariableGet node) { if (node.variable.isConst) { - return tryEvaluateAndTransformWithContext(node, node); + return evaluateAndTransformWithContext(node, node); } return super.visitVariableGet(node); } visitListLiteral(ListLiteral node) { if (node.isConst) { - return tryEvaluateAndTransformWithContext(node, node); + return evaluateAndTransformWithContext(node, node); } return super.visitListLiteral(node); } visitSetLiteral(SetLiteral node) { if (node.isConst) { - return tryEvaluateAndTransformWithContext(node, node); + return evaluateAndTransformWithContext(node, node); } return super.visitSetLiteral(node); } visitMapLiteral(MapLiteral node) { if (node.isConst) { - return tryEvaluateAndTransformWithContext(node, node); + return evaluateAndTransformWithContext(node, node); } return super.visitMapLiteral(node); } visitConstructorInvocation(ConstructorInvocation node) { if (node.isConst) { - return tryEvaluateAndTransformWithContext(node, node); + return evaluateAndTransformWithContext(node, node); } return super.visitConstructorInvocation(node); } visitStaticInvocation(StaticInvocation node) { if (node.isConst) { - return tryEvaluateAndTransformWithContext(node, node); + return evaluateAndTransformWithContext(node, node); } return super.visitStaticInvocation(node); } @@ -407,19 +418,18 @@ Constant constant = node.constant; if (constant is UnevaluatedConstant) { Expression expression = constant.expression; - return tryEvaluateAndTransformWithContext(expression, expression); + return evaluateAndTransformWithContext(expression, expression); } else { node.constant = constantEvaluator.canonicalize(constant); return node; } } - tryEvaluateAndTransformWithContext(TreeNode treeContext, Expression node) { - final Constant constant = tryEvaluateWithContext(treeContext, node); - return constant != null ? makeConstantExpression(constant) : node; + evaluateAndTransformWithContext(TreeNode treeContext, Expression node) { + return makeConstantExpression(evaluateWithContext(treeContext, node)); } - tryEvaluateWithContext(TreeNode treeContext, Expression node) { + evaluateWithContext(TreeNode treeContext, Expression node) { if (treeContext == node) { return constantEvaluator.evaluate(node); } @@ -456,6 +466,8 @@ final Map<Node, Object> nodeCache; final CloneVisitor cloner = new CloneVisitor(); + Map<Class, bool> primitiveEqualCache; + final NullConstant nullConstant = new NullConstant(); final BoolConstant trueConstant = new BoolConstant(true); final BoolConstant falseConstant = new BoolConstant(false); @@ -485,7 +497,22 @@ unmodifiableSetMap = desugarSets ? typeEnvironment.coreTypes.index .getMember('dart:collection', '_UnmodifiableSet', '_map') - : null; + : null { + primitiveEqualCache = <Class, bool>{ + coreTypes.boolClass: true, + coreTypes.doubleClass: false, + coreTypes.intClass: true, + coreTypes.internalSymbolClass: true, + coreTypes.listClass: true, + coreTypes.mapClass: true, + coreTypes.nullClass: true, + coreTypes.objectClass: true, + coreTypes.setClass: true, + coreTypes.stringClass: true, + coreTypes.symbolClass: true, + coreTypes.typeClass: true, + }; + } Uri getFileUri(TreeNode node) { while (node != null && node is! FileUriNode) { @@ -671,13 +698,15 @@ visitNullLiteral(NullLiteral node) => nullConstant; visitBoolLiteral(BoolLiteral node) { - return node.value ? trueConstant : falseConstant; + return makeBoolConstant(node.value); } visitIntLiteral(IntLiteral node) { - // The frontend will ensure the integer literals are in signed 64-bit - // range. - return canonicalize(new IntConstant(node.value)); + // The frontend ensures that integer literals are valid according to the + // target representation. + return targetingJavaScript + ? canonicalize(new JavaScriptIntConstant.fromUInt64(node.value)) + : canonicalize(new IntConstant(node.value)); } visitDoubleLiteral(DoubleLiteral node) { @@ -700,6 +729,14 @@ result = runInsideContext(constant.expression, () { return _evaluateSubexpression(constant.expression); }); + } else if (targetingJavaScript) { + if (constant is DoubleConstant) { + double value = constant.value; + // TODO(askesc, fishythefish): Handle infinite integers. + if (value.isFinite && value.truncateToDouble() == value) { + result = new JavaScriptIntConstant.fromDouble(value); + } + } } // If there were already constants in the AST then we make sure we // re-canonicalize them. After running the transformer we will therefore @@ -828,12 +865,19 @@ } else { parts.add(listOrSet = <Constant>[]); } - if (isSet && !seen.add(constant)) { - report(element, - templateConstEvalDuplicateElement.withArguments(constant)); - } else { - listOrSet.add(ensureIsSubtype(constant, elementType, element)); + if (isSet) { + if (!hasPrimitiveEqual(constant)) { + report( + element, + templateConstEvalElementImplementsEqual + .withArguments(constant)); + } + if (!seen.add(constant)) { + report(element, + templateConstEvalDuplicateElement.withArguments(constant)); + } } + listOrSet.add(ensureIsSubtype(constant, elementType, element)); } } } @@ -1051,13 +1095,16 @@ } else { parts.add(entries = <ConstantMapEntry>[]); } + if (!hasPrimitiveEqual(key)) { + report( + element, templateConstEvalKeyImplementsEqual.withArguments(key)); + } if (!seenKeys.add(key)) { report(element.key, templateConstEvalDuplicateKey.withArguments(key)); - } else { - entries.add(new ConstantMapEntry( - ensureIsSubtype(key, keyType, element.key), - ensureIsSubtype(value, valueType, element.value))); } + entries.add(new ConstantMapEntry( + ensureIsSubtype(key, keyType, element.key), + ensureIsSubtype(value, valueType, element.value))); } } } @@ -1115,6 +1162,7 @@ visitConstructorInvocation(ConstructorInvocation node) { final Constructor constructor = node.target; final Class klass = constructor.enclosingClass; + bool isSymbol = klass == coreTypes.internalSymbolClass; if (!constructor.isConst) { return reportInvalid(node, 'Non-const constructor invocation.'); } @@ -1138,7 +1186,7 @@ constructor.initializers.isEmpty && constructor.enclosingClass.supertype != null; - if (isUnavailable || shouldBeUnevaluated) { + if (isUnavailable || (isSymbol && shouldBeUnevaluated)) { return unevaluated( node, new ConstructorInvocation(constructor, @@ -1146,6 +1194,18 @@ isConst: true)); } + // Special case the dart:core's Symbol class here and convert it to a + // [SymbolConstant]. For invalid values we report a compile-time error. + if (isSymbol) { + final Constant nameValue = positionals.single; + + if (nameValue is StringConstant && isValidSymbolName(nameValue.value)) { + return canonicalize(new SymbolConstant(nameValue.value, null)); + } + return report(node.arguments.positional.first, + templateConstEvalInvalidSymbolName.withArguments(nameValue)); + } + final typeArguments = evaluateTypeArguments(node, node.arguments); // Fill in any missing type arguments with "dynamic". @@ -1158,33 +1218,39 @@ return runInsideContextIfNoContext(node, () { // "Run" the constructor (and any super constructor calls), which will // initialize the fields of the new instance. + if (shouldBeUnevaluated) { + enterLazy(); + handleConstructorInvocation( + constructor, typeArguments, positionals, named); + leaveLazy(); + return unevaluated(node, instanceBuilder.buildUnevaluatedInstance()); + } handleConstructorInvocation( constructor, typeArguments, positionals, named); - final InstanceConstant result = instanceBuilder.buildInstance(); - - // Special case the dart:core's Symbol class here and convert it to a - // [SymbolConstant]. For invalid values we report a compile-time error. - if (result.classNode == coreTypes.internalSymbolClass) { - // The dart:_internal's Symbol class has only the name field. - assert(coreTypes.internalSymbolClass.fields - .where((f) => !f.isStatic) - .length == - 1); - final nameValue = result.fieldValues.values.single; - - if (nameValue is StringConstant && - isValidSymbolName(nameValue.value)) { - return canonicalize(new SymbolConstant(nameValue.value, null)); - } - return report(node.arguments.positional.first, - templateConstEvalInvalidSymbolName.withArguments(nameValue)); + if (shouldBeUnevaluated) { + return unevaluated(node, instanceBuilder.buildUnevaluatedInstance()); } - - return canonicalize(result); + return canonicalize(instanceBuilder.buildInstance()); }); }); } + visitInstanceCreation(InstanceCreation node) { + return withNewInstanceBuilder(node.classNode, node.typeArguments, () { + for (AssertStatement statement in node.asserts) { + checkAssert(statement); + } + node.fieldValues.forEach((Reference fieldRef, Expression value) { + instanceBuilder.setFieldValue( + fieldRef.asField, _evaluateSubexpression(value)); + }); + if (shouldBeUnevaluated) { + return unevaluated(node, instanceBuilder.buildUnevaluatedInstance()); + } + return canonicalize(instanceBuilder.buildInstance()); + }); + } + bool isValidSymbolName(String name) { // See https://api.dartlang.org/stable/2.0.0/dart-core/Symbol/Symbol.html: // @@ -1370,40 +1436,7 @@ evaluatePositionalArguments(init.arguments), evaluateNamedArguments(init.arguments)); } else if (init is AssertInitializer) { - if (enableAsserts) { - final Constant condition = - _evaluateSubexpression(init.statement.condition); - - if (condition is BoolConstant) { - if (!condition.value) { - if (init.statement.message == null) { - return report(init.statement.condition, - messageConstEvalFailedAssertion); - } - final Constant message = - _evaluateSubexpression(init.statement.message); - if (message is StringConstant) { - return report( - init.statement.condition, - templateConstEvalFailedAssertionWithMessage - .withArguments(message.value)); - } - return report( - init.statement.message, - templateConstEvalInvalidType.withArguments( - message, - typeEnvironment.stringType, - message.getType(typeEnvironment))); - } - } else { - return report( - init.statement.condition, - templateConstEvalInvalidType.withArguments( - condition, - typeEnvironment.boolType, - condition.getType(typeEnvironment))); - } - } + checkAssert(init.statement); } else { return reportInvalid( constructor, @@ -1415,6 +1448,55 @@ }); } + void checkAssert(AssertStatement statement) { + if (enableAsserts) { + final Constant condition = _evaluateSubexpression(statement.condition); + + if (shouldBeUnevaluated) { + Expression message = null; + if (statement.message != null) { + enterLazy(); + message = extract(_evaluateSubexpression(statement.message)); + leaveLazy(); + } + instanceBuilder.asserts.add(new AssertStatement(extract(condition), + message: message, + conditionStartOffset: statement.conditionStartOffset, + conditionEndOffset: statement.conditionEndOffset)); + } else if (condition is BoolConstant) { + if (!condition.value) { + if (statement.message == null) { + report(statement.condition, messageConstEvalFailedAssertion); + } + final Constant message = _evaluateSubexpression(statement.message); + if (shouldBeUnevaluated) { + instanceBuilder.asserts.add(new AssertStatement(extract(condition), + message: extract(message), + conditionStartOffset: statement.conditionStartOffset, + conditionEndOffset: statement.conditionEndOffset)); + } else if (message is StringConstant) { + report( + statement.condition, + templateConstEvalFailedAssertionWithMessage + .withArguments(message.value)); + } else { + report( + statement.message, + templateConstEvalInvalidType.withArguments( + message, + typeEnvironment.stringType, + message.getType(typeEnvironment))); + } + } + } else { + report( + statement.condition, + templateConstEvalInvalidType.withArguments(condition, + typeEnvironment.boolType, condition.getType(typeEnvironment))); + } + } + } + visitInvalidExpression(InvalidExpression node) { return reportInvalid(node, node.message); } @@ -1434,17 +1516,36 @@ unevaluatedArguments(arguments, {}, node.arguments.types))); } - // TODO(http://dartbug.com/31799): Ensure we only invoke ==/!= on - // null/bool/int/double/String objects. - - // Handle == and != first (it's common between all types). + // Handle == and != first (it's common between all types). Since `a != b` is + // parsed as `!(a == b)` it is handled implicitly through ==. if (arguments.length == 1 && node.name.name == '==') { final right = arguments[0]; - return receiver == right ? trueConstant : falseConstant; - } - if (arguments.length == 1 && node.name.name == '!=') { - final right = arguments[0]; - return receiver != right ? trueConstant : falseConstant; + + // [DoubleConstant] uses [identical] to determine equality, so we need two + // special cases: + // Two NaNs are always unequal even if [identical] returns `true`. + if (isNaN(receiver) || isNaN(right)) { + return falseConstant; + } + + // Two zero values are always equal regardless of sign. + if (isZero(receiver)) { + return makeBoolConstant(isZero(right)); + } + + if (receiver is NullConstant || + receiver is BoolConstant || + receiver is IntConstant || + receiver is DoubleConstant || + receiver is StringConstant || + right is NullConstant) { + return makeBoolConstant(receiver == right); + } else { + return report( + node, + templateConstEvalInvalidEqualsOperandType.withArguments( + receiver, receiver.getType(typeEnvironment))); + } } // This is a white-listed set of methods we need to support on constants. @@ -1466,64 +1567,118 @@ other.getType(typeEnvironment))); } } - } else if (receiver is IntConstant) { + } else if (receiver is IntConstant || receiver is JavaScriptIntConstant) { if (arguments.length == 0) { switch (node.name.name) { case 'unary-': - return canonicalize(new IntConstant(-receiver.value)); + if (targetingJavaScript) { + BigInt value = (receiver as JavaScriptIntConstant).bigIntValue; + if (value == BigInt.zero) { + return canonicalize(new DoubleConstant(-0.0)); + } + return canonicalize(new JavaScriptIntConstant.fromBigInt(-value)); + } + int value = (receiver as IntConstant).value; + return canonicalize(new IntConstant(-value)); case '~': - return canonicalize(new IntConstant(~receiver.value)); + if (targetingJavaScript) { + BigInt value = (receiver as JavaScriptIntConstant).bigIntValue; + return canonicalize(new JavaScriptIntConstant.fromBigInt( + (~value).toUnsigned(32))); + } + int value = (receiver as IntConstant).value; + return canonicalize(new IntConstant(~value)); } } else if (arguments.length == 1) { final Constant other = arguments[0]; final op = node.name.name; - if (other is IntConstant) { - if ((op == '<<' || op == '>>' || op == '>>>') && other.value < 0) { - return report( - node.arguments.positional.first, - // TODO(askesc): Change argument types in template to constants. - templateConstEvalNegativeShift.withArguments( - op, '${receiver.value}', '${other.value}')); + if (other is IntConstant || other is JavaScriptIntConstant) { + if ((op == '<<' || op == '>>' || op == '>>>')) { + var receiverValue = receiver is IntConstant + ? receiver.value + : (receiver as JavaScriptIntConstant).bigIntValue; + int otherValue = other is IntConstant + ? other.value + : (other as JavaScriptIntConstant).bigIntValue.toInt(); + if (otherValue < 0) { + return report( + node.arguments.positional.first, + // TODO(askesc): Change argument types in template to constants. + templateConstEvalNegativeShift.withArguments( + op, '${receiverValue}', '${otherValue}')); + } } + + if ((op == '%' || op == '~/')) { + var receiverValue = receiver is IntConstant + ? receiver.value + : (receiver as JavaScriptIntConstant).bigIntValue; + int otherValue = other is IntConstant + ? other.value + : (other as JavaScriptIntConstant).bigIntValue.toInt(); + if (otherValue == 0) { + return report( + node.arguments.positional.first, + // TODO(askesc): Change argument type in template to constant. + templateConstEvalZeroDivisor.withArguments( + op, '${receiverValue}')); + } + } + switch (op) { case '|': - return canonicalize( - new IntConstant(receiver.value | other.value)); case '&': - return canonicalize( - new IntConstant(receiver.value & other.value)); case '^': - return canonicalize( - new IntConstant(receiver.value ^ other.value)); + int receiverValue = receiver is IntConstant + ? receiver.value + : (receiver as JavaScriptIntConstant) + .bigIntValue + .toUnsigned(32) + .toInt(); + int otherValue = other is IntConstant + ? other.value + : (other as JavaScriptIntConstant) + .bigIntValue + .toUnsigned(32) + .toInt(); + return evaluateBinaryBitOperation( + node.name.name, receiverValue, otherValue, node); case '<<': - return canonicalize( - new IntConstant(receiver.value << other.value)); case '>>': - return canonicalize( - new IntConstant(receiver.value >> other.value)); case '>>>': - int result = other.value >= 64 - ? 0 - : (receiver.value >> other.value) & - ((1 << (64 - other.value)) - 1); - return canonicalize(new IntConstant(result)); - } - } + bool negative = false; + int receiverValue; + if (receiver is IntConstant) { + receiverValue = receiver.value; + } else { + BigInt bigIntValue = + (receiver as JavaScriptIntConstant).bigIntValue; + receiverValue = bigIntValue.toUnsigned(32).toInt(); + negative = bigIntValue.isNegative; + } + int otherValue = other is IntConstant + ? other.value + : (other as JavaScriptIntConstant).bigIntValue.toInt(); - if (other is IntConstant) { - if (other.value == 0 && (op == '%' || op == '~/')) { - return report( - node.arguments.positional.first, - // TODO(askesc): Change argument type in template to constant. - templateConstEvalZeroDivisor.withArguments( - op, '${receiver.value}')); + return evaluateBinaryShiftOperation( + node.name.name, receiverValue, otherValue, node, + negativeReceiver: negative); + default: + num receiverValue = receiver is IntConstant + ? receiver.value + : (receiver as DoubleConstant).value; + num otherValue = other is IntConstant + ? other.value + : (other as DoubleConstant).value; + return evaluateBinaryNumericOperation( + node.name.name, receiverValue, otherValue, node); } - - return evaluateBinaryNumericOperation( - node.name.name, receiver.value, other.value, node); } else if (other is DoubleConstant) { + num receiverValue = receiver is IntConstant + ? receiver.value + : (receiver as DoubleConstant).value; return evaluateBinaryNumericOperation( - node.name.name, receiver.value, other.value, node); + node.name.name, receiverValue, other.value, node); } return report( node, @@ -1688,6 +1843,9 @@ final Constant receiver = _evaluateSubexpression(node.receiver); if (receiver is StringConstant && node.name.name == 'length') { + if (targetingJavaScript) { + return canonicalize(new JavaScriptIntConstant(receiver.value.length)); + } return canonicalize(new IntConstant(receiver.value.length)); } else if (shouldBeUnevaluated) { return unevaluated(node, @@ -1765,7 +1923,7 @@ for (int i = 0; i < node.expressions.length; i++) { Constant constant = _evaluateSubexpression(node.expressions[i]); if (constant is PrimitiveConstant<Object>) { - String value = constant.value.toString(); + String value = constant.toString(); Object last = concatenated.last; if (last is StringBuffer) { last.write(value); @@ -1827,16 +1985,22 @@ : value == "false" ? falseConstant : defaultValue is BoolConstant - ? defaultValue.value ? trueConstant : falseConstant + ? makeBoolConstant(defaultValue.value) : defaultValue is NullConstant ? nullConstant : falseConstant; return boolConstant; } else if (target.enclosingClass == coreTypes.intClass) { int intValue = value != null ? int.tryParse(value) : null; - intValue ??= - defaultValue is IntConstant ? defaultValue.value : null; + intValue ??= defaultValue is IntConstant + ? defaultValue.value + : defaultValue is JavaScriptIntConstant + ? defaultValue.bigIntValue.toInt() + : null; if (intValue == null) return nullConstant; + if (targetingJavaScript) { + return canonicalize(new JavaScriptIntConstant(intValue)); + } return canonicalize(new IntConstant(intValue)); } else if (target.enclosingClass == coreTypes.stringClass) { value ??= @@ -1862,9 +2026,23 @@ if (parent is Library && parent == coreTypes.coreLibrary) { final Constant left = positionals[0]; final Constant right = positionals[1]; + + if (targetingJavaScript) { + // In JavaScript, we lower [identical] to `===`, so any comparison + // against NaN yields `false`. + if (isNaN(left) || isNaN(right)) { + return falseConstant; + } + + // In JavaScript, `-0.0 === 0.0`. + if (isZero(left)) { + return makeBoolConstant(isZero(right)); + } + } + // Since we canonicalize constants during the evaluation, we can use // identical here. - return identical(left, right) ? trueConstant : falseConstant; + return makeBoolConstant(identical(left, right)); } } @@ -1900,21 +2078,18 @@ return unevaluated(node, new IsExpression(extract(constant), node.type)); } if (constant is NullConstant) { - return node.type == typeEnvironment.nullType || - node.type == typeEnvironment.objectType || - node.type is DynamicType - ? trueConstant - : falseConstant; + return makeBoolConstant(node.type == typeEnvironment.nullType || + node.type == typeEnvironment.objectType || + node.type is DynamicType); } - return isSubtype(constant, evaluateDartType(node, node.type)) - ? trueConstant - : falseConstant; + return makeBoolConstant( + isSubtype(constant, evaluateDartType(node, node.type))); } visitNot(Not node) { final Constant constant = _evaluateSubexpression(node.operand); if (constant is BoolConstant) { - return constant == trueConstant ? falseConstant : trueConstant; + return makeBoolConstant(constant != trueConstant); } if (shouldBeUnevaluated) { return unevaluated(node, new Not(extract(constant))); @@ -1963,13 +2138,46 @@ // Helper methods: - Constant makeDoubleConstant(double value) { + bool isZero(Constant value) => + (value is IntConstant && value.value == 0) || + (value is JavaScriptIntConstant && value.bigIntValue == BigInt.zero) || + (value is DoubleConstant && value.value == 0); + + bool isNaN(Constant value) => value is DoubleConstant && value.value.isNaN; + + bool hasPrimitiveEqual(Constant constant) { + // TODO(askesc, fishythefish): Make sure the correct class is inferred + // when we clean up JavaScript int constant handling. + DartType type = constant.getType(typeEnvironment); + return !(type is InterfaceType && !classHasPrimitiveEqual(type.classNode)); + } + + bool classHasPrimitiveEqual(Class klass) { + bool cached = primitiveEqualCache[klass]; + if (cached != null) return cached; + for (Procedure procedure in klass.procedures) { + if (procedure.kind == ProcedureKind.Operator && + procedure.name.name == '==' && + !procedure.isAbstract && + !procedure.isForwardingStub) { + return primitiveEqualCache[klass] = false; + } + } + if (klass.supertype == null) return true; // To be on the safe side + return primitiveEqualCache[klass] = + classHasPrimitiveEqual(klass.supertype.classNode); + } + + BoolConstant makeBoolConstant(bool value) => + value ? trueConstant : falseConstant; + + DoubleConstant makeDoubleConstant(double value) { if (targetingJavaScript) { // Convert to an integer when possible (matching the runtime behavior // of `is int`). - if (value.isFinite) { + if (value.isFinite && !identical(value, -0.0)) { var i = value.toInt(); - if (value == i.toDouble()) return new IntConstant(i); + if (value == i.toDouble()) return new JavaScriptIntConstant(i); } } return new DoubleConstant(value); @@ -2060,7 +2268,7 @@ withNewInstanceBuilder(Class klass, List<DartType> typeArguments, fn()) { InstanceBuilder old = instanceBuilder; try { - instanceBuilder = new InstanceBuilder(klass, typeArguments); + instanceBuilder = new InstanceBuilder(this, klass, typeArguments); return fn(); } finally { instanceBuilder = old; @@ -2077,12 +2285,58 @@ } } + Constant evaluateBinaryBitOperation(String op, int a, int b, TreeNode node) { + int result; + switch (op) { + case '|': + result = a | b; + break; + case '&': + result = a & b; + break; + case '^': + result = a ^ b; + break; + } + + if (targetingJavaScript) { + return canonicalize(new JavaScriptIntConstant(result)); + } + return canonicalize(new IntConstant(result)); + } + + Constant evaluateBinaryShiftOperation(String op, int a, int b, TreeNode node, + {negativeReceiver: false}) { + int result; + switch (op) { + case '<<': + result = a << b; + break; + case '>>': + if (targetingJavaScript) { + if (negativeReceiver) { + const signBit = 0x80000000; + a -= (a & signBit) << 1; + } + result = a >> b; + } else { + result = a >> b; + } + break; + case '>>>': + // TODO(fishythefish): Implement JS semantics for `>>>`. + result = b >= 64 ? 0 : (a >> b) & ((1 << (64 - b)) - 1); + break; + } + + if (targetingJavaScript) { + return canonicalize(new JavaScriptIntConstant(result.toUnsigned(32))); + } + return canonicalize(new IntConstant(result)); + } + Constant evaluateBinaryNumericOperation( String op, num a, num b, TreeNode node) { - if (targetingJavaScript) { - a = a.toDouble(); - b = b.toDouble(); - } num result; switch (op) { case '+': @@ -2106,6 +2360,9 @@ } if (result is int) { + if (targetingJavaScript) { + return canonicalize(new JavaScriptIntConstant(result)); + } return canonicalize(new IntConstant(result.toSigned(64))); } if (result is double) { @@ -2114,13 +2371,13 @@ switch (op) { case '<': - return a < b ? trueConstant : falseConstant; + return makeBoolConstant(a < b); case '<=': - return a <= b ? trueConstant : falseConstant; + return makeBoolConstant(a <= b); case '>=': - return a >= b ? trueConstant : falseConstant; + return makeBoolConstant(a >= b); case '>': - return a > b ? trueConstant : falseConstant; + return makeBoolConstant(a > b); } return reportInvalid(node, "Unexpected binary numeric operation '$op'."); @@ -2142,6 +2399,8 @@ /// * the [fields] the instance will obtain (all fields from the /// instantiated [klass] up to the [Object] klass). class InstanceBuilder { + ConstantEvaluator evaluator; + /// The class of the new instance. final Class klass; @@ -2151,19 +2410,32 @@ /// The field values of the new instance. final Map<Field, Constant> fields = <Field, Constant>{}; - InstanceBuilder(this.klass, this.typeArguments); + final List<AssertStatement> asserts = <AssertStatement>[]; + + InstanceBuilder(this.evaluator, this.klass, this.typeArguments); void setFieldValue(Field field, Constant constant) { fields[field] = constant; } InstanceConstant buildInstance() { + assert(asserts.isEmpty); final Map<Reference, Constant> fieldValues = <Reference, Constant>{}; fields.forEach((Field field, Constant value) { + assert(value is! UnevaluatedConstant); fieldValues[field.reference] = value; }); return new InstanceConstant(klass.reference, typeArguments, fieldValues); } + + InstanceCreation buildUnevaluatedInstance() { + final Map<Reference, Expression> fieldValues = <Reference, Expression>{}; + fields.forEach((Field field, Constant value) { + fieldValues[field.reference] = evaluator.extract(value); + }); + return new InstanceCreation( + klass.reference, typeArguments, fieldValues, asserts); + } } /// Holds an environment of type parameters, parameters and variables.
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart index 89a79f1..830e13a 100644 --- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart +++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -7,6 +7,20 @@ class InferenceVisitor extends BodyVisitor1<void, DartType> { final ShadowTypeInferrer inferrer; + Class mapEntryClass; + + // Stores the offset of the map entry found by inferMapEntry. + int mapEntryOffset = null; + + // Stores the offset of the map spread found by inferMapEntry. + int mapSpreadOffset = null; + + // Stores the offset of the iterable spread found by inferMapEntry. + int iterableSpreadOffset = null; + + // Stores the type of the iterable spread found by inferMapEntry. + DartType iterableSpreadType = null; + InferenceVisitor(this.inferrer); @override @@ -729,9 +743,12 @@ getSpreadElementType(spreadType, element.isNullAware) ?? const DynamicType(); } else if (element is IfElement) { - inferrer.inferExpression(element.condition, - inferrer.coreTypes.boolClass.rawType, typeChecksNeeded, + DartType boolType = inferrer.coreTypes.boolClass.rawType; + DartType conditionType = inferrer.inferExpression( + element.condition, boolType, typeChecksNeeded, isVoidAllowed: false); + inferrer.ensureAssignable(boolType, conditionType, element.condition, + element.condition.fileOffset); DartType thenType = inferElement( element.then, element, @@ -755,10 +772,14 @@ .getStandardUpperBound(thenType, otherwiseType); } else if (element is ForElement) { for (VariableDeclaration declaration in element.variables) { - if (declaration.initializer != null) { - inferrer.inferExpression(declaration.initializer, declaration.type, - inferenceNeeded || typeChecksNeeded, - isVoidAllowed: true); + if (declaration.name == null) { + if (declaration.initializer != null) { + declaration.type = inferrer.inferExpression(declaration.initializer, + declaration.type, inferenceNeeded || typeChecksNeeded, + isVoidAllowed: true); + } + } else { + inferrer.inferStatement(declaration); } } if (element.condition != null) { @@ -793,14 +814,20 @@ return inferElement(element.body, element, inferredTypeArgument, inferredSpreadTypes, inferenceNeeded, typeChecksNeeded); } else { - return inferrer.inferExpression( + DartType inferredType = inferrer.inferExpression( element, inferredTypeArgument, inferenceNeeded || typeChecksNeeded, isVoidAllowed: true); + if (inferredTypeArgument is! UnknownType) { + inferrer.ensureAssignable( + inferredTypeArgument, inferredType, element, element.fileOffset, + isVoidAllowed: inferredTypeArgument is VoidType); + } + return inferredType; } } void checkElement(Expression item, Expression parent, DartType typeArgument, - DartType actualType, Map<TreeNode, DartType> inferredSpreadTypes) { + Map<TreeNode, DartType> inferredSpreadTypes) { if (item is SpreadElement) { DartType spreadType = inferredSpreadTypes[item.expression]; if (spreadType is DynamicType) { @@ -808,24 +835,9 @@ spreadType, item.expression, item.expression.fileOffset); } } else if (item is IfElement) { - if (!inferrer.isAssignable(typeArgument, actualType)) { - int offset = - item.otherwise == null ? item.then.fileOffset : item.fileOffset; - parent.replaceChild( - item, - inferrer.helper.desugarSyntheticExpression(inferrer.helper - .buildProblem( - templateInvalidAssignment.withArguments( - actualType, typeArgument), - offset, - 1))); - } else { - checkElement( - item.then, item, typeArgument, actualType, inferredSpreadTypes); - if (item.otherwise != null) { - checkElement(item.otherwise, item, typeArgument, actualType, - inferredSpreadTypes); - } + checkElement(item.then, item, typeArgument, inferredSpreadTypes); + if (item.otherwise != null) { + checkElement(item.otherwise, item, typeArgument, inferredSpreadTypes); } } else if (item is ForElement) { if (item.condition != null) { @@ -833,36 +845,11 @@ inferrer.ensureAssignable(inferrer.coreTypes.boolClass.rawType, conditionType, item.condition, item.condition.fileOffset); } - if (!inferrer.isAssignable(typeArgument, actualType)) { - parent.replaceChild( - item, - inferrer.helper.desugarSyntheticExpression(inferrer.helper - .buildProblem( - templateInvalidAssignment.withArguments( - actualType, typeArgument), - item.body.fileOffset, - 1))); - } else { - checkElement( - item.body, item, typeArgument, actualType, inferredSpreadTypes); - } + checkElement(item.body, item, typeArgument, inferredSpreadTypes); } else if (item is ForInElement) { - if (!inferrer.isAssignable(typeArgument, actualType)) { - parent.replaceChild( - item, - inferrer.helper.desugarSyntheticExpression(inferrer.helper - .buildProblem( - templateInvalidAssignment.withArguments( - actualType, typeArgument), - item.body.fileOffset, - 1))); - } else { - checkElement( - item.body, item, typeArgument, actualType, inferredSpreadTypes); - } + checkElement(item.body, item, typeArgument, inferredSpreadTypes); } else { - inferrer.ensureAssignable(typeArgument, actualType, item, item.fileOffset, - isVoidAllowed: typeArgument is VoidType); + // Do nothing. Assignability checks are done during type inference. } } @@ -924,8 +911,8 @@ } if (typeChecksNeeded) { for (int i = 0; i < node.expressions.length; i++) { - checkElement(node.expressions[i], node, node.typeArgument, - actualTypes[i], inferredSpreadTypes); + checkElement( + node.expressions[i], node, node.typeArgument, inferredSpreadTypes); } } node.inferredType = new InterfaceType(listClass, [inferredTypeArgument]); @@ -977,11 +964,10 @@ } // Note that inferMapEntry adds exactly two elements to actualTypes -- the - // actual types of the key and the value. - int mapEntryOffset = null; - int mapSpreadOffset = null; - int iterableSpreadOffset = null; - DartType iterableSpreadType = null; + // actual types of the key and the value. The same technique is used for + // actualTypesForSet, only inferMapEntry adds exactly one element to that + // list: the actual type of the iterable spread elements in case the map + // literal will be disambiguated as a set literal later. void inferMapEntry( MapEntry entry, TreeNode parent, @@ -1077,7 +1063,7 @@ // recovery. actualTypesForSet.add(actualElementType ?? const DynamicType()); - Class mapEntryClass = + mapEntryClass ??= inferrer.coreTypes.index.getClass('dart:core', 'MapEntry'); // TODO(dmitryas): Handle the case of an ambiguous Set. entry.entryType = new InterfaceType( @@ -1096,9 +1082,12 @@ return; } else if (entry is IfMapEntry) { - inferrer.inferExpression(entry.condition, - inferrer.coreTypes.boolClass.rawType, typeChecksNeeded, + DartType boolType = inferrer.coreTypes.boolClass.rawType; + DartType conditionType = inferrer.inferExpression( + entry.condition, boolType, typeChecksNeeded, isVoidAllowed: false); + inferrer.ensureAssignable( + boolType, conditionType, entry.condition, entry.condition.fileOffset); // Note that this recursive invocation of inferMapEntry will add two types // to actualTypes; they are the actual types of the current invocation if // the 'else' branch is empty. @@ -1143,10 +1132,14 @@ return; } else if (entry is ForMapEntry) { for (VariableDeclaration declaration in entry.variables) { - if (declaration.initializer != null) { - inferrer.inferExpression(declaration.initializer, declaration.type, - inferenceNeeded || typeChecksNeeded, - isVoidAllowed: true); + if (declaration.name == null) { + if (declaration.initializer != null) { + declaration.type = inferrer.inferExpression(declaration.initializer, + declaration.type, inferenceNeeded || typeChecksNeeded, + isVoidAllowed: true); + } + } else { + inferrer.inferStatement(declaration); } } if (entry.condition != null) { @@ -1229,8 +1222,6 @@ Expression cachedValue, DartType keyType, DartType valueType, - DartType actualKeyType, - DartType actualValueType, Map<TreeNode, DartType> inferredSpreadTypes) { // It's disambiguated as a map literal. if (iterableSpreadOffset != null) { @@ -1252,37 +1243,11 @@ spreadType, entry.expression, entry.expression.fileOffset); } } else if (entry is IfMapEntry) { - Expression keyError; - Expression valueError; - int offset = - entry.otherwise == null ? entry.then.fileOffset : entry.fileOffset; - if (!inferrer.isAssignable(keyType, actualKeyType)) { - keyError = inferrer.helper.desugarSyntheticExpression(inferrer.helper - .buildProblem( - templateInvalidAssignment.withArguments(actualKeyType, keyType), - offset, - 1)); - } - if (!inferrer.isAssignable(valueType, actualValueType)) { - valueError = inferrer.helper.desugarSyntheticExpression(inferrer.helper - .buildProblem( - templateInvalidAssignment.withArguments( - actualValueType, valueType), - offset, - 1)); - } - if (keyError != null || valueError != null) { - keyError ??= new NullLiteral(); - valueError ??= new NullLiteral(); - parent.replaceChild(entry, - new MapEntry(keyError, valueError)..fileOffset = entry.fileOffset); - } else { - checkMapEntry(entry.then, entry, cachedKey, cachedValue, keyType, - valueType, actualKeyType, actualValueType, inferredSpreadTypes); - if (entry.otherwise != null) { - checkMapEntry(entry.otherwise, entry, cachedKey, cachedValue, keyType, - valueType, actualKeyType, actualValueType, inferredSpreadTypes); - } + checkMapEntry(entry.then, entry, cachedKey, cachedValue, keyType, + valueType, inferredSpreadTypes); + if (entry.otherwise != null) { + checkMapEntry(entry.otherwise, entry, cachedKey, cachedValue, keyType, + valueType, inferredSpreadTypes); } } else if (entry is ForMapEntry) { if (entry.condition != null) { @@ -1290,92 +1255,16 @@ inferrer.ensureAssignable(inferrer.coreTypes.boolClass.rawType, conditionType, entry.condition, entry.condition.fileOffset); } - Expression keyError; - Expression valueError; - if (!inferrer.isAssignable(keyType, actualKeyType)) { - keyError = inferrer.helper.desugarSyntheticExpression(inferrer.helper - .buildProblem( - templateInvalidAssignment.withArguments(actualKeyType, keyType), - entry.fileOffset, - 1)); - } - if (!inferrer.isAssignable(valueType, actualValueType)) { - valueError = inferrer.helper.desugarSyntheticExpression(inferrer.helper - .buildProblem( - templateInvalidAssignment.withArguments( - actualValueType, valueType), - entry.fileOffset, - 1)); - } - if (keyError != null || valueError != null) { - keyError ??= new NullLiteral(); - valueError ??= new NullLiteral(); - parent.replaceChild(entry, - new MapEntry(keyError, valueError)..fileOffset = entry.fileOffset); - } else { - checkMapEntry(entry.body, entry, cachedKey, cachedValue, keyType, - valueType, actualKeyType, actualValueType, inferredSpreadTypes); - } + checkMapEntry(entry.body, entry, cachedKey, cachedValue, keyType, + valueType, inferredSpreadTypes); } else if (entry is ForInMapEntry) { - Expression keyError; - Expression valueError; - if (!inferrer.isAssignable(keyType, actualKeyType)) { - keyError = inferrer.helper.desugarSyntheticExpression(inferrer.helper - .buildProblem( - templateInvalidAssignment.withArguments(actualKeyType, keyType), - entry.fileOffset, - 1)); - } - if (!inferrer.isAssignable(valueType, actualValueType)) { - valueError = inferrer.helper.desugarSyntheticExpression(inferrer.helper - .buildProblem( - templateInvalidAssignment.withArguments( - actualValueType, valueType), - entry.fileOffset, - 1)); - } - if (keyError != null || valueError != null) { - keyError ??= new NullLiteral(); - valueError ??= new NullLiteral(); - parent.replaceChild(entry, - new MapEntry(keyError, valueError)..fileOffset = entry.fileOffset); - } else { - checkMapEntry(entry.body, entry, cachedKey, cachedValue, keyType, - valueType, actualKeyType, actualValueType, inferredSpreadTypes); - } + checkMapEntry(entry.body, entry, cachedKey, cachedValue, keyType, + valueType, inferredSpreadTypes); } else { // Do nothing. Assignability checks are done during type inference. } } - Expression convertToElement(MapEntry entry) { - if (entry is SpreadMapEntry) { - return new SpreadElement(entry.expression, entry.isNullAware) - ..fileOffset = entry.expression.fileOffset; - } - if (entry is IfMapEntry) { - return new IfElement(entry.condition, convertToElement(entry.then), - entry.otherwise == null ? null : convertToElement(entry.otherwise)) - ..fileOffset = entry.fileOffset; - } - if (entry is ForMapEntry) { - return new ForElement(entry.variables, entry.condition, entry.updates, - convertToElement(entry.body)) - ..fileOffset = entry.fileOffset; - } - if (entry is ForInMapEntry) { - return new ForInElement(entry.variable, entry.iterable, entry.prologue, - convertToElement(entry.body), entry.problem) - ..fileOffset = entry.fileOffset; - } - return inferrer.helper - .desugarSyntheticExpression(inferrer.helper.buildProblem( - templateExpectedButGot.withArguments(','), - entry.fileOffset, - 1, - )); - } - void visitMapLiteralJudgment(MapLiteralJudgment node, DartType typeContext) { var mapClass = inferrer.coreTypes.mapClass; var mapType = mapClass.thisType; @@ -1493,7 +1382,7 @@ List<DartType> formalTypesForSet = <DartType>[]; InterfaceType setType = inferrer.coreTypes.setClass.thisType; for (int i = 0; i < node.entries.length; ++i) { - setElements.add(convertToElement(node.entries[i])); + setElements.add(convertToElement(node.entries[i], inferrer.helper)); formalTypesForSet.add(setType.typeArguments[0]); } @@ -1526,12 +1415,8 @@ node.parent.replaceChild(node, setLiteral); if (typeChecksNeeded) { for (int i = 0; i < setLiteral.expressions.length; i++) { - checkElement( - setLiteral.expressions[i], - setLiteral, - setLiteral.typeArgument, - actualTypesForSet[i], - inferredSpreadTypes); + checkElement(setLiteral.expressions[i], setLiteral, + setLiteral.typeArgument, inferredSpreadTypes); } } @@ -1579,16 +1464,8 @@ } if (typeChecksNeeded) { for (int i = 0; i < node.entries.length; ++i) { - checkMapEntry( - node.entries[i], - node, - cachedKeys[i], - cachedValues[i], - node.keyType, - node.valueType, - actualTypes[2 * i], - actualTypes[2 * i + 1], - inferredSpreadTypes); + checkMapEntry(node.entries[i], node, cachedKeys[i], cachedValues[i], + node.keyType, node.valueType, inferredSpreadTypes); } } node.inferredType = @@ -1875,8 +1752,8 @@ } if (typeChecksNeeded) { for (int i = 0; i < node.expressions.length; i++) { - checkElement(node.expressions[i], node, node.typeArgument, - actualTypes[i], inferredSpreadTypes); + checkElement( + node.expressions[i], node, node.typeArgument, inferredSpreadTypes); } } node.inferredType = new InterfaceType(setClass, [inferredTypeArgument]);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart index 8e04138..bca9db5 100644 --- a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
@@ -18,6 +18,7 @@ Catch, CheckLibraryIsLoaded, Class, + Component, Constructor, ConstructorInvocation, ContinueSwitchStatement,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart index f89f7ea..e91b0a4 100644 --- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -42,11 +42,9 @@ messageVoidExpression, noLength, templateCantInferTypeDueToCircularity, - templateExpectedButGot, templateForInLoopElementTypeNotAssignable, templateForInLoopTypeNotIterable, templateIntegerLiteralIsOutOfRange, - templateInvalidAssignment, templateSpreadElementTypeMismatch, templateSpreadMapEntryElementKeyTypeMismatch, templateSpreadMapEntryElementValueTypeMismatch, @@ -91,7 +89,8 @@ IfElement, IfMapEntry, SpreadElement, - SpreadMapEntry; + SpreadMapEntry, + convertToElement; import 'implicit_type_argument.dart' show ImplicitTypeArgument;
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 ed8f7b2..dfa8437 100644 --- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart +++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -224,6 +224,11 @@ } @override + void beginThenControlFlow(Token token) { + listener?.beginThenControlFlow(token); + } + + @override void beginIfStatement(Token token) { listener?.beginIfStatement(token); }
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart index 8a24cdf..858b3b8 100644 --- a/pkg/front_end/lib/src/fasta/parser/listener.dart +++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -1115,6 +1115,10 @@ /// Called before parsing an `if` control flow list, set, or map entry. void beginIfControlFlow(Token ifToken) {} + /// Called before parsing the `then` portion of an `if` control flow list, + /// set, or map entry. + void beginThenControlFlow(Token token) {} + /// Called before parsing the `else` portion of an `if` control flow list, /// set, or map entry. void handleElseControlFlow(Token elseToken) {
diff --git a/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart index 1ea0bf7..f5e4b8b 100644 --- a/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart +++ b/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart
@@ -144,7 +144,9 @@ final ifToken = token.next; assert(optional('if', ifToken)); parser.listener.beginIfControlFlow(ifToken); - return parser.ensureParenthesizedCondition(ifToken); + Token result = parser.ensureParenthesizedCondition(ifToken); + parser.listener.beginThenControlFlow(result); + return result; } @override
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart index 6ec8e5a..e716b34 100644 --- a/pkg/front_end/lib/src/fasta/parser/parser.dart +++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -2878,6 +2878,9 @@ } else if (identical(value, 'factory')) { Token next2 = next.next; if (next2.isIdentifier || next2.isModifier) { + if (beforeType != token) { + reportRecoverableError(token, fasta.messageTypeBeforeFactory); + } token = parseFactoryMethod(token, beforeStart, externalToken, staticToken ?? covariantToken, varFinalOrConst); listener.endMember();
diff --git a/pkg/front_end/lib/src/scanner/errors.dart b/pkg/front_end/lib/src/scanner/errors.dart index 6cdb878..4a7bb1d 100644 --- a/pkg/front_end/lib/src/scanner/errors.dart +++ b/pkg/front_end/lib/src/scanner/errors.dart
@@ -63,7 +63,7 @@ const ScannerErrorCode( 'UNTERMINATED_MULTI_LINE_COMMENT', "Unterminated multi-line comment.", correction: "Try terminating the comment with '*/', or " - "removing any unbalanced occurances of '/*'" + "removing any unbalanced occurrences of '/*'" " (because comments nest in Dart)."); static const ScannerErrorCode UNTERMINATED_STRING_LITERAL =
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status index 5a1995a..64141b8 100644 --- a/pkg/front_end/messages.status +++ b/pkg/front_end/messages.status
@@ -66,12 +66,15 @@ ConstEvalDeferredLibrary/example: Fail ConstEvalDuplicateElement/example: Fail ConstEvalDuplicateKey/example: Fail +ConstEvalElementImplementsEqual/example: Fail ConstEvalFailedAssertion/example: Fail ConstEvalFailedAssertionWithMessage/example: Fail ConstEvalFreeTypeParameter/analyzerCode: Fail ConstEvalFreeTypeParameter/example: Fail ConstEvalInvalidBinaryOperandType/analyzerCode: Fail # CONST_EVAL_TYPE_NUM / CONST_EVAL_TYPE_BOOL ConstEvalInvalidBinaryOperandType/example: Fail +ConstEvalInvalidEqualsOperandType/analyzerCode: Fail +ConstEvalInvalidEqualsOperandType/example: Fail ConstEvalInvalidMethodInvocation/example: Fail ConstEvalInvalidPropertyGet/example: Fail ConstEvalInvalidStaticInvocation/example: Fail @@ -82,6 +85,7 @@ ConstEvalIterationInConstList/example: Fail ConstEvalIterationInConstMap/example: Fail ConstEvalIterationInConstSet/example: Fail +ConstEvalKeyImplementsEqual/example: Fail ConstEvalNegativeShift/analyzerCode: Fail # http://dartbug.com/33481 ConstEvalNegativeShift/example: Fail ConstEvalNonConstantLiteral/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml index 558bd5b..e633dfd 100644 --- a/pkg/front_end/messages.yaml +++ b/pkg/front_end/messages.yaml
@@ -93,6 +93,14 @@ template: "The key '#constant' conflicts with another existing key in the map." analyzerCode: EQUAL_KEYS_IN_CONST_MAP +ConstEvalElementImplementsEqual: + template: "The element '#constant' does not have a primitive operator '=='." + analyzerCode: CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS + +ConstEvalKeyImplementsEqual: + template: "The key '#constant' does not have a primitive operator '=='." + analyzerCode: CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS + ConstEvalNonConstantLiteral: template: "Can't have a non-constant #string literal within a const context." analyzerCode: NON_CONSTANT_DEFAULT_VALUE @@ -103,6 +111,9 @@ ConstEvalInvalidBinaryOperandType: template: "Binary operator '#string' on '#constant' requires operand of type '#type', but was of type '#type2'." +ConstEvalInvalidEqualsOperandType: + template: "Binary operator '==' requires receiver constant '#constant' of type 'Null', 'bool', 'int', 'double', or 'String', but was of type '#type'." + ConstEvalZeroDivisor: template: "Binary operator '#string' on '#string2' requires non-zero divisor, but divisor was '0'." analyzerCode: CONST_EVAL_THROWS_IDBZE @@ -626,6 +637,14 @@ script: - "class C { factory const C() = prefix.B.foo; }" +TypeBeforeFactory: + index: 97 + template: "Factory constructors cannot have a return type." + tip: "Try removing the type appearing before 'factory'." + analyzerCode: ParserErrorCode.TYPE_BEFORE_FACTORY + script: + - "class C { T factory C() { return null; } }" + ConstConstructorWithBody: template: "A const constructor can't have a body." tip: "Try removing either the 'const' keyword or the body." @@ -669,7 +688,7 @@ DuplicatedModifier: index: 70 template: "The modifier '#lexeme' was already specified." - tip: "Try removing all but one occurance of the modifier." + tip: "Try removing all but one occurence of the modifier." analyzerCode: ParserErrorCode.DUPLICATED_MODIFIER script: - "class C { const const m; }" @@ -2165,7 +2184,7 @@ ImportAfterPart: index: 10 - template: "Import directives must preceed part directives." + template: "Import directives must precede part directives." tip: "Try moving the import directives before the part directives." analyzerCode: ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE script: @@ -2173,7 +2192,7 @@ ExportAfterPart: index: 75 - template: "Export directives must preceed part directives." + template: "Export directives must precede part directives." tip: "Try moving the export directives before the part directives." analyzerCode: ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE script: @@ -2463,7 +2482,7 @@ MissingOperatorKeyword: index: 31 - template: "Operator declarations must be preceeded by the keyword 'operator'." + template: "Operator declarations must be preceded by the keyword 'operator'." tip: "Try adding the keyword 'operator'." analyzerCode: ParserErrorCode.MISSING_KEYWORD_OPERATOR script:
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml index a9c0c28..1bfa71e 100644 --- a/pkg/front_end/pubspec.yaml +++ b/pkg/front_end/pubspec.yaml
@@ -8,14 +8,9 @@ environment: sdk: '>=2.1.0-dev.5.0 <3.0.0' dependencies: - charcode: '^1.1.1' - convert: '^2.0.1' - crypto: '^2.0.2' kernel: 0.3.15 - meta: '^1.1.1' package_config: '^1.0.1' path: '^1.3.9' - source_span: '^1.2.3' yaml: '^2.1.12' dev_dependencies: analyzer: 0.36.0 @@ -24,8 +19,6 @@ path: ../build_integration dart_style: '^1.0.7' json_rpc_2: ^2.0.9 - mockito: ^2.0.2 - stream_channel: ^1.6.1 test: ^1.3.4 test_reflective_loader: ^0.1.0 web_socket_channel: ^1.0.4
diff --git a/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart b/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart index 3051815..fcaed11 100644 --- a/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart +++ b/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart
@@ -206,6 +206,7 @@ 'handleNoArguments )', 'handleSend a )', 'handleParenthesizedCondition (', + 'beginThenControlFlow )', // nested for (b in c) 'beginForControlFlow null for', 'handleIdentifier b expression', @@ -343,6 +344,7 @@ 'beginIfControlFlow if', 'handleLiteralBool true', 'handleParenthesizedCondition (', + 'beginThenControlFlow )', 'handleLiteralInt 2', 'endIfControlFlow 2', 'handleLiteralList 1, [, null, ]', @@ -357,6 +359,7 @@ 'beginIfControlFlow if', 'handleLiteralBool true', 'handleParenthesizedCondition (', + 'beginThenControlFlow )', 'handleLiteralInt 2', 'handleElseControlFlow else', 'handleLiteralInt 5', @@ -374,6 +377,7 @@ 'beginIfControlFlow if', 'handleLiteralBool true', 'handleParenthesizedCondition (', + 'beginThenControlFlow )', // nested for (x in y) 'beginForControlFlow null for', 'handleIdentifier x expression', @@ -407,6 +411,7 @@ 'beginIfControlFlow if', 'handleLiteralBool true', 'handleParenthesizedCondition (', + 'beginThenControlFlow )', // nested for (a in b) 'beginForControlFlow null for', 'handleIdentifier a expression', @@ -434,6 +439,7 @@ 'handleNoArguments )', 'handleSend c )', 'handleParenthesizedCondition (', + 'beginThenControlFlow )', // nested for (d in e) 'beginForControlFlow null for', 'handleIdentifier d expression', @@ -468,6 +474,7 @@ 'beginIfControlFlow if', 'handleLiteralBool true', 'handleParenthesizedCondition (', + 'beginThenControlFlow )', 'handleNoTypeArguments [', 'handleLiteralInt 2', 'handleLiteralList 1, [, null, ]', @@ -485,6 +492,7 @@ 'beginIfControlFlow if', 'handleLiteralBool true', 'handleParenthesizedCondition (', + 'beginThenControlFlow )', 'handleNoTypeArguments [', 'handleLiteralInt 2', 'handleLiteralList 1, [, null, ]', @@ -764,6 +772,7 @@ 'beginIfControlFlow if', 'handleLiteralBool true', 'handleParenthesizedCondition (', + 'beginThenControlFlow )', 'handleLiteralInt 2', 'handleLiteralInt 3', 'handleLiteralMapEntry :, ', @@ -779,6 +788,7 @@ 'beginIfControlFlow if', 'handleLiteralBool true', 'handleParenthesizedCondition (', + 'beginThenControlFlow )', 'handleNoTypeArguments {', 'handleLiteralInt 2', 'handleLiteralInt 3', @@ -877,6 +887,11 @@ } @override + void beginThenControlFlow(Token token) { + calls.add('beginThenControlFlow $token'); + } + + @override void beginInitializedIdentifier(Token token) { calls.add('beginInitializedIdentifier $token'); }
diff --git a/pkg/front_end/test/hot_reload_e2e_test.dart b/pkg/front_end/test/hot_reload_e2e_test.dart index 7b50c3c..b90b143 100644 --- a/pkg/front_end/test/hot_reload_e2e_test.dart +++ b/pkg/front_end/test/hot_reload_e2e_test.dart
@@ -103,6 +103,7 @@ var vmArgs = [ '--enable-vm-service=0', // Note: use 0 to avoid port collisions. '--pause_isolates_on_start', + '--disable-service-auth-codes', outputUri.toFilePath() ]; vmArgs.add('$reloadCount');
diff --git a/pkg/front_end/testcases/control_flow_collection.dart.strong.expect b/pkg/front_end/testcases/control_flow_collection.dart.strong.expect index 9fed289..8c19425 100644 --- a/pkg/front_end/testcases/control_flow_collection.dart.strong.expect +++ b/pkg/front_end/testcases/control_flow_collection.dart.strong.expect
@@ -7,19 +7,19 @@ final core::List<core::int> aList = block { final core::List<core::int> #t1 = <core::int>[]; #t1.{core::List::add}(1); - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t1.{core::List::add}(2); - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t1.{core::List::add}(3); else #t1.{core::List::add}(1.{core::int::unary-}()); - if(self::oracle()) - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) + if(self::oracle() as{TypeError} core::bool) #t1.{core::List::add}(4); for (core::int i in <core::int>[5, 6, 7]) #t1.{core::List::add}(i); for (core::int i in <core::int>[8, 9, 10]) - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t1.{core::List::add}(i); for (core::int i = 11; i.{core::num::<=}(14); i = i.{core::num::+}(1)) #t1.{core::List::add}(i); @@ -27,19 +27,19 @@ final core::Set<core::int> aSet = block { final core::Set<core::int> #t2 = col::LinkedHashSet::•<core::int>(); #t2.{core::Set::add}(1); - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t2.{core::Set::add}(2); - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t2.{core::Set::add}(3); else #t2.{core::Set::add}(1.{core::int::unary-}()); - if(self::oracle()) - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) + if(self::oracle() as{TypeError} core::bool) #t2.{core::Set::add}(4); for (core::int i in <core::int>[5, 6, 7]) #t2.{core::Set::add}(i); for (core::int i in <core::int>[8, 9, 10]) - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t2.{core::Set::add}(i); for (core::int i = 11; i.{core::num::<=}(14); i = i.{core::num::+}(1)) #t2.{core::Set::add}(i); @@ -47,19 +47,19 @@ final core::Map<core::int, core::int> aMap = block { final core::Map<core::int, core::int> #t3 = <core::int, core::int>{}; #t3.{core::Map::[]=}(1, 1); - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t3.{core::Map::[]=}(2, 2); - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t3.{core::Map::[]=}(3, 3); else #t3.{core::Map::[]=}(1.{core::int::unary-}(), 1.{core::int::unary-}()); - if(self::oracle()) - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) + if(self::oracle() as{TypeError} core::bool) #t3.{core::Map::[]=}(4, 4); for (core::int i in <core::int>[5, 6, 7]) #t3.{core::Map::[]=}(i, i); for (core::int i in <core::int>[8, 9, 10]) - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t3.{core::Map::[]=}(i, i); for (core::int i = 11; i.{core::num::<=}(14); i = i.{core::num::+}(1)) #t3.{core::Map::[]=}(i, i);
diff --git a/pkg/front_end/testcases/control_flow_collection.dart.strong.transformed.expect b/pkg/front_end/testcases/control_flow_collection.dart.strong.transformed.expect index 9fed289..8c19425 100644 --- a/pkg/front_end/testcases/control_flow_collection.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/control_flow_collection.dart.strong.transformed.expect
@@ -7,19 +7,19 @@ final core::List<core::int> aList = block { final core::List<core::int> #t1 = <core::int>[]; #t1.{core::List::add}(1); - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t1.{core::List::add}(2); - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t1.{core::List::add}(3); else #t1.{core::List::add}(1.{core::int::unary-}()); - if(self::oracle()) - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) + if(self::oracle() as{TypeError} core::bool) #t1.{core::List::add}(4); for (core::int i in <core::int>[5, 6, 7]) #t1.{core::List::add}(i); for (core::int i in <core::int>[8, 9, 10]) - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t1.{core::List::add}(i); for (core::int i = 11; i.{core::num::<=}(14); i = i.{core::num::+}(1)) #t1.{core::List::add}(i); @@ -27,19 +27,19 @@ final core::Set<core::int> aSet = block { final core::Set<core::int> #t2 = col::LinkedHashSet::•<core::int>(); #t2.{core::Set::add}(1); - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t2.{core::Set::add}(2); - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t2.{core::Set::add}(3); else #t2.{core::Set::add}(1.{core::int::unary-}()); - if(self::oracle()) - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) + if(self::oracle() as{TypeError} core::bool) #t2.{core::Set::add}(4); for (core::int i in <core::int>[5, 6, 7]) #t2.{core::Set::add}(i); for (core::int i in <core::int>[8, 9, 10]) - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t2.{core::Set::add}(i); for (core::int i = 11; i.{core::num::<=}(14); i = i.{core::num::+}(1)) #t2.{core::Set::add}(i); @@ -47,19 +47,19 @@ final core::Map<core::int, core::int> aMap = block { final core::Map<core::int, core::int> #t3 = <core::int, core::int>{}; #t3.{core::Map::[]=}(1, 1); - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t3.{core::Map::[]=}(2, 2); - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t3.{core::Map::[]=}(3, 3); else #t3.{core::Map::[]=}(1.{core::int::unary-}(), 1.{core::int::unary-}()); - if(self::oracle()) - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) + if(self::oracle() as{TypeError} core::bool) #t3.{core::Map::[]=}(4, 4); for (core::int i in <core::int>[5, 6, 7]) #t3.{core::Map::[]=}(i, i); for (core::int i in <core::int>[8, 9, 10]) - if(self::oracle()) + if(self::oracle() as{TypeError} core::bool) #t3.{core::Map::[]=}(i, i); for (core::int i = 11; i.{core::num::<=}(14); i = i.{core::num::+}(1)) #t3.{core::Map::[]=}(i, i);
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart b/pkg/front_end/testcases/control_flow_collection_inference.dart index 3d9520f..4a64f6a 100644 --- a/pkg/front_end/testcases/control_flow_collection_inference.dart +++ b/pkg/front_end/testcases/control_flow_collection_inference.dart
@@ -78,6 +78,9 @@ List<int> list91 = [if (oracle("foo")) ...dynVar]; Set<int> set91 = {if (oracle("foo")) ...dynVar, null}; Map<String, int> map91 = {if (oracle("foo")) ...dynVar, "baz": null}; + List<int> list100 = [if (dynVar) 42]; + Set<int> set100 = {if (dynVar) 42}; + Map<int, int> map100 = {if (dynVar) 42: 42}; } testIfElementErrors(Map<int, int> map) { @@ -99,6 +102,20 @@ <int>[if (oracle("foo")) 42 else ...map]; <int>{if (oracle("foo")) ...map else 42, null}; <String, int>{if (oracle("foo")) "bar": 42 else ...[42], "baz": null}; + + Set<dynamic> set10 = {if (oracle("foo")) 42 else "bar": 3.14}; + Map<dynamic, dynamic> map10 = {if (oracle("foo")) 42 else "bar": 3.14}; + Set<dynamic> set11 = {if (oracle("foo")) "bar": 3.14 else 42}; + Map<dynamic, dynamic> map11 = {if (oracle("foo")) "bar": 3.14 else 42}; + var map12 = {if (oracle("foo")) 42 else "bar": 3.14}; + var map13 = {if (oracle("foo")) "bar": 3.14 else 42}; + List<int> list20 = [if (42) 42]; + Set<int> set20 = {if (42) 42}; + Map<int, int> map30 = {if (42) 42: 42}; + List<String> list40 = <String>[if (oracle("foo")) true else 42]; + Set<String> set40 = <String>{if (oracle("foo")) true else 42}; + Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42}; + Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42}; } testForElement(dynamic dynVar, List<int> listInt, List<double> listDouble, int @@ -184,6 +201,9 @@ List<int> list120 = [for (var i in dynVar) i]; Set<int> set120 = {for (var i in dynVar) i, null}; Map<String, int> map120 = {for (var i in dynVar) "bar": i, "baz": null}; + List<int> list130 = [for (var i = 1; i < 2; i++) i]; + Set<int> set130 = {for (var i = 1; i < 2; i++) i}; + Map<int, int> map130 = {for (var i = 1; i < 2; i++) i: i}; } testForElementErrors(Map<int, int> map, List<int> list) async { @@ -237,4 +257,16 @@ <String, int>{await for (int i in stream) "bar": i}; } +class A {} + +class B extends A { + int get foo => 42; +} + +testPromotion(A a) { + List<int> list10 = [if (a is B) a.foo]; + Set<int> set10 = {if (a is B) a.foo}; + Map<int, int> map10 = {if (a is B) a.foo: a.foo}; +} + main() {}
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart.hierarchy.expect b/pkg/front_end/testcases/control_flow_collection_inference.dart.hierarchy.expect new file mode 100644 index 0000000..3a1da21 --- /dev/null +++ b/pkg/front_end/testcases/control_flow_collection_inference.dart.hierarchy.expect
@@ -0,0 +1,55 @@ +Object: + superclasses: + interfaces: + classMembers: + Object._haveSameRuntimeType + Object.toString + Object.runtimeType + Object._toString + Object._simpleInstanceOf + Object._hashCodeRnd + Object._instanceOf + Object.noSuchMethod + Object._objectHashCode + Object._identityHashCode + Object.hashCode + Object._simpleInstanceOfFalse + Object._simpleInstanceOfTrue + Object.== + classSetters: + +A: + superclasses: + Object + interfaces: + classMembers: + Object.toString + Object.runtimeType + Object._simpleInstanceOf + Object._instanceOf + Object.noSuchMethod + Object._identityHashCode + Object.hashCode + Object._simpleInstanceOfFalse + Object._simpleInstanceOfTrue + Object.== + classSetters: + +B: + superclasses: + Object + -> A + interfaces: + classMembers: + Object.toString + Object.runtimeType + Object._simpleInstanceOf + Object._instanceOf + B.foo + Object.noSuchMethod + Object._identityHashCode + Object.hashCode + Object._simpleInstanceOfFalse + Object._simpleInstanceOfTrue + Object.== + classSetters:
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart.legacy.expect b/pkg/front_end/testcases/control_flow_collection_inference.dart.legacy.expect index b94b0a3..ffd86f8 100644 --- a/pkg/front_end/testcases/control_flow_collection_inference.dart.legacy.expect +++ b/pkg/front_end/testcases/control_flow_collection_inference.dart.legacy.expect
@@ -598,108 +598,96 @@ // Map<String, int> map91 = {if (oracle("foo")) ...dynVar, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:84:9: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:81:24: Error: Unexpected token 'if'. +// List<int> list100 = [if (dynVar) 42]; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:82:22: Error: Unexpected token 'if'. +// Set<int> set100 = {if (dynVar) 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:83:27: Error: Unexpected token 'if'. +// Map<int, int> map100 = {if (dynVar) 42: 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:87:9: Error: Unexpected token 'if'. // <int>[if (oracle("foo")) "bar"]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:85:9: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:88:9: Error: Unexpected token 'if'. // <int>{if (oracle("foo")) "bar", null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:86:17: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:89:17: Error: Unexpected token 'if'. // <String, int>{if (oracle("foo")) "bar": "bar", "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:87:28: Error: Unexpected token '...'. -// <int>[if (oracle("foo")) ...["bar"]]; -// ^^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:87:9: Error: Unexpected token 'if'. -// <int>[if (oracle("foo")) ...["bar"]]; -// ^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:88:28: Error: Unexpected token '...'. -// <int>{if (oracle("foo")) ...["bar"], null}; -// ^^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:88:9: Error: Unexpected token 'if'. -// <int>{if (oracle("foo")) ...["bar"], null}; -// ^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:89:36: Error: Unexpected token '...'. -// <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null}; -// ^^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:89:17: Error: Unexpected token 'if'. -// <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null}; -// ^^ -// // pkg/front_end/testcases/control_flow_collection_inference.dart:90:28: Error: Unexpected token '...'. -// <int>[if (oracle("foo")) ...map]; +// <int>[if (oracle("foo")) ...["bar"]]; // ^^^ // // pkg/front_end/testcases/control_flow_collection_inference.dart:90:9: Error: Unexpected token 'if'. -// <int>[if (oracle("foo")) ...map]; +// <int>[if (oracle("foo")) ...["bar"]]; // ^^ // // pkg/front_end/testcases/control_flow_collection_inference.dart:91:28: Error: Unexpected token '...'. -// <int>{if (oracle("foo")) ...map, null}; +// <int>{if (oracle("foo")) ...["bar"], null}; // ^^^ // // pkg/front_end/testcases/control_flow_collection_inference.dart:91:9: Error: Unexpected token 'if'. -// <int>{if (oracle("foo")) ...map, null}; +// <int>{if (oracle("foo")) ...["bar"], null}; // ^^ // // pkg/front_end/testcases/control_flow_collection_inference.dart:92:36: Error: Unexpected token '...'. -// <String, int>{if (oracle("foo")) ...["bar"], "baz": null}; +// <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null}; // ^^^ // // pkg/front_end/testcases/control_flow_collection_inference.dart:92:17: Error: Unexpected token 'if'. +// <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:93:28: Error: Unexpected token '...'. +// <int>[if (oracle("foo")) ...map]; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:93:9: Error: Unexpected token 'if'. +// <int>[if (oracle("foo")) ...map]; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:94:28: Error: Unexpected token '...'. +// <int>{if (oracle("foo")) ...map, null}; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:94:9: Error: Unexpected token 'if'. +// <int>{if (oracle("foo")) ...map, null}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:95:36: Error: Unexpected token '...'. +// <String, int>{if (oracle("foo")) ...["bar"], "baz": null}; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:95:17: Error: Unexpected token 'if'. // <String, int>{if (oracle("foo")) ...["bar"], "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:93:12: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:96:12: Error: Unexpected token 'if'. // <String>[if (oracle("foo")) 42 else 3.14]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:94:12: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:97:12: Error: Unexpected token 'if'. // <String>{if (oracle("foo")) 42 else 3.14, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:95:20: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:98:20: Error: Unexpected token 'if'. // <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:96:28: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:99:28: Error: Unexpected token '...'. // <int>[if (oracle("foo")) ...map else 42]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:96:9: Error: Unexpected token 'if'. -// <int>[if (oracle("foo")) ...map else 42]; -// ^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:97:28: Error: Unexpected token '...'. -// <int>{if (oracle("foo")) ...map else 42, null}; -// ^^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:97:9: Error: Unexpected token 'if'. -// <int>{if (oracle("foo")) ...map else 42, null}; -// ^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:98:36: Error: Unexpected token '...'. -// <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null}; -// ^^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:98:17: Error: Unexpected token 'if'. -// <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null}; -// ^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:99:36: Error: Unexpected token '...'. -// <int>[if (oracle("foo")) 42 else ...map]; -// ^^^ -// // pkg/front_end/testcases/control_flow_collection_inference.dart:99:9: Error: Unexpected token 'if'. -// <int>[if (oracle("foo")) 42 else ...map]; +// <int>[if (oracle("foo")) ...map else 42]; // ^^ // // pkg/front_end/testcases/control_flow_collection_inference.dart:100:28: Error: Unexpected token '...'. @@ -710,980 +698,1092 @@ // <int>{if (oracle("foo")) ...map else 42, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:101:51: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:101:36: Error: Unexpected token '...'. +// <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null}; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:101:17: Error: Unexpected token 'if'. +// <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:102:36: Error: Unexpected token '...'. +// <int>[if (oracle("foo")) 42 else ...map]; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:102:9: Error: Unexpected token 'if'. +// <int>[if (oracle("foo")) 42 else ...map]; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:103:28: Error: Unexpected token '...'. +// <int>{if (oracle("foo")) ...map else 42, null}; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:103:9: Error: Unexpected token 'if'. +// <int>{if (oracle("foo")) ...map else 42, null}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:104:51: Error: Unexpected token '...'. // <String, int>{if (oracle("foo")) "bar": 42 else ...[42], "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:101:17: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:104:17: Error: Unexpected token 'if'. // <String, int>{if (oracle("foo")) "bar": 42 else ...[42], "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:106:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:106:25: Error: Unexpected token 'if'. +// Set<dynamic> set10 = {if (oracle("foo")) 42 else "bar": 3.14}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:107:34: Error: Unexpected token 'if'. +// Map<dynamic, dynamic> map10 = {if (oracle("foo")) 42 else "bar": 3.14}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:108:25: Error: Unexpected token 'if'. +// Set<dynamic> set11 = {if (oracle("foo")) "bar": 3.14 else 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:109:34: Error: Unexpected token 'if'. +// Map<dynamic, dynamic> map11 = {if (oracle("foo")) "bar": 3.14 else 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:110:16: Error: Unexpected token 'if'. +// var map12 = {if (oracle("foo")) 42 else "bar": 3.14}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:111:16: Error: Unexpected token 'if'. +// var map13 = {if (oracle("foo")) "bar": 3.14 else 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:112:23: Error: Unexpected token 'if'. +// List<int> list20 = [if (42) 42]; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:113:21: Error: Unexpected token 'if'. +// Set<int> set20 = {if (42) 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:114:26: Error: Unexpected token 'if'. +// Map<int, int> map30 = {if (42) 42: 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:115:34: Error: Unexpected token 'if'. +// List<String> list40 = <String>[if (oracle("foo")) true else 42]; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:116:32: Error: Unexpected token 'if'. +// Set<String> set40 = <String>{if (oracle("foo")) true else 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:117:42: Error: Unexpected token 'if'. +// Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:118:42: Error: Unexpected token 'if'. +// Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:123:17: Error: Unexpected token 'for'. // var list10 = [for (int i = 0; oracle("foo"); i++) 42]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:107:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:124:16: Error: Unexpected token 'for'. // var set10 = {for (int i = 0; oracle("foo"); i++) 42, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:108:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:125:16: Error: Unexpected token 'for'. // var map10 = {for (int i = 0; oracle("foo"); i++) "bar": 42, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:109:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:126:17: Error: Unexpected token 'for'. // var list11 = [for (int i = 0; oracle("foo"); i++) dynVar]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:110:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:127:16: Error: Unexpected token 'for'. // var set11 = {for (int i = 0; oracle("foo"); i++) dynVar, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:111:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:128:16: Error: Unexpected token 'for'. // var map11 = {for (int i = 0; oracle("foo"); i++) "bar": dynVar, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:112:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:129:17: Error: Unexpected token 'for'. // var list12 = [for (int i = 0; oracle("foo"); i++) [42]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:113:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:130:16: Error: Unexpected token 'for'. // var set12 = {for (int i = 0; oracle("foo"); i++) [42], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:114:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:131:16: Error: Unexpected token 'for'. // var map12 = {for (int i = 0; oracle("foo"); i++) "bar": [42], "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:115:53: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:132:53: Error: Unexpected token '...'. // var list20 = [for (int i = 0; oracle("foo"); i++) ...[42]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:115:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:132:17: Error: Unexpected token 'for'. // var list20 = [for (int i = 0; oracle("foo"); i++) ...[42]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:116:52: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:133:52: Error: Unexpected token '...'. // var set20 = {for (int i = 0; oracle("foo"); i++) ...[42], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:116:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:133:16: Error: Unexpected token 'for'. // var set20 = {for (int i = 0; oracle("foo"); i++) ...[42], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:117:52: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:134:52: Error: Unexpected token '...'. // var map20 = {for (int i = 0; oracle("foo"); i++) ...{"bar": 42}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:117:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:134:16: Error: Unexpected token 'for'. // var map20 = {for (int i = 0; oracle("foo"); i++) ...{"bar": 42}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:118:53: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:135:53: Error: Unexpected token '...'. // var list21 = [for (int i = 0; oracle("foo"); i++) ...[dynVar]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:118:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:135:17: Error: Unexpected token 'for'. // var list21 = [for (int i = 0; oracle("foo"); i++) ...[dynVar]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:119:52: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:136:52: Error: Unexpected token '...'. // var set21 = {for (int i = 0; oracle("foo"); i++) ...[dynVar], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:119:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:136:16: Error: Unexpected token 'for'. // var set21 = {for (int i = 0; oracle("foo"); i++) ...[dynVar], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:120:52: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:137:52: Error: Unexpected token '...'. // var map21 = {for (int i = 0; oracle("foo"); i++) ...{"bar": dynVar}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:120:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:137:16: Error: Unexpected token 'for'. // var map21 = {for (int i = 0; oracle("foo"); i++) ...{"bar": dynVar}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:121:53: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:138:53: Error: Unexpected token '...'. // var list22 = [for (int i = 0; oracle("foo"); i++) ...[[42]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:121:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:138:17: Error: Unexpected token 'for'. // var list22 = [for (int i = 0; oracle("foo"); i++) ...[[42]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:122:52: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:139:52: Error: Unexpected token '...'. // var set22 = {for (int i = 0; oracle("foo"); i++) ...[[42]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:122:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:139:16: Error: Unexpected token 'for'. // var set22 = {for (int i = 0; oracle("foo"); i++) ...[[42]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:123:52: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:140:52: Error: Unexpected token '...'. // var map22 = {for (int i = 0; oracle("foo"); i++) ...{"bar": [42]}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:123:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:140:16: Error: Unexpected token 'for'. // var map22 = {for (int i = 0; oracle("foo"); i++) ...{"bar": [42]}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:124:67: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:141:67: Error: Unexpected token '...'. // var list30 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:124:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:141:53: Error: Unexpected token 'if'. // var list30 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42]]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:124:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:141:17: Error: Unexpected token 'for'. // var list30 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:125:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:142:66: Error: Unexpected token '...'. // var set30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:125:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:142:52: Error: Unexpected token 'if'. // var set30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42], null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:125:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:142:16: Error: Unexpected token 'for'. // var set30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:126:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:143:66: Error: Unexpected token '...'. // var map30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": 42}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:126:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:143:52: Error: Unexpected token 'if'. // var map30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": 42}, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:126:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:143:16: Error: Unexpected token 'for'. // var map30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": 42}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:127:67: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:144:67: Error: Unexpected token '...'. // var list31 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:127:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:144:53: Error: Unexpected token 'if'. // var list31 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar]]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:127:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:144:17: Error: Unexpected token 'for'. // var list31 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:128:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:145:66: Error: Unexpected token '...'. // var set31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:128:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:145:52: Error: Unexpected token 'if'. // var set31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar], null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:128:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:145:16: Error: Unexpected token 'for'. // var set31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:129:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:146:66: Error: Unexpected token '...'. // var map31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": dynVar}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:129:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:146:52: Error: Unexpected token 'if'. // var map31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": dynVar}, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:129:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:146:16: Error: Unexpected token 'for'. // var map31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": dynVar}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:130:67: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:147:67: Error: Unexpected token '...'. // var list33 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:130:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:147:53: Error: Unexpected token 'if'. // var list33 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]]]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:130:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:147:17: Error: Unexpected token 'for'. // var list33 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:131:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:148:66: Error: Unexpected token '...'. // var set33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:131:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:148:52: Error: Unexpected token 'if'. // var set33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]], null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:131:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:148:16: Error: Unexpected token 'for'. // var set33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:132:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:149:66: Error: Unexpected token '...'. // var map33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": [42]}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:132:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:149:52: Error: Unexpected token 'if'. // var map33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": [42]}, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:132:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:149:16: Error: Unexpected token 'for'. // var map33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": [42]}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:133:65: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:150:65: Error: Unexpected token '...'. // List<List<int>> list40 = [for (int i = 0; oracle("foo"); i++) ...[[]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:133:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:150:29: Error: Unexpected token 'for'. // List<List<int>> list40 = [for (int i = 0; oracle("foo"); i++) ...[[]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:134:63: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:151:63: Error: Unexpected token '...'. // Set<List<int>> set40 = {for (int i = 0; oracle("foo"); i++) ...[[]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:134:27: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:151:27: Error: Unexpected token 'for'. // Set<List<int>> set40 = {for (int i = 0; oracle("foo"); i++) ...[[]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:135:71: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:152:71: Error: Unexpected token '...'. // Map<String, List<int>> map40 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:135:35: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:152:35: Error: Unexpected token 'for'. // Map<String, List<int>> map40 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:136:65: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:153:65: Error: Unexpected token '...'. // List<List<int>> list41 = [for (int i = 0; oracle("foo"); i++) ...{[]}]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:136:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:153:29: Error: Unexpected token 'for'. // List<List<int>> list41 = [for (int i = 0; oracle("foo"); i++) ...{[]}]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:137:63: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:154:63: Error: Unexpected token '...'. // Set<List<int>> set41 = {for (int i = 0; oracle("foo"); i++) ...{[]}, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:137:27: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:154:27: Error: Unexpected token 'for'. // Set<List<int>> set41 = {for (int i = 0; oracle("foo"); i++) ...{[]}, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:138:79: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:155:79: Error: Unexpected token '...'. // List<List<int>> list42 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:138:65: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:155:65: Error: Unexpected token 'if'. // List<List<int>> list42 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:138:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:155:29: Error: Unexpected token 'for'. // List<List<int>> list42 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:139:77: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:156:77: Error: Unexpected token '...'. // Set<List<int>> set42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:139:63: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:156:63: Error: Unexpected token 'if'. // Set<List<int>> set42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:139:27: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:156:27: Error: Unexpected token 'for'. // Set<List<int>> set42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:140:85: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:157:85: Error: Unexpected token '...'. // Map<String, List<int>> map42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:140:71: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:157:71: Error: Unexpected token 'if'. // Map<String, List<int>> map42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:140:35: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:157:35: Error: Unexpected token 'for'. // Map<String, List<int>> map42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:141:59: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:158:59: Error: Unexpected token '...'. // List<int> list50 = [for (int i = 0; oracle("foo"); i++) ...[]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:141:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:158:23: Error: Unexpected token 'for'. // List<int> list50 = [for (int i = 0; oracle("foo"); i++) ...[]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:142:57: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:159:57: Error: Unexpected token '...'. // Set<int> set50 = {for (int i = 0; oracle("foo"); i++) ...[], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:142:21: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:159:21: Error: Unexpected token 'for'. // Set<int> set50 = {for (int i = 0; oracle("foo"); i++) ...[], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:143:65: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:160:65: Error: Unexpected token '...'. // Map<String, int> map50 = {for (int i = 0; oracle("foo"); i++) ...{}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:143:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:160:29: Error: Unexpected token 'for'. // Map<String, int> map50 = {for (int i = 0; oracle("foo"); i++) ...{}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:144:59: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:161:59: Error: Unexpected token '...'. // List<int> list51 = [for (int i = 0; oracle("foo"); i++) ...{}]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:144:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:161:23: Error: Unexpected token 'for'. // List<int> list51 = [for (int i = 0; oracle("foo"); i++) ...{}]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:145:57: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:162:57: Error: Unexpected token '...'. // Set<int> set51 = {for (int i = 0; oracle("foo"); i++) ...{}, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:145:21: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:162:21: Error: Unexpected token 'for'. // Set<int> set51 = {for (int i = 0; oracle("foo"); i++) ...{}, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:146:73: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:163:73: Error: Unexpected token '...'. // List<int> list52 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:146:59: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:163:59: Error: Unexpected token 'if'. // List<int> list52 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[]]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:146:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:163:23: Error: Unexpected token 'for'. // List<int> list52 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:147:71: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:164:71: Error: Unexpected token '...'. // Set<int> set52 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:147:57: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:164:57: Error: Unexpected token 'if'. // Set<int> set52 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[], null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:147:21: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:164:21: Error: Unexpected token 'for'. // Set<int> set52 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:148:65: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:165:65: Error: Unexpected token '...'. // List<List<int>> list60 = [for (int i = 0; oracle("foo"); i++) ...[[]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:148:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:165:29: Error: Unexpected token 'for'. // List<List<int>> list60 = [for (int i = 0; oracle("foo"); i++) ...[[]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:149:63: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:166:63: Error: Unexpected token '...'. // Set<List<int>> set60 = {for (int i = 0; oracle("foo"); i++) ...[[]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:149:27: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:166:27: Error: Unexpected token 'for'. // Set<List<int>> set60 = {for (int i = 0; oracle("foo"); i++) ...[[]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:150:71: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:167:71: Error: Unexpected token '...'. // Map<String, List<int>> map60 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:150:35: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:167:35: Error: Unexpected token 'for'. // Map<String, List<int>> map60 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:151:79: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:168:79: Error: Unexpected token '...'. // List<List<int>> list61 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:151:65: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:168:65: Error: Unexpected token 'if'. // List<List<int>> list61 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:151:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:168:29: Error: Unexpected token 'for'. // List<List<int>> list61 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:152:77: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:169:77: Error: Unexpected token '...'. // Set<List<int>> set61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:152:63: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:169:63: Error: Unexpected token 'if'. // Set<List<int>> set61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:152:27: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:169:27: Error: Unexpected token 'for'. // Set<List<int>> set61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:153:85: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:170:85: Error: Unexpected token '...'. // Map<String, List<int>> map61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:153:71: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:170:71: Error: Unexpected token 'if'. // Map<String, List<int>> map61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:153:35: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:170:35: Error: Unexpected token 'for'. // Map<String, List<int>> map61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:154:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:171:29: Error: Unexpected token 'for'. // List<List<int>> list70 = [for (int i = 0; oracle("foo"); i++) []]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:155:27: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:172:27: Error: Unexpected token 'for'. // Set<List<int>> set70 = {for (int i = 0; oracle("foo"); i++) [], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:156:35: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:173:35: Error: Unexpected token 'for'. // Map<String, List<int>> map70 = {for (int i = 0; oracle("foo"); i++) "bar": [], "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:157:65: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:174:65: Error: Unexpected token 'if'. // List<List<int>> list71 = [for (int i = 0; oracle("foo"); i++) if (oracle()) []]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:157:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:174:29: Error: Unexpected token 'for'. // List<List<int>> list71 = [for (int i = 0; oracle("foo"); i++) if (oracle()) []]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:158:63: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:175:63: Error: Unexpected token 'if'. // Set<List<int>> set71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) [], null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:158:27: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:175:27: Error: Unexpected token 'for'. // Set<List<int>> set71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) [], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:159:71: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:176:71: Error: Unexpected token 'if'. // Map<String, List<int>> map71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": [], "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:159:35: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:176:35: Error: Unexpected token 'for'. // Map<String, List<int>> map71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": [], "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:160:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:177:53: Error: Unexpected token 'if'. // var list80 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:160:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:177:17: Error: Unexpected token 'for'. // var list80 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:161:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:178:52: Error: Unexpected token 'if'. // var set80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:161:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:178:16: Error: Unexpected token 'for'. // var set80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:162:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:179:52: Error: Unexpected token 'if'. // var map80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:162:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:179:16: Error: Unexpected token 'for'. // var map80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:163:67: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:180:67: Error: Unexpected token '...'. // var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:163:83: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:180:83: Error: Unexpected token '...'. // var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:163:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:180:53: Error: Unexpected token 'if'. // var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:163:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:180:17: Error: Unexpected token 'for'. // var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:164:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:181:66: Error: Unexpected token '...'. // var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:164:82: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:181:82: Error: Unexpected token '...'. // var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:164:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:181:52: Error: Unexpected token 'if'. // var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:164:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:181:16: Error: Unexpected token 'for'. // var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:165:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:182:66: Error: Unexpected token '...'. // var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:165:87: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:182:87: Error: Unexpected token '...'. // var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:165:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:182:52: Error: Unexpected token 'if'. // var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:165:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:182:16: Error: Unexpected token 'for'. // var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:166:67: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:183:67: Error: Unexpected token '...'. // var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:166:83: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:183:83: Error: Unexpected token '...'. // var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:166:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:183:53: Error: Unexpected token 'if'. // var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:166:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:183:17: Error: Unexpected token 'for'. // var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:167:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:184:66: Error: Unexpected token '...'. // var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:167:82: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:184:82: Error: Unexpected token '...'. // var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:167:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:184:52: Error: Unexpected token 'if'. // var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:167:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:184:16: Error: Unexpected token 'for'. // var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:168:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:185:66: Error: Unexpected token '...'. // var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:168:87: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:185:87: Error: Unexpected token '...'. // var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:168:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:185:52: Error: Unexpected token 'if'. // var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:168:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:185:16: Error: Unexpected token 'for'. // var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:169:75: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:186:75: Error: Unexpected token '...'. // var list83 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...listDouble]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:169:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:186:53: Error: Unexpected token 'if'. // var list83 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...listDouble]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:169:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:186:17: Error: Unexpected token 'for'. // var list83 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...listDouble]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:170:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:187:66: Error: Unexpected token '...'. // var set83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else 3.14, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:170:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:187:52: Error: Unexpected token 'if'. // var set83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else 3.14, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:170:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:187:16: Error: Unexpected token 'for'. // var set83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else 3.14, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:171:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:188:66: Error: Unexpected token '...'. // var map83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else "bar": 3.14, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:171:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:188:52: Error: Unexpected token 'if'. // var map83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else "bar": 3.14, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:171:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:188:16: Error: Unexpected token 'for'. // var map83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else "bar": 3.14, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:172:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:189:23: Error: Unexpected token 'for'. // List<int> list90 = [for (int i = 0; oracle("foo"); i++) dynVar]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:173:21: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:190:21: Error: Unexpected token 'for'. // Set<int> set90 = {for (int i = 0; oracle("foo"); i++) dynVar, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:174:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:191:29: Error: Unexpected token 'for'. // Map<String, int> map90 = {for (int i = 0; oracle("foo"); i++) "bar": dynVar, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:175:59: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:192:59: Error: Unexpected token '...'. // List<int> list91 = [for (int i = 0; oracle("foo"); i++) ...dynVar]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:175:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:192:23: Error: Unexpected token 'for'. // List<int> list91 = [for (int i = 0; oracle("foo"); i++) ...dynVar]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:176:57: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:193:57: Error: Unexpected token '...'. // Set<int> set91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:176:21: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:193:21: Error: Unexpected token 'for'. // Set<int> set91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:177:65: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:194:65: Error: Unexpected token '...'. // Map<String, int> map91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:177:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:194:29: Error: Unexpected token 'for'. // Map<String, int> map91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:178:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:195:29: Error: Unexpected token 'for'. // List<int> list100 = <int>[for (index = 0; oracle("foo"); index++) 42]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:179:27: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:196:27: Error: Unexpected token 'for'. // Set<int> set100 = <int>{for (index = 0; oracle("foo"); index++) 42}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:180:43: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:197:43: Error: Unexpected token 'for'. // Map<String, int> map100 = <String, int>{for (index = 0; oracle("foo"); index++) "bar": 42}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:181:18: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:198:18: Error: Unexpected token 'for'. // var list110 = [for (var i in [1, 2, 3]) i]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:182:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:199:17: Error: Unexpected token 'for'. // var set110 = {for (var i in [1, 2, 3]) i, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:183:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:200:17: Error: Unexpected token 'for'. // var map110 = {for (var i in [1, 2, 3]) "bar": i, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:184:24: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:201:24: Error: Unexpected token 'for'. // List<int> list120 = [for (var i in dynVar) i]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:185:22: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:202:22: Error: Unexpected token 'for'. // Set<int> set120 = {for (var i in dynVar) i, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:186:30: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:203:30: Error: Unexpected token 'for'. // Map<String, int> map120 = {for (var i in dynVar) "bar": i, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:190:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:204:24: Error: Unexpected token 'for'. +// List<int> list130 = [for (var i = 1; i < 2; i++) i]; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:205:22: Error: Unexpected token 'for'. +// Set<int> set130 = {for (var i = 1; i < 2; i++) i}; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:206:27: Error: Unexpected token 'for'. +// Map<int, int> map130 = {for (var i = 1; i < 2; i++) i: i}; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:210:9: Error: Unexpected token 'for'. // <int>[for (int i = 0; oracle("foo"); i++) "bar"]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:191:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:211:9: Error: Unexpected token 'for'. // <int>{for (int i = 0; oracle("foo"); i++) "bar", null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:192:14: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:212:14: Error: Unexpected token 'for'. // <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:193:45: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:213:45: Error: Unexpected token '...'. // <int>[for (int i = 0; oracle("foo"); i++) ...["bar"]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:193:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:213:9: Error: Unexpected token 'for'. // <int>[for (int i = 0; oracle("foo"); i++) ...["bar"]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:194:45: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:214:45: Error: Unexpected token '...'. // <int>{for (int i = 0; oracle("foo"); i++) ...["bar"], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:194:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:214:9: Error: Unexpected token 'for'. // <int>{for (int i = 0; oracle("foo"); i++) ...["bar"], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:195:50: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:215:50: Error: Unexpected token '...'. // <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:195:14: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:215:14: Error: Unexpected token 'for'. // <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:196:45: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:216:45: Error: Unexpected token '...'. // <int>[for (int i = 0; oracle("foo"); i++) ...map]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:196:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:216:9: Error: Unexpected token 'for'. // <int>[for (int i = 0; oracle("foo"); i++) ...map]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:197:45: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:217:45: Error: Unexpected token '...'. // <int>{for (int i = 0; oracle("foo"); i++) ...map, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:197:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:217:9: Error: Unexpected token 'for'. // <int>{for (int i = 0; oracle("foo"); i++) ...map, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:198:50: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:218:50: Error: Unexpected token '...'. // <int, int>{for (int i = 0; oracle("foo"); i++) ...list, 42: null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:198:14: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:218:14: Error: Unexpected token 'for'. // <int, int>{for (int i = 0; oracle("foo"); i++) ...list, 42: null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:199:48: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:219:48: Error: Unexpected token 'if'. // <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:199:12: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:219:12: Error: Unexpected token 'for'. // <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:200:48: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:220:48: Error: Unexpected token 'if'. // <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:200:12: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:220:12: Error: Unexpected token 'for'. // <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:201:56: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:221:56: Error: Unexpected token 'if'. // <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:201:20: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:221:20: Error: Unexpected token 'for'. // <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:202:59: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:222:59: Error: Unexpected token '...'. // <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:202:45: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:222:45: Error: Unexpected token 'if'. // <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:202:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:222:9: Error: Unexpected token 'for'. // <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:203:59: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:223:59: Error: Unexpected token '...'. // <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:203:45: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:223:45: Error: Unexpected token 'if'. // <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:203:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:223:9: Error: Unexpected token 'for'. // <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:204:67: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:224:67: Error: Unexpected token '...'. // <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:204:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:224:53: Error: Unexpected token 'if'. // <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:204:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:224:17: Error: Unexpected token 'for'. // <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:205:67: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:225:67: Error: Unexpected token '...'. // <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:205:45: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:225:45: Error: Unexpected token 'if'. // <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:205:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:225:9: Error: Unexpected token 'for'. // <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:206:67: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:226:67: Error: Unexpected token '...'. // <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:206:45: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:226:45: Error: Unexpected token 'if'. // <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:206:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:226:9: Error: Unexpected token 'for'. // <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:207:82: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:227:82: Error: Unexpected token '...'. // <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:207:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:227:53: Error: Unexpected token 'if'. // <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:207:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:227:17: Error: Unexpected token 'for'. // <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:210:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:230:9: Error: Unexpected token 'for'. // <int>[for (i in <int>[1]) i]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:211:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:231:9: Error: Unexpected token 'for'. // <int>{for (i in <int>[1]) i, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:212:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:232:16: Error: Unexpected token 'for'. // <String, int>{for (i in <int>[1]) "bar": i, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:214:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:234:17: Error: Unexpected token 'for'. // var list10 = [for (var i in "not iterable") i]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:215:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:235:16: Error: Unexpected token 'for'. // var set10 = {for (var i in "not iterable") i, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:216:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:236:16: Error: Unexpected token 'for'. // var map10 = {for (var i in "not iterable") "bar": i, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:217:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:237:17: Error: Unexpected token 'for'. // var list20 = [for (int i in ["not", "int"]) i]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:218:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:238:16: Error: Unexpected token 'for'. // var set20 = {for (int i in ["not", "int"]) i, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:219:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:239:16: Error: Unexpected token 'for'. // var map20 = {for (int i in ["not", "int"]) "bar": i, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:220:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:240:23: Error: Unexpected token 'for'. // var list30 = [await for (var i in "not stream") i]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:221:22: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:241:22: Error: Unexpected token 'for'. // var set30 = {await for (var i in "not stream") i, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:222:22: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:242:22: Error: Unexpected token 'for'. // var map30 = {await for (var i in "not stream") "bar": i, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:223:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:243:23: Error: Unexpected token 'for'. // var list40 = [await for (int i in Stream.fromIterable(["not", "int"])) i]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:224:22: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:244:22: Error: Unexpected token 'for'. // var set40 = {await for (int i in Stream.fromIterable(["not", "int"])) i, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:225:22: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:245:22: Error: Unexpected token 'for'. // var map40 = {await for (int i in Stream.fromIterable(["not", "int"])) "bar": i, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:226:17: Error: The keyword 'await' isn't allowed for a normal 'for' statement. +// pkg/front_end/testcases/control_flow_collection_inference.dart:246:17: Error: The keyword 'await' isn't allowed for a normal 'for' statement. // Try removing the keyword, or use a for-each statement. // var list50 = [await for (;;) 42]; // ^^^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:226:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:246:23: Error: Unexpected token 'for'. // var list50 = [await for (;;) 42]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:227:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement. +// pkg/front_end/testcases/control_flow_collection_inference.dart:247:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement. // Try removing the keyword, or use a for-each statement. // var set50 = {await for (;;) 42, null}; // ^^^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:227:22: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:247:22: Error: Unexpected token 'for'. // var set50 = {await for (;;) 42, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:228:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement. +// pkg/front_end/testcases/control_flow_collection_inference.dart:248:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement. // Try removing the keyword, or use a for-each statement. // var map50 = {await for (;;) "bar": 42, "baz": null}; // ^^^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:228:22: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:248:22: Error: Unexpected token 'for'. // var map50 = {await for (;;) "bar": 42, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:229:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:249:17: Error: Unexpected token 'for'. // var list60 = [for (; "not bool";) 42]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:230:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:250:16: Error: Unexpected token 'for'. // var set60 = {for (; "not bool";) 42, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:231:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:251:16: Error: Unexpected token 'for'. // var map60 = {for (; "not bool";) "bar": 42, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:235:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:255:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop. // <int>[await for (int i in stream) i]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:235:15: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:255:15: Error: Unexpected token 'for'. // <int>[await for (int i in stream) i]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:236:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:256:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop. // <int>{await for (int i in stream) i}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:236:15: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:256:15: Error: Unexpected token 'for'. // <int>{await for (int i in stream) i}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:237:34: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:257:34: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop. // <String, int>{await for (int i in stream) "bar": i}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:237:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:257:23: Error: Unexpected token 'for'. // <String, int>{await for (int i in stream) "bar": i}; // ^^^ // +// pkg/front_end/testcases/control_flow_collection_inference.dart:267:23: Error: Unexpected token 'if'. +// List<int> list10 = [if (a is B) a.foo]; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:268:21: Error: Unexpected token 'if'. +// Set<int> set10 = {if (a is B) a.foo}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:269:26: Error: Unexpected token 'if'. +// Map<int, int> map10 = {if (a is B) a.foo: a.foo}; +// ^^ +// import self as self; import "dart:core" as core; import "dart:async" as asy; +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +class B extends self::A { + synthetic constructor •() → self::B + : super self::A::•() + ; + get foo() → core::int + return 42; +} static method oracle<T extends core::Object = dynamic>([self::oracle::T t = null]) → dynamic return true; static method testIfElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::Map<core::String, core::int> mapToInt, core::Map<core::String, core::double> mapToDouble) → dynamic { @@ -1758,6 +1858,9 @@ core::List<core::int> list91 = <dynamic>[]; core::Set<core::int> set91 = <dynamic>{null}; core::Map<core::String, core::int> map91 = <dynamic, dynamic>{"baz": null}; + core::List<core::int> list100 = <dynamic>[]; + core::Set<core::int> set100 = <dynamic, dynamic>{}; + core::Map<core::int, core::int> map100 = <dynamic, dynamic>{}; } static method testIfElementErrors(core::Map<core::int, core::int> map) → dynamic { <core::int>[]; @@ -1778,6 +1881,19 @@ <core::int>[]; <core::int>{null}; <core::String, core::int>{"baz": null}; + core::Set<dynamic> set10 = <dynamic, dynamic>{}; + core::Map<dynamic, dynamic> map10 = <dynamic, dynamic>{}; + core::Set<dynamic> set11 = <dynamic, dynamic>{}; + core::Map<dynamic, dynamic> map11 = <dynamic, dynamic>{}; + dynamic map12 = <dynamic, dynamic>{}; + dynamic map13 = <dynamic, dynamic>{}; + core::List<core::int> list20 = <dynamic>[]; + core::Set<core::int> set20 = <dynamic, dynamic>{}; + core::Map<core::int, core::int> map30 = <dynamic, dynamic>{}; + core::List<core::String> list40 = <core::String>[]; + core::Set<core::String> set40 = <core::String>{}; + core::Map<core::String, core::int> map40 = <core::String, core::int>{}; + core::Map<core::int, core::String> map41 = <core::int, core::String>{}; } static method testForElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::int index, core::Map<core::String, core::int> mapStringInt, core::Map<core::String, core::double> mapStringDouble) → dynamic { dynamic list10 = <dynamic>[]; @@ -1861,6 +1977,9 @@ core::List<core::int> list120 = <dynamic>[]; core::Set<core::int> set120 = <dynamic>{null}; core::Map<core::String, core::int> map120 = <dynamic, dynamic>{"baz": null}; + core::List<core::int> list130 = <dynamic>[]; + core::Set<core::int> set130 = <dynamic, dynamic>{}; + core::Map<core::int, core::int> map130 = <dynamic, dynamic>{}; } static method testForElementErrors(core::Map<core::int, core::int> map, core::List<core::int> list) → dynamic async { <core::int>[]; @@ -1909,4 +2028,9 @@ <core::int>{}; <core::String, core::int>{}; } +static method testPromotion(self::A a) → dynamic { + core::List<core::int> list10 = <dynamic>[]; + core::Set<core::int> set10 = <dynamic, dynamic>{}; + core::Map<core::int, core::int> map10 = <dynamic, dynamic>{}; +} static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart.legacy.transformed.expect b/pkg/front_end/testcases/control_flow_collection_inference.dart.legacy.transformed.expect index 9fdaca1..d384c49 100644 --- a/pkg/front_end/testcases/control_flow_collection_inference.dart.legacy.transformed.expect +++ b/pkg/front_end/testcases/control_flow_collection_inference.dart.legacy.transformed.expect
@@ -598,108 +598,96 @@ // Map<String, int> map91 = {if (oracle("foo")) ...dynVar, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:84:9: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:81:24: Error: Unexpected token 'if'. +// List<int> list100 = [if (dynVar) 42]; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:82:22: Error: Unexpected token 'if'. +// Set<int> set100 = {if (dynVar) 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:83:27: Error: Unexpected token 'if'. +// Map<int, int> map100 = {if (dynVar) 42: 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:87:9: Error: Unexpected token 'if'. // <int>[if (oracle("foo")) "bar"]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:85:9: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:88:9: Error: Unexpected token 'if'. // <int>{if (oracle("foo")) "bar", null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:86:17: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:89:17: Error: Unexpected token 'if'. // <String, int>{if (oracle("foo")) "bar": "bar", "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:87:28: Error: Unexpected token '...'. -// <int>[if (oracle("foo")) ...["bar"]]; -// ^^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:87:9: Error: Unexpected token 'if'. -// <int>[if (oracle("foo")) ...["bar"]]; -// ^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:88:28: Error: Unexpected token '...'. -// <int>{if (oracle("foo")) ...["bar"], null}; -// ^^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:88:9: Error: Unexpected token 'if'. -// <int>{if (oracle("foo")) ...["bar"], null}; -// ^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:89:36: Error: Unexpected token '...'. -// <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null}; -// ^^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:89:17: Error: Unexpected token 'if'. -// <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null}; -// ^^ -// // pkg/front_end/testcases/control_flow_collection_inference.dart:90:28: Error: Unexpected token '...'. -// <int>[if (oracle("foo")) ...map]; +// <int>[if (oracle("foo")) ...["bar"]]; // ^^^ // // pkg/front_end/testcases/control_flow_collection_inference.dart:90:9: Error: Unexpected token 'if'. -// <int>[if (oracle("foo")) ...map]; +// <int>[if (oracle("foo")) ...["bar"]]; // ^^ // // pkg/front_end/testcases/control_flow_collection_inference.dart:91:28: Error: Unexpected token '...'. -// <int>{if (oracle("foo")) ...map, null}; +// <int>{if (oracle("foo")) ...["bar"], null}; // ^^^ // // pkg/front_end/testcases/control_flow_collection_inference.dart:91:9: Error: Unexpected token 'if'. -// <int>{if (oracle("foo")) ...map, null}; +// <int>{if (oracle("foo")) ...["bar"], null}; // ^^ // // pkg/front_end/testcases/control_flow_collection_inference.dart:92:36: Error: Unexpected token '...'. -// <String, int>{if (oracle("foo")) ...["bar"], "baz": null}; +// <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null}; // ^^^ // // pkg/front_end/testcases/control_flow_collection_inference.dart:92:17: Error: Unexpected token 'if'. +// <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:93:28: Error: Unexpected token '...'. +// <int>[if (oracle("foo")) ...map]; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:93:9: Error: Unexpected token 'if'. +// <int>[if (oracle("foo")) ...map]; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:94:28: Error: Unexpected token '...'. +// <int>{if (oracle("foo")) ...map, null}; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:94:9: Error: Unexpected token 'if'. +// <int>{if (oracle("foo")) ...map, null}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:95:36: Error: Unexpected token '...'. +// <String, int>{if (oracle("foo")) ...["bar"], "baz": null}; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:95:17: Error: Unexpected token 'if'. // <String, int>{if (oracle("foo")) ...["bar"], "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:93:12: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:96:12: Error: Unexpected token 'if'. // <String>[if (oracle("foo")) 42 else 3.14]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:94:12: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:97:12: Error: Unexpected token 'if'. // <String>{if (oracle("foo")) 42 else 3.14, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:95:20: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:98:20: Error: Unexpected token 'if'. // <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:96:28: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:99:28: Error: Unexpected token '...'. // <int>[if (oracle("foo")) ...map else 42]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:96:9: Error: Unexpected token 'if'. -// <int>[if (oracle("foo")) ...map else 42]; -// ^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:97:28: Error: Unexpected token '...'. -// <int>{if (oracle("foo")) ...map else 42, null}; -// ^^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:97:9: Error: Unexpected token 'if'. -// <int>{if (oracle("foo")) ...map else 42, null}; -// ^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:98:36: Error: Unexpected token '...'. -// <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null}; -// ^^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:98:17: Error: Unexpected token 'if'. -// <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null}; -// ^^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:99:36: Error: Unexpected token '...'. -// <int>[if (oracle("foo")) 42 else ...map]; -// ^^^ -// // pkg/front_end/testcases/control_flow_collection_inference.dart:99:9: Error: Unexpected token 'if'. -// <int>[if (oracle("foo")) 42 else ...map]; +// <int>[if (oracle("foo")) ...map else 42]; // ^^ // // pkg/front_end/testcases/control_flow_collection_inference.dart:100:28: Error: Unexpected token '...'. @@ -710,980 +698,1092 @@ // <int>{if (oracle("foo")) ...map else 42, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:101:51: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:101:36: Error: Unexpected token '...'. +// <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null}; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:101:17: Error: Unexpected token 'if'. +// <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:102:36: Error: Unexpected token '...'. +// <int>[if (oracle("foo")) 42 else ...map]; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:102:9: Error: Unexpected token 'if'. +// <int>[if (oracle("foo")) 42 else ...map]; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:103:28: Error: Unexpected token '...'. +// <int>{if (oracle("foo")) ...map else 42, null}; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:103:9: Error: Unexpected token 'if'. +// <int>{if (oracle("foo")) ...map else 42, null}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:104:51: Error: Unexpected token '...'. // <String, int>{if (oracle("foo")) "bar": 42 else ...[42], "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:101:17: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:104:17: Error: Unexpected token 'if'. // <String, int>{if (oracle("foo")) "bar": 42 else ...[42], "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:106:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:106:25: Error: Unexpected token 'if'. +// Set<dynamic> set10 = {if (oracle("foo")) 42 else "bar": 3.14}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:107:34: Error: Unexpected token 'if'. +// Map<dynamic, dynamic> map10 = {if (oracle("foo")) 42 else "bar": 3.14}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:108:25: Error: Unexpected token 'if'. +// Set<dynamic> set11 = {if (oracle("foo")) "bar": 3.14 else 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:109:34: Error: Unexpected token 'if'. +// Map<dynamic, dynamic> map11 = {if (oracle("foo")) "bar": 3.14 else 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:110:16: Error: Unexpected token 'if'. +// var map12 = {if (oracle("foo")) 42 else "bar": 3.14}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:111:16: Error: Unexpected token 'if'. +// var map13 = {if (oracle("foo")) "bar": 3.14 else 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:112:23: Error: Unexpected token 'if'. +// List<int> list20 = [if (42) 42]; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:113:21: Error: Unexpected token 'if'. +// Set<int> set20 = {if (42) 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:114:26: Error: Unexpected token 'if'. +// Map<int, int> map30 = {if (42) 42: 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:115:34: Error: Unexpected token 'if'. +// List<String> list40 = <String>[if (oracle("foo")) true else 42]; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:116:32: Error: Unexpected token 'if'. +// Set<String> set40 = <String>{if (oracle("foo")) true else 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:117:42: Error: Unexpected token 'if'. +// Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:118:42: Error: Unexpected token 'if'. +// Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:123:17: Error: Unexpected token 'for'. // var list10 = [for (int i = 0; oracle("foo"); i++) 42]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:107:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:124:16: Error: Unexpected token 'for'. // var set10 = {for (int i = 0; oracle("foo"); i++) 42, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:108:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:125:16: Error: Unexpected token 'for'. // var map10 = {for (int i = 0; oracle("foo"); i++) "bar": 42, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:109:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:126:17: Error: Unexpected token 'for'. // var list11 = [for (int i = 0; oracle("foo"); i++) dynVar]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:110:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:127:16: Error: Unexpected token 'for'. // var set11 = {for (int i = 0; oracle("foo"); i++) dynVar, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:111:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:128:16: Error: Unexpected token 'for'. // var map11 = {for (int i = 0; oracle("foo"); i++) "bar": dynVar, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:112:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:129:17: Error: Unexpected token 'for'. // var list12 = [for (int i = 0; oracle("foo"); i++) [42]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:113:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:130:16: Error: Unexpected token 'for'. // var set12 = {for (int i = 0; oracle("foo"); i++) [42], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:114:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:131:16: Error: Unexpected token 'for'. // var map12 = {for (int i = 0; oracle("foo"); i++) "bar": [42], "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:115:53: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:132:53: Error: Unexpected token '...'. // var list20 = [for (int i = 0; oracle("foo"); i++) ...[42]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:115:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:132:17: Error: Unexpected token 'for'. // var list20 = [for (int i = 0; oracle("foo"); i++) ...[42]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:116:52: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:133:52: Error: Unexpected token '...'. // var set20 = {for (int i = 0; oracle("foo"); i++) ...[42], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:116:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:133:16: Error: Unexpected token 'for'. // var set20 = {for (int i = 0; oracle("foo"); i++) ...[42], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:117:52: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:134:52: Error: Unexpected token '...'. // var map20 = {for (int i = 0; oracle("foo"); i++) ...{"bar": 42}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:117:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:134:16: Error: Unexpected token 'for'. // var map20 = {for (int i = 0; oracle("foo"); i++) ...{"bar": 42}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:118:53: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:135:53: Error: Unexpected token '...'. // var list21 = [for (int i = 0; oracle("foo"); i++) ...[dynVar]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:118:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:135:17: Error: Unexpected token 'for'. // var list21 = [for (int i = 0; oracle("foo"); i++) ...[dynVar]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:119:52: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:136:52: Error: Unexpected token '...'. // var set21 = {for (int i = 0; oracle("foo"); i++) ...[dynVar], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:119:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:136:16: Error: Unexpected token 'for'. // var set21 = {for (int i = 0; oracle("foo"); i++) ...[dynVar], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:120:52: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:137:52: Error: Unexpected token '...'. // var map21 = {for (int i = 0; oracle("foo"); i++) ...{"bar": dynVar}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:120:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:137:16: Error: Unexpected token 'for'. // var map21 = {for (int i = 0; oracle("foo"); i++) ...{"bar": dynVar}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:121:53: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:138:53: Error: Unexpected token '...'. // var list22 = [for (int i = 0; oracle("foo"); i++) ...[[42]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:121:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:138:17: Error: Unexpected token 'for'. // var list22 = [for (int i = 0; oracle("foo"); i++) ...[[42]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:122:52: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:139:52: Error: Unexpected token '...'. // var set22 = {for (int i = 0; oracle("foo"); i++) ...[[42]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:122:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:139:16: Error: Unexpected token 'for'. // var set22 = {for (int i = 0; oracle("foo"); i++) ...[[42]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:123:52: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:140:52: Error: Unexpected token '...'. // var map22 = {for (int i = 0; oracle("foo"); i++) ...{"bar": [42]}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:123:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:140:16: Error: Unexpected token 'for'. // var map22 = {for (int i = 0; oracle("foo"); i++) ...{"bar": [42]}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:124:67: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:141:67: Error: Unexpected token '...'. // var list30 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:124:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:141:53: Error: Unexpected token 'if'. // var list30 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42]]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:124:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:141:17: Error: Unexpected token 'for'. // var list30 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:125:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:142:66: Error: Unexpected token '...'. // var set30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:125:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:142:52: Error: Unexpected token 'if'. // var set30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42], null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:125:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:142:16: Error: Unexpected token 'for'. // var set30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:126:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:143:66: Error: Unexpected token '...'. // var map30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": 42}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:126:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:143:52: Error: Unexpected token 'if'. // var map30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": 42}, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:126:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:143:16: Error: Unexpected token 'for'. // var map30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": 42}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:127:67: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:144:67: Error: Unexpected token '...'. // var list31 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:127:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:144:53: Error: Unexpected token 'if'. // var list31 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar]]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:127:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:144:17: Error: Unexpected token 'for'. // var list31 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:128:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:145:66: Error: Unexpected token '...'. // var set31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:128:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:145:52: Error: Unexpected token 'if'. // var set31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar], null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:128:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:145:16: Error: Unexpected token 'for'. // var set31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:129:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:146:66: Error: Unexpected token '...'. // var map31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": dynVar}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:129:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:146:52: Error: Unexpected token 'if'. // var map31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": dynVar}, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:129:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:146:16: Error: Unexpected token 'for'. // var map31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": dynVar}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:130:67: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:147:67: Error: Unexpected token '...'. // var list33 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:130:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:147:53: Error: Unexpected token 'if'. // var list33 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]]]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:130:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:147:17: Error: Unexpected token 'for'. // var list33 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:131:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:148:66: Error: Unexpected token '...'. // var set33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:131:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:148:52: Error: Unexpected token 'if'. // var set33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]], null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:131:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:148:16: Error: Unexpected token 'for'. // var set33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:132:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:149:66: Error: Unexpected token '...'. // var map33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": [42]}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:132:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:149:52: Error: Unexpected token 'if'. // var map33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": [42]}, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:132:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:149:16: Error: Unexpected token 'for'. // var map33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": [42]}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:133:65: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:150:65: Error: Unexpected token '...'. // List<List<int>> list40 = [for (int i = 0; oracle("foo"); i++) ...[[]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:133:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:150:29: Error: Unexpected token 'for'. // List<List<int>> list40 = [for (int i = 0; oracle("foo"); i++) ...[[]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:134:63: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:151:63: Error: Unexpected token '...'. // Set<List<int>> set40 = {for (int i = 0; oracle("foo"); i++) ...[[]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:134:27: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:151:27: Error: Unexpected token 'for'. // Set<List<int>> set40 = {for (int i = 0; oracle("foo"); i++) ...[[]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:135:71: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:152:71: Error: Unexpected token '...'. // Map<String, List<int>> map40 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:135:35: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:152:35: Error: Unexpected token 'for'. // Map<String, List<int>> map40 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:136:65: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:153:65: Error: Unexpected token '...'. // List<List<int>> list41 = [for (int i = 0; oracle("foo"); i++) ...{[]}]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:136:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:153:29: Error: Unexpected token 'for'. // List<List<int>> list41 = [for (int i = 0; oracle("foo"); i++) ...{[]}]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:137:63: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:154:63: Error: Unexpected token '...'. // Set<List<int>> set41 = {for (int i = 0; oracle("foo"); i++) ...{[]}, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:137:27: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:154:27: Error: Unexpected token 'for'. // Set<List<int>> set41 = {for (int i = 0; oracle("foo"); i++) ...{[]}, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:138:79: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:155:79: Error: Unexpected token '...'. // List<List<int>> list42 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:138:65: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:155:65: Error: Unexpected token 'if'. // List<List<int>> list42 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:138:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:155:29: Error: Unexpected token 'for'. // List<List<int>> list42 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:139:77: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:156:77: Error: Unexpected token '...'. // Set<List<int>> set42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:139:63: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:156:63: Error: Unexpected token 'if'. // Set<List<int>> set42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:139:27: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:156:27: Error: Unexpected token 'for'. // Set<List<int>> set42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:140:85: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:157:85: Error: Unexpected token '...'. // Map<String, List<int>> map42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:140:71: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:157:71: Error: Unexpected token 'if'. // Map<String, List<int>> map42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:140:35: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:157:35: Error: Unexpected token 'for'. // Map<String, List<int>> map42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:141:59: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:158:59: Error: Unexpected token '...'. // List<int> list50 = [for (int i = 0; oracle("foo"); i++) ...[]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:141:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:158:23: Error: Unexpected token 'for'. // List<int> list50 = [for (int i = 0; oracle("foo"); i++) ...[]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:142:57: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:159:57: Error: Unexpected token '...'. // Set<int> set50 = {for (int i = 0; oracle("foo"); i++) ...[], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:142:21: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:159:21: Error: Unexpected token 'for'. // Set<int> set50 = {for (int i = 0; oracle("foo"); i++) ...[], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:143:65: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:160:65: Error: Unexpected token '...'. // Map<String, int> map50 = {for (int i = 0; oracle("foo"); i++) ...{}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:143:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:160:29: Error: Unexpected token 'for'. // Map<String, int> map50 = {for (int i = 0; oracle("foo"); i++) ...{}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:144:59: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:161:59: Error: Unexpected token '...'. // List<int> list51 = [for (int i = 0; oracle("foo"); i++) ...{}]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:144:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:161:23: Error: Unexpected token 'for'. // List<int> list51 = [for (int i = 0; oracle("foo"); i++) ...{}]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:145:57: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:162:57: Error: Unexpected token '...'. // Set<int> set51 = {for (int i = 0; oracle("foo"); i++) ...{}, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:145:21: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:162:21: Error: Unexpected token 'for'. // Set<int> set51 = {for (int i = 0; oracle("foo"); i++) ...{}, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:146:73: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:163:73: Error: Unexpected token '...'. // List<int> list52 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:146:59: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:163:59: Error: Unexpected token 'if'. // List<int> list52 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[]]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:146:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:163:23: Error: Unexpected token 'for'. // List<int> list52 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:147:71: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:164:71: Error: Unexpected token '...'. // Set<int> set52 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:147:57: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:164:57: Error: Unexpected token 'if'. // Set<int> set52 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[], null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:147:21: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:164:21: Error: Unexpected token 'for'. // Set<int> set52 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:148:65: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:165:65: Error: Unexpected token '...'. // List<List<int>> list60 = [for (int i = 0; oracle("foo"); i++) ...[[]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:148:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:165:29: Error: Unexpected token 'for'. // List<List<int>> list60 = [for (int i = 0; oracle("foo"); i++) ...[[]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:149:63: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:166:63: Error: Unexpected token '...'. // Set<List<int>> set60 = {for (int i = 0; oracle("foo"); i++) ...[[]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:149:27: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:166:27: Error: Unexpected token 'for'. // Set<List<int>> set60 = {for (int i = 0; oracle("foo"); i++) ...[[]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:150:71: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:167:71: Error: Unexpected token '...'. // Map<String, List<int>> map60 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:150:35: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:167:35: Error: Unexpected token 'for'. // Map<String, List<int>> map60 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:151:79: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:168:79: Error: Unexpected token '...'. // List<List<int>> list61 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:151:65: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:168:65: Error: Unexpected token 'if'. // List<List<int>> list61 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:151:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:168:29: Error: Unexpected token 'for'. // List<List<int>> list61 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:152:77: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:169:77: Error: Unexpected token '...'. // Set<List<int>> set61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:152:63: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:169:63: Error: Unexpected token 'if'. // Set<List<int>> set61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:152:27: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:169:27: Error: Unexpected token 'for'. // Set<List<int>> set61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:153:85: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:170:85: Error: Unexpected token '...'. // Map<String, List<int>> map61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:153:71: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:170:71: Error: Unexpected token 'if'. // Map<String, List<int>> map61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:153:35: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:170:35: Error: Unexpected token 'for'. // Map<String, List<int>> map61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:154:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:171:29: Error: Unexpected token 'for'. // List<List<int>> list70 = [for (int i = 0; oracle("foo"); i++) []]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:155:27: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:172:27: Error: Unexpected token 'for'. // Set<List<int>> set70 = {for (int i = 0; oracle("foo"); i++) [], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:156:35: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:173:35: Error: Unexpected token 'for'. // Map<String, List<int>> map70 = {for (int i = 0; oracle("foo"); i++) "bar": [], "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:157:65: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:174:65: Error: Unexpected token 'if'. // List<List<int>> list71 = [for (int i = 0; oracle("foo"); i++) if (oracle()) []]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:157:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:174:29: Error: Unexpected token 'for'. // List<List<int>> list71 = [for (int i = 0; oracle("foo"); i++) if (oracle()) []]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:158:63: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:175:63: Error: Unexpected token 'if'. // Set<List<int>> set71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) [], null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:158:27: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:175:27: Error: Unexpected token 'for'. // Set<List<int>> set71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) [], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:159:71: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:176:71: Error: Unexpected token 'if'. // Map<String, List<int>> map71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": [], "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:159:35: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:176:35: Error: Unexpected token 'for'. // Map<String, List<int>> map71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": [], "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:160:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:177:53: Error: Unexpected token 'if'. // var list80 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:160:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:177:17: Error: Unexpected token 'for'. // var list80 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:161:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:178:52: Error: Unexpected token 'if'. // var set80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:161:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:178:16: Error: Unexpected token 'for'. // var set80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:162:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:179:52: Error: Unexpected token 'if'. // var map80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:162:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:179:16: Error: Unexpected token 'for'. // var map80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:163:67: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:180:67: Error: Unexpected token '...'. // var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:163:83: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:180:83: Error: Unexpected token '...'. // var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:163:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:180:53: Error: Unexpected token 'if'. // var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:163:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:180:17: Error: Unexpected token 'for'. // var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:164:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:181:66: Error: Unexpected token '...'. // var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:164:82: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:181:82: Error: Unexpected token '...'. // var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:164:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:181:52: Error: Unexpected token 'if'. // var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:164:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:181:16: Error: Unexpected token 'for'. // var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:165:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:182:66: Error: Unexpected token '...'. // var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:165:87: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:182:87: Error: Unexpected token '...'. // var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:165:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:182:52: Error: Unexpected token 'if'. // var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:165:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:182:16: Error: Unexpected token 'for'. // var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:166:67: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:183:67: Error: Unexpected token '...'. // var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:166:83: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:183:83: Error: Unexpected token '...'. // var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:166:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:183:53: Error: Unexpected token 'if'. // var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:166:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:183:17: Error: Unexpected token 'for'. // var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:167:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:184:66: Error: Unexpected token '...'. // var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:167:82: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:184:82: Error: Unexpected token '...'. // var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:167:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:184:52: Error: Unexpected token 'if'. // var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:167:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:184:16: Error: Unexpected token 'for'. // var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:168:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:185:66: Error: Unexpected token '...'. // var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:168:87: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:185:87: Error: Unexpected token '...'. // var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:168:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:185:52: Error: Unexpected token 'if'. // var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:168:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:185:16: Error: Unexpected token 'for'. // var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:169:75: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:186:75: Error: Unexpected token '...'. // var list83 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...listDouble]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:169:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:186:53: Error: Unexpected token 'if'. // var list83 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...listDouble]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:169:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:186:17: Error: Unexpected token 'for'. // var list83 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...listDouble]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:170:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:187:66: Error: Unexpected token '...'. // var set83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else 3.14, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:170:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:187:52: Error: Unexpected token 'if'. // var set83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else 3.14, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:170:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:187:16: Error: Unexpected token 'for'. // var set83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else 3.14, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:171:66: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:188:66: Error: Unexpected token '...'. // var map83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else "bar": 3.14, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:171:52: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:188:52: Error: Unexpected token 'if'. // var map83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else "bar": 3.14, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:171:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:188:16: Error: Unexpected token 'for'. // var map83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else "bar": 3.14, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:172:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:189:23: Error: Unexpected token 'for'. // List<int> list90 = [for (int i = 0; oracle("foo"); i++) dynVar]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:173:21: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:190:21: Error: Unexpected token 'for'. // Set<int> set90 = {for (int i = 0; oracle("foo"); i++) dynVar, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:174:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:191:29: Error: Unexpected token 'for'. // Map<String, int> map90 = {for (int i = 0; oracle("foo"); i++) "bar": dynVar, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:175:59: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:192:59: Error: Unexpected token '...'. // List<int> list91 = [for (int i = 0; oracle("foo"); i++) ...dynVar]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:175:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:192:23: Error: Unexpected token 'for'. // List<int> list91 = [for (int i = 0; oracle("foo"); i++) ...dynVar]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:176:57: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:193:57: Error: Unexpected token '...'. // Set<int> set91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:176:21: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:193:21: Error: Unexpected token 'for'. // Set<int> set91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:177:65: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:194:65: Error: Unexpected token '...'. // Map<String, int> map91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:177:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:194:29: Error: Unexpected token 'for'. // Map<String, int> map91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:178:29: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:195:29: Error: Unexpected token 'for'. // List<int> list100 = <int>[for (index = 0; oracle("foo"); index++) 42]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:179:27: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:196:27: Error: Unexpected token 'for'. // Set<int> set100 = <int>{for (index = 0; oracle("foo"); index++) 42}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:180:43: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:197:43: Error: Unexpected token 'for'. // Map<String, int> map100 = <String, int>{for (index = 0; oracle("foo"); index++) "bar": 42}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:181:18: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:198:18: Error: Unexpected token 'for'. // var list110 = [for (var i in [1, 2, 3]) i]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:182:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:199:17: Error: Unexpected token 'for'. // var set110 = {for (var i in [1, 2, 3]) i, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:183:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:200:17: Error: Unexpected token 'for'. // var map110 = {for (var i in [1, 2, 3]) "bar": i, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:184:24: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:201:24: Error: Unexpected token 'for'. // List<int> list120 = [for (var i in dynVar) i]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:185:22: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:202:22: Error: Unexpected token 'for'. // Set<int> set120 = {for (var i in dynVar) i, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:186:30: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:203:30: Error: Unexpected token 'for'. // Map<String, int> map120 = {for (var i in dynVar) "bar": i, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:190:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:204:24: Error: Unexpected token 'for'. +// List<int> list130 = [for (var i = 1; i < 2; i++) i]; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:205:22: Error: Unexpected token 'for'. +// Set<int> set130 = {for (var i = 1; i < 2; i++) i}; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:206:27: Error: Unexpected token 'for'. +// Map<int, int> map130 = {for (var i = 1; i < 2; i++) i: i}; +// ^^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:210:9: Error: Unexpected token 'for'. // <int>[for (int i = 0; oracle("foo"); i++) "bar"]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:191:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:211:9: Error: Unexpected token 'for'. // <int>{for (int i = 0; oracle("foo"); i++) "bar", null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:192:14: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:212:14: Error: Unexpected token 'for'. // <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:193:45: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:213:45: Error: Unexpected token '...'. // <int>[for (int i = 0; oracle("foo"); i++) ...["bar"]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:193:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:213:9: Error: Unexpected token 'for'. // <int>[for (int i = 0; oracle("foo"); i++) ...["bar"]]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:194:45: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:214:45: Error: Unexpected token '...'. // <int>{for (int i = 0; oracle("foo"); i++) ...["bar"], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:194:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:214:9: Error: Unexpected token 'for'. // <int>{for (int i = 0; oracle("foo"); i++) ...["bar"], null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:195:50: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:215:50: Error: Unexpected token '...'. // <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:195:14: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:215:14: Error: Unexpected token 'for'. // <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:196:45: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:216:45: Error: Unexpected token '...'. // <int>[for (int i = 0; oracle("foo"); i++) ...map]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:196:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:216:9: Error: Unexpected token 'for'. // <int>[for (int i = 0; oracle("foo"); i++) ...map]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:197:45: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:217:45: Error: Unexpected token '...'. // <int>{for (int i = 0; oracle("foo"); i++) ...map, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:197:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:217:9: Error: Unexpected token 'for'. // <int>{for (int i = 0; oracle("foo"); i++) ...map, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:198:50: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:218:50: Error: Unexpected token '...'. // <int, int>{for (int i = 0; oracle("foo"); i++) ...list, 42: null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:198:14: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:218:14: Error: Unexpected token 'for'. // <int, int>{for (int i = 0; oracle("foo"); i++) ...list, 42: null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:199:48: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:219:48: Error: Unexpected token 'if'. // <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:199:12: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:219:12: Error: Unexpected token 'for'. // <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:200:48: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:220:48: Error: Unexpected token 'if'. // <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:200:12: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:220:12: Error: Unexpected token 'for'. // <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:201:56: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:221:56: Error: Unexpected token 'if'. // <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:201:20: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:221:20: Error: Unexpected token 'for'. // <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:202:59: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:222:59: Error: Unexpected token '...'. // <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:202:45: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:222:45: Error: Unexpected token 'if'. // <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:202:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:222:9: Error: Unexpected token 'for'. // <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:203:59: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:223:59: Error: Unexpected token '...'. // <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:203:45: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:223:45: Error: Unexpected token 'if'. // <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:203:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:223:9: Error: Unexpected token 'for'. // <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:204:67: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:224:67: Error: Unexpected token '...'. // <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:204:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:224:53: Error: Unexpected token 'if'. // <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:204:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:224:17: Error: Unexpected token 'for'. // <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:205:67: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:225:67: Error: Unexpected token '...'. // <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:205:45: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:225:45: Error: Unexpected token 'if'. // <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:205:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:225:9: Error: Unexpected token 'for'. // <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:206:67: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:226:67: Error: Unexpected token '...'. // <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:206:45: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:226:45: Error: Unexpected token 'if'. // <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:206:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:226:9: Error: Unexpected token 'for'. // <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:207:82: Error: Unexpected token '...'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:227:82: Error: Unexpected token '...'. // <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:207:53: Error: Unexpected token 'if'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:227:53: Error: Unexpected token 'if'. // <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:207:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:227:17: Error: Unexpected token 'for'. // <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:210:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:230:9: Error: Unexpected token 'for'. // <int>[for (i in <int>[1]) i]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:211:9: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:231:9: Error: Unexpected token 'for'. // <int>{for (i in <int>[1]) i, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:212:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:232:16: Error: Unexpected token 'for'. // <String, int>{for (i in <int>[1]) "bar": i, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:214:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:234:17: Error: Unexpected token 'for'. // var list10 = [for (var i in "not iterable") i]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:215:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:235:16: Error: Unexpected token 'for'. // var set10 = {for (var i in "not iterable") i, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:216:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:236:16: Error: Unexpected token 'for'. // var map10 = {for (var i in "not iterable") "bar": i, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:217:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:237:17: Error: Unexpected token 'for'. // var list20 = [for (int i in ["not", "int"]) i]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:218:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:238:16: Error: Unexpected token 'for'. // var set20 = {for (int i in ["not", "int"]) i, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:219:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:239:16: Error: Unexpected token 'for'. // var map20 = {for (int i in ["not", "int"]) "bar": i, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:220:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:240:23: Error: Unexpected token 'for'. // var list30 = [await for (var i in "not stream") i]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:221:22: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:241:22: Error: Unexpected token 'for'. // var set30 = {await for (var i in "not stream") i, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:222:22: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:242:22: Error: Unexpected token 'for'. // var map30 = {await for (var i in "not stream") "bar": i, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:223:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:243:23: Error: Unexpected token 'for'. // var list40 = [await for (int i in Stream.fromIterable(["not", "int"])) i]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:224:22: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:244:22: Error: Unexpected token 'for'. // var set40 = {await for (int i in Stream.fromIterable(["not", "int"])) i, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:225:22: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:245:22: Error: Unexpected token 'for'. // var map40 = {await for (int i in Stream.fromIterable(["not", "int"])) "bar": i, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:226:17: Error: The keyword 'await' isn't allowed for a normal 'for' statement. +// pkg/front_end/testcases/control_flow_collection_inference.dart:246:17: Error: The keyword 'await' isn't allowed for a normal 'for' statement. // Try removing the keyword, or use a for-each statement. // var list50 = [await for (;;) 42]; // ^^^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:226:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:246:23: Error: Unexpected token 'for'. // var list50 = [await for (;;) 42]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:227:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement. +// pkg/front_end/testcases/control_flow_collection_inference.dart:247:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement. // Try removing the keyword, or use a for-each statement. // var set50 = {await for (;;) 42, null}; // ^^^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:227:22: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:247:22: Error: Unexpected token 'for'. // var set50 = {await for (;;) 42, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:228:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement. +// pkg/front_end/testcases/control_flow_collection_inference.dart:248:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement. // Try removing the keyword, or use a for-each statement. // var map50 = {await for (;;) "bar": 42, "baz": null}; // ^^^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:228:22: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:248:22: Error: Unexpected token 'for'. // var map50 = {await for (;;) "bar": 42, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:229:17: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:249:17: Error: Unexpected token 'for'. // var list60 = [for (; "not bool";) 42]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:230:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:250:16: Error: Unexpected token 'for'. // var set60 = {for (; "not bool";) 42, null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:231:16: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:251:16: Error: Unexpected token 'for'. // var map60 = {for (; "not bool";) "bar": 42, "baz": null}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:235:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:255:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop. // <int>[await for (int i in stream) i]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:235:15: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:255:15: Error: Unexpected token 'for'. // <int>[await for (int i in stream) i]; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:236:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:256:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop. // <int>{await for (int i in stream) i}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:236:15: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:256:15: Error: Unexpected token 'for'. // <int>{await for (int i in stream) i}; // ^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:237:34: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:257:34: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop. // <String, int>{await for (int i in stream) "bar": i}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:237:23: Error: Unexpected token 'for'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:257:23: Error: Unexpected token 'for'. // <String, int>{await for (int i in stream) "bar": i}; // ^^^ // +// pkg/front_end/testcases/control_flow_collection_inference.dart:267:23: Error: Unexpected token 'if'. +// List<int> list10 = [if (a is B) a.foo]; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:268:21: Error: Unexpected token 'if'. +// Set<int> set10 = {if (a is B) a.foo}; +// ^^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:269:26: Error: Unexpected token 'if'. +// Map<int, int> map10 = {if (a is B) a.foo: a.foo}; +// ^^ +// import self as self; import "dart:core" as core; import "dart:async" as asy; +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +class B extends self::A { + synthetic constructor •() → self::B + : super self::A::•() + ; + get foo() → core::int + return 42; +} static method oracle<T extends core::Object = dynamic>([self::oracle::T t = null]) → dynamic return true; static method testIfElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::Map<core::String, core::int> mapToInt, core::Map<core::String, core::double> mapToDouble) → dynamic { @@ -1758,6 +1858,9 @@ core::List<core::int> list91 = <dynamic>[]; core::Set<core::int> set91 = <dynamic>{null}; core::Map<core::String, core::int> map91 = <dynamic, dynamic>{"baz": null}; + core::List<core::int> list100 = <dynamic>[]; + core::Set<core::int> set100 = <dynamic, dynamic>{}; + core::Map<core::int, core::int> map100 = <dynamic, dynamic>{}; } static method testIfElementErrors(core::Map<core::int, core::int> map) → dynamic { <core::int>[]; @@ -1778,6 +1881,19 @@ <core::int>[]; <core::int>{null}; <core::String, core::int>{"baz": null}; + core::Set<dynamic> set10 = <dynamic, dynamic>{}; + core::Map<dynamic, dynamic> map10 = <dynamic, dynamic>{}; + core::Set<dynamic> set11 = <dynamic, dynamic>{}; + core::Map<dynamic, dynamic> map11 = <dynamic, dynamic>{}; + dynamic map12 = <dynamic, dynamic>{}; + dynamic map13 = <dynamic, dynamic>{}; + core::List<core::int> list20 = <dynamic>[]; + core::Set<core::int> set20 = <dynamic, dynamic>{}; + core::Map<core::int, core::int> map30 = <dynamic, dynamic>{}; + core::List<core::String> list40 = <core::String>[]; + core::Set<core::String> set40 = <core::String>{}; + core::Map<core::String, core::int> map40 = <core::String, core::int>{}; + core::Map<core::int, core::String> map41 = <core::int, core::String>{}; } static method testForElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::int index, core::Map<core::String, core::int> mapStringInt, core::Map<core::String, core::double> mapStringDouble) → dynamic { dynamic list10 = <dynamic>[]; @@ -1861,6 +1977,9 @@ core::List<core::int> list120 = <dynamic>[]; core::Set<core::int> set120 = <dynamic>{null}; core::Map<core::String, core::int> map120 = <dynamic, dynamic>{"baz": null}; + core::List<core::int> list130 = <dynamic>[]; + core::Set<core::int> set130 = <dynamic, dynamic>{}; + core::Map<core::int, core::int> map130 = <dynamic, dynamic>{}; } static method testForElementErrors(core::Map<core::int, core::int> map, core::List<core::int> list) → dynamic /* originally async */ { final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>(); @@ -1932,4 +2051,9 @@ <core::int>{}; <core::String, core::int>{}; } +static method testPromotion(self::A a) → dynamic { + core::List<core::int> list10 = <dynamic>[]; + core::Set<core::int> set10 = <dynamic, dynamic>{}; + core::Map<core::int, core::int> map10 = <dynamic, dynamic>{}; +} static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart.outline.expect b/pkg/front_end/testcases/control_flow_collection_inference.dart.outline.expect index ff425da..c40231f 100644 --- a/pkg/front_end/testcases/control_flow_collection_inference.dart.outline.expect +++ b/pkg/front_end/testcases/control_flow_collection_inference.dart.outline.expect
@@ -3,6 +3,16 @@ import "dart:core" as core; import "dart:async" as asy; +class A extends core::Object { + synthetic constructor •() → self::A + ; +} +class B extends self::A { + synthetic constructor •() → self::B + ; + get foo() → core::int + ; +} static method oracle<T extends core::Object = dynamic>([self::oracle::T t]) → dynamic ; static method testIfElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::Map<core::String, core::int> mapToInt, core::Map<core::String, core::double> mapToDouble) → dynamic @@ -15,5 +25,7 @@ ; static method testForElementErrorsNotAsync(asy::Stream<core::int> stream) → dynamic ; +static method testPromotion(self::A a) → dynamic + ; static method main() → dynamic ;
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.expect b/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.expect index 5d1a4bb..c3b0f74 100644 --- a/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.expect +++ b/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.expect
@@ -11,379 +11,466 @@ // var map82 = {if (oracle("foo")) ...mapToInt else ...dynVar, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:84:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:106:44: Error: Expected ':' after this. +// Set<dynamic> set10 = {if (oracle("foo")) 42 else "bar": 3.14}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:107:53: Error: Expected ':' after this. +// Map<dynamic, dynamic> map10 = {if (oracle("foo")) 42 else "bar": 3.14}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:108:61: Error: Expected ':' after this. +// Set<dynamic> set11 = {if (oracle("foo")) "bar": 3.14 else 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:109:70: Error: Expected ':' after this. +// Map<dynamic, dynamic> map11 = {if (oracle("foo")) "bar": 3.14 else 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:110:35: Error: Expected ':' after this. +// var map12 = {if (oracle("foo")) 42 else "bar": 3.14}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:111:52: Error: Expected ':' after this. +// var map13 = {if (oracle("foo")) "bar": 3.14 else 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:87:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int>[if (oracle("foo")) "bar"]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:85:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:88:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int>{if (oracle("foo")) "bar", null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:86:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:89:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <String, int>{if (oracle("foo")) "bar": "bar", "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:86:41: Error: A value of type 'String' can't be assigned to a variable of type 'int'. -// Try changing the type of the left hand side, or casting the right hand side to 'int'. -// <String, int>{if (oracle("foo")) "bar": "bar", "baz": null}; -// ^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:87:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int>[if (oracle("foo")) ...["bar"]]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:88:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int>{if (oracle("foo")) ...["bar"], null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:89:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:90:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:93:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>[if (oracle("foo")) ...map]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:91:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:94:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>{if (oracle("foo")) ...map, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:92:39: Error: Unexpected type 'List<String>' of a map spread entry. Expected 'dynamic' or a Map. +// pkg/front_end/testcases/control_flow_collection_inference.dart:95:39: Error: Unexpected type 'List<String>' of a map spread entry. Expected 'dynamic' or a Map. // - 'List' is from 'dart:core'. // <String, int>{if (oracle("foo")) ...["bar"], "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:93:12: Error: A value of type 'num' can't be assigned to a variable of type 'String'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:96:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'. // Try changing the type of the left hand side, or casting the right hand side to 'String'. // <String>[if (oracle("foo")) 42 else 3.14]; -// ^ +// ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:94:12: Error: A value of type 'num' can't be assigned to a variable of type 'String'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:96:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// <String>[if (oracle("foo")) 42 else 3.14]; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:97:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'. // Try changing the type of the left hand side, or casting the right hand side to 'String'. // <String>{if (oracle("foo")) 42 else 3.14, null}; -// ^ +// ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:95:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:97:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// <String>{if (oracle("foo")) 42 else 3.14, null}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:98:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'. // Try changing the type of the left hand side, or casting the right hand side to 'String'. // <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:95:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:98:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'. // Try changing the type of the left hand side, or casting the right hand side to 'String'. // <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:95:20: Error: A value of type 'num' can't be assigned to a variable of type 'String'. -// Try changing the type of the left hand side, or casting the right hand side to 'String'. -// <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null}; -// ^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:96:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:99:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>[if (oracle("foo")) ...map else 42]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:97:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. -// - 'Map' is from 'dart:core'. -// <int>{if (oracle("foo")) ...map else 42, null}; -// ^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:98:39: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. -// - 'List' is from 'dart:core'. -// <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null}; -// ^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:99:39: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. -// - 'Map' is from 'dart:core'. -// <int>[if (oracle("foo")) 42 else ...map]; -// ^ -// // pkg/front_end/testcases/control_flow_collection_inference.dart:100:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>{if (oracle("foo")) ...map else 42, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:101:54: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. +// pkg/front_end/testcases/control_flow_collection_inference.dart:101:39: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. +// - 'List' is from 'dart:core'. +// <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:102:39: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// - 'Map' is from 'dart:core'. +// <int>[if (oracle("foo")) 42 else ...map]; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:103:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// - 'Map' is from 'dart:core'. +// <int>{if (oracle("foo")) ...map else 42, null}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:104:54: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. // - 'List' is from 'dart:core'. // <String, int>{if (oracle("foo")) "bar": 42 else ...[42], "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:210:14: Error: Setter not found: 'i'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:106:24: Error: Both Iterable and Map spread elements encountered in ambiguous literal. +// Set<dynamic> set10 = {if (oracle("foo")) 42 else "bar": 3.14}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:108:24: Error: Both Iterable and Map spread elements encountered in ambiguous literal. +// Set<dynamic> set11 = {if (oracle("foo")) "bar": 3.14 else 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:112:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'. +// Try changing the type of the left hand side, or casting the right hand side to 'bool'. +// List<int> list20 = [if (42) 42]; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'. +// Try changing the type of the left hand side, or casting the right hand side to 'bool'. +// Set<int> set20 = {if (42) 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:114:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'. +// Try changing the type of the left hand side, or casting the right hand side to 'bool'. +// Map<int, int> map30 = {if (42) 42: 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:115:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// List<String> list40 = <String>[if (oracle("foo")) true else 42]; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:115:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// List<String> list40 = <String>[if (oracle("foo")) true else 42]; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// Set<String> set40 = <String>{if (oracle("foo")) true else 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:116:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// Set<String> set40 = <String>{if (oracle("foo")) true else 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:117:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:117:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:118:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:118:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:230:14: Error: Setter not found: 'i'. // <int>[for (i in <int>[1]) i]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:211:14: Error: Setter not found: 'i'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:231:14: Error: Setter not found: 'i'. // <int>{for (i in <int>[1]) i, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:212:21: Error: Setter not found: 'i'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:232:21: Error: Setter not found: 'i'. // <String, int>{for (i in <int>[1]) "bar": i, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:226:17: Error: The keyword 'await' isn't allowed for a normal 'for' statement. +// pkg/front_end/testcases/control_flow_collection_inference.dart:246:17: Error: The keyword 'await' isn't allowed for a normal 'for' statement. // Try removing the keyword, or use a for-each statement. // var list50 = [await for (;;) 42]; // ^^^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:227:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement. +// pkg/front_end/testcases/control_flow_collection_inference.dart:247:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement. // Try removing the keyword, or use a for-each statement. // var set50 = {await for (;;) 42, null}; // ^^^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:228:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement. +// pkg/front_end/testcases/control_flow_collection_inference.dart:248:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement. // Try removing the keyword, or use a for-each statement. // var map50 = {await for (;;) "bar": 42, "baz": null}; // ^^^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:190:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:210:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int>[for (int i = 0; oracle("foo"); i++) "bar"]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:191:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:211:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int>{for (int i = 0; oracle("foo"); i++) "bar", null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:192:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:212:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:192:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:212:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:192:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:212:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:192:14: Error: A value of type 'String' can't be assigned to a variable of type 'int'. -// Try changing the type of the left hand side, or casting the right hand side to 'int'. -// <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null}; -// ^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:193:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int>[for (int i = 0; oracle("foo"); i++) ...["bar"]]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:194:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int>{for (int i = 0; oracle("foo"); i++) ...["bar"], null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:195:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:195:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:195:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:215:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:196:48: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:216:48: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>[for (int i = 0; oracle("foo"); i++) ...map]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:197:48: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:217:48: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>{for (int i = 0; oracle("foo"); i++) ...map, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:198:53: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. +// pkg/front_end/testcases/control_flow_collection_inference.dart:218:53: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. // - 'List' is from 'dart:core'. // <int, int>{for (int i = 0; oracle("foo"); i++) ...list, 42: null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:199:48: Error: A value of type 'num' can't be assigned to a variable of type 'String'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:219:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'. // Try changing the type of the left hand side, or casting the right hand side to 'String'. // <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14]; -// ^ +// ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:200:48: Error: A value of type 'num' can't be assigned to a variable of type 'String'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:219:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14]; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:220:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'. // Try changing the type of the left hand side, or casting the right hand side to 'String'. // <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null}; -// ^ +// ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:201:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:220:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:221:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'. // Try changing the type of the left hand side, or casting the right hand side to 'String'. // <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:201:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:221:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'. // Try changing the type of the left hand side, or casting the right hand side to 'String'. // <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:201:20: Error: A value of type 'num' can't be assigned to a variable of type 'String'. -// Try changing the type of the left hand side, or casting the right hand side to 'String'. -// <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null}; -// ^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:202:62: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:222:62: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:203:62: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:223:62: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:204:70: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. +// pkg/front_end/testcases/control_flow_collection_inference.dart:224:70: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. // - 'List' is from 'dart:core'. // <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:205:70: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:225:70: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:206:70: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:226:70: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:207:85: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. +// pkg/front_end/testcases/control_flow_collection_inference.dart:227:85: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. // - 'List' is from 'dart:core'. // <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:214:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:234:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. // - 'Iterable' is from 'dart:core'. // var list10 = [for (var i in "not iterable") i]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:215:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:235:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. // - 'Iterable' is from 'dart:core'. // var set10 = {for (var i in "not iterable") i, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:216:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:236:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. // - 'Iterable' is from 'dart:core'. // var map10 = {for (var i in "not iterable") "bar": i, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:217:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var list20 = [for (int i in ["not", "int"]) i]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:217:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var list20 = [for (int i in ["not", "int"]) i]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:218:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var set20 = {for (int i in ["not", "int"]) i, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:218:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var set20 = {for (int i in ["not", "int"]) i, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:219:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var map20 = {for (int i in ["not", "int"]) "bar": i, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:219:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var map20 = {for (int i in ["not", "int"]) "bar": i, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:220:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:240:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. // - 'Stream' is from 'dart:async'. // var list30 = [await for (var i in "not stream") i]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:221:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:241:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. // - 'Stream' is from 'dart:async'. // var set30 = {await for (var i in "not stream") i, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:222:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:242:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. // - 'Stream' is from 'dart:async'. // var map30 = {await for (var i in "not stream") "bar": i, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:223:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var list40 = [await for (int i in Stream.fromIterable(["not", "int"])) i]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:223:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var list40 = [await for (int i in Stream.fromIterable(["not", "int"])) i]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:224:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var set40 = {await for (int i in Stream.fromIterable(["not", "int"])) i, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:224:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var set40 = {await for (int i in Stream.fromIterable(["not", "int"])) i, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:225:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var map40 = {await for (int i in Stream.fromIterable(["not", "int"])) "bar": i, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:225:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var map40 = {await for (int i in Stream.fromIterable(["not", "int"])) "bar": i, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:229:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:249:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. // Try changing the type of the left hand side, or casting the right hand side to 'bool'. // var list60 = [for (; "not bool";) 42]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:230:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. // Try changing the type of the left hand side, or casting the right hand side to 'bool'. // var set60 = {for (; "not bool";) 42, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:231:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:251:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. // Try changing the type of the left hand side, or casting the right hand side to 'bool'. // var map60 = {for (; "not bool";) "bar": 42, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:235:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:255:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop. // <int>[await for (int i in stream) i]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:236:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:256:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop. // <int>{await for (int i in stream) i}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:237:34: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:257:34: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop. // <String, int>{await for (int i in stream) "bar": i}; // ^^ @@ -393,198 +480,210 @@ import "dart:collection" as col; import "dart:async" as asy; +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +class B extends self::A { + synthetic constructor •() → self::B + : super self::A::•() + ; + get foo() → core::int + return 42; +} static method oracle<T extends core::Object = dynamic>([self::oracle::T t = null]) → dynamic return true; static method testIfElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::Map<core::String, core::int> mapToInt, core::Map<core::String, core::double> mapToDouble) → dynamic { core::List<core::int> list10 = block { final core::List<core::int> #t1 = <core::int>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t1.{core::List::add}(42); } =>#t1; core::Set<core::int> set10 = block { final core::Set<core::int> #t2 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t2.{core::Set::add}(42); #t2.{core::Set::add}(null); } =>#t2; core::Map<core::String, core::int> map10 = block { final core::Map<core::String, core::int> #t3 = <core::String, core::int>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t3.{core::Map::[]=}("bar", 42); #t3.{core::Map::[]=}("baz", null); } =>#t3; core::List<dynamic> list11 = block { final core::List<dynamic> #t4 = <dynamic>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t4.{core::List::add}(dynVar); } =>#t4; core::Set<dynamic> set11 = block { final core::Set<dynamic> #t5 = col::LinkedHashSet::•<dynamic>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t5.{core::Set::add}(dynVar); #t5.{core::Set::add}(null); } =>#t5; core::Map<core::String, dynamic> map11 = block { final core::Map<core::String, dynamic> #t6 = <core::String, dynamic>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t6.{core::Map::[]=}("bar", dynVar); #t6.{core::Map::[]=}("baz", null); } =>#t6; core::List<core::List<core::int>> list12 = block { final core::List<core::List<core::int>> #t7 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t7.{core::List::add}(<core::int>[42]); } =>#t7; core::Set<core::List<core::int>> set12 = block { final core::Set<core::List<core::int>> #t8 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t8.{core::Set::add}(<core::int>[42]); #t8.{core::Set::add}(null); } =>#t8; core::Map<core::String, core::List<core::int>> map12 = block { final core::Map<core::String, core::List<core::int>> #t9 = <core::String, core::List<core::int>>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t9.{core::Map::[]=}("bar", <core::int>[42]); #t9.{core::Map::[]=}("baz", null); } =>#t9; core::List<core::int> list20 = block { final core::List<core::int> #t10 = <core::int>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::int #t11 in <core::int>[42]) #t10.{core::List::add}(#t11); } =>#t10; core::Set<core::int> set20 = block { final core::Set<core::int> #t12 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::int #t13 in <core::int>[42]) #t12.{core::Set::add}(#t13); #t12.{core::Set::add}(null); } =>#t12; core::Map<core::String, core::int> map20 = block { final core::Map<core::String, core::int> #t14 = <core::String, core::int>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::MapEntry<core::String, core::int> #t15 in <core::String, core::int>{"bar": 42}.{core::Map::entries}) #t14.{core::Map::[]=}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value}); #t14.{core::Map::[]=}("baz", null); } =>#t14; core::List<dynamic> list21 = block { final core::List<dynamic> #t16 = <dynamic>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final dynamic #t17 in <dynamic>[dynVar]) #t16.{core::List::add}(#t17); } =>#t16; core::Set<dynamic> set21 = block { final core::Set<dynamic> #t18 = col::LinkedHashSet::•<dynamic>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final dynamic #t19 in <dynamic>[dynVar]) #t18.{core::Set::add}(#t19); #t18.{core::Set::add}(null); } =>#t18; core::Map<core::String, dynamic> map21 = block { final core::Map<core::String, dynamic> #t20 = <core::String, dynamic>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::MapEntry<core::String, dynamic> #t21 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries}) #t20.{core::Map::[]=}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value}); #t20.{core::Map::[]=}("baz", null); } =>#t20; core::List<core::List<core::int>> list22 = block { final core::List<core::List<core::int>> #t22 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::List<core::int> #t23 in <core::List<core::int>>[<core::int>[42]]) #t22.{core::List::add}(#t23); } =>#t22; core::Set<core::List<core::int>> set22 = block { final core::Set<core::List<core::int>> #t24 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::List<core::int> #t25 in <core::List<core::int>>[<core::int>[42]]) #t24.{core::Set::add}(#t25); #t24.{core::Set::add}(null); } =>#t24; core::Map<core::String, core::List<core::int>> map22 = block { final core::Map<core::String, core::List<core::int>> #t26 = <core::String, core::List<core::int>>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::MapEntry<core::String, core::List<core::int>> #t27 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries}) #t26.{core::Map::[]=}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value}); #t26.{core::Map::[]=}("baz", null); } =>#t26; core::List<core::int> list30 = block { final core::List<core::int> #t28 = <core::int>[]; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::int #t29 in <core::int>[42]) #t28.{core::List::add}(#t29); } =>#t28; core::Set<core::int> set30 = block { final core::Set<core::int> #t30 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::int #t31 in <core::int>[42]) #t30.{core::Set::add}(#t31); #t30.{core::Set::add}(null); } =>#t30; core::Map<core::String, core::int> map30 = block { final core::Map<core::String, core::int> #t32 = <core::String, core::int>{}; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::MapEntry<core::String, core::int> #t33 in <core::String, core::int>{"bar": 42}.{core::Map::entries}) #t32.{core::Map::[]=}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value}); #t32.{core::Map::[]=}("baz", null); } =>#t32; core::List<dynamic> list31 = block { final core::List<dynamic> #t34 = <dynamic>[]; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final dynamic #t35 in <dynamic>[dynVar]) #t34.{core::List::add}(#t35); } =>#t34; core::Set<dynamic> set31 = block { final core::Set<dynamic> #t36 = col::LinkedHashSet::•<dynamic>(); - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final dynamic #t37 in <dynamic>[dynVar]) #t36.{core::Set::add}(#t37); #t36.{core::Set::add}(null); } =>#t36; core::Map<core::String, dynamic> map31 = block { final core::Map<core::String, dynamic> #t38 = <core::String, dynamic>{}; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::MapEntry<core::String, dynamic> #t39 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries}) #t38.{core::Map::[]=}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value}); #t38.{core::Map::[]=}("baz", null); } =>#t38; core::List<core::List<core::int>> list33 = block { final core::List<core::List<core::int>> #t40 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::List<core::int> #t41 in <core::List<core::int>>[<core::int>[42]]) #t40.{core::List::add}(#t41); } =>#t40; core::Set<core::List<core::int>> set33 = block { final core::Set<core::List<core::int>> #t42 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::List<core::int> #t43 in <core::List<core::int>>[<core::int>[42]]) #t42.{core::Set::add}(#t43); #t42.{core::Set::add}(null); } =>#t42; core::Map<core::String, core::List<core::int>> map33 = block { final core::Map<core::String, core::List<core::int>> #t44 = <core::String, core::List<core::int>>{}; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::MapEntry<core::String, core::List<core::int>> #t45 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries}) #t44.{core::Map::[]=}(#t45.{core::MapEntry::key}, #t45.{core::MapEntry::value}); #t44.{core::Map::[]=}("baz", null); } =>#t44; core::List<core::List<core::int>> list40 = block { final core::List<core::List<core::int>> #t46 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::List<core::int> #t47 in <core::List<core::int>>[<core::int>[]]) #t46.{core::List::add}(#t47); } =>#t46; core::Set<core::List<core::int>> set40 = block { final core::Set<core::List<core::int>> #t48 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::List<core::int> #t49 in <core::List<core::int>>[<core::int>[]]) #t48.{core::Set::add}(#t49); #t48.{core::Set::add}(null); @@ -594,173 +693,173 @@ ^"; core::List<core::List<core::int>> list41 = block { final core::List<core::List<core::int>> #t50 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::List<core::int> #t51 in let final core::Set<core::List<core::int>> #t52 = col::LinkedHashSet::•<core::List<core::int>>() in let final dynamic #t53 = #t52.{core::Set::add}(<core::int>[]) in #t52) #t50.{core::List::add}(#t51); } =>#t50; core::Set<core::List<core::int>> set41 = block { final core::Set<core::List<core::int>> #t54 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::List<core::int> #t55 in let final core::Set<core::List<core::int>> #t56 = col::LinkedHashSet::•<core::List<core::int>>() in let final dynamic #t57 = #t56.{core::Set::add}(<core::int>[]) in #t56) #t54.{core::Set::add}(#t55); #t54.{core::Set::add}(null); } =>#t54; core::List<core::List<core::int>> list42 = block { final core::List<core::List<core::int>> #t58 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::List<core::int> #t59 in <core::List<core::int>>[<core::int>[]]) #t58.{core::List::add}(#t59); } =>#t58; core::Set<core::List<core::int>> set42 = block { final core::Set<core::List<core::int>> #t60 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::List<core::int> #t61 in <core::List<core::int>>[<core::int>[]]) #t60.{core::Set::add}(#t61); #t60.{core::Set::add}(null); } =>#t60; core::Map<core::String, core::List<core::int>> map42 = block { final core::Map<core::String, core::List<core::int>> #t62 = <core::String, core::List<core::int>>{}; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::MapEntry<core::String, core::List<core::int>> #t63 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) #t62.{core::Map::[]=}(#t63.{core::MapEntry::key}, #t63.{core::MapEntry::value}); #t62.{core::Map::[]=}("baz", null); } =>#t62; core::List<core::int> list50 = block { final core::List<core::int> #t64 = <core::int>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::int #t65 in <core::int>[]) #t64.{core::List::add}(#t65); } =>#t64; core::Set<core::int> set50 = block { final core::Set<core::int> #t66 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::int #t67 in <core::int>[]) #t66.{core::Set::add}(#t67); #t66.{core::Set::add}(null); } =>#t66; core::Map<core::String, core::int> map50 = block { final core::Map<core::String, core::int> #t68 = <core::String, core::int>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::MapEntry<core::String, core::int> #t69 in <core::String, core::int>{}.{core::Map::entries}) #t68.{core::Map::[]=}(#t69.{core::MapEntry::key}, #t69.{core::MapEntry::value}); #t68.{core::Map::[]=}("baz", null); } =>#t68; core::List<core::int> list51 = block { final core::List<core::int> #t70 = <core::int>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::int #t71 in let final core::Set<core::int> #t72 = col::LinkedHashSet::•<core::int>() in #t72) #t70.{core::List::add}(#t71); } =>#t70; core::Set<core::int> set51 = block { final core::Set<core::int> #t73 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::int #t74 in let final core::Set<core::int> #t75 = col::LinkedHashSet::•<core::int>() in #t75) #t73.{core::Set::add}(#t74); #t73.{core::Set::add}(null); } =>#t73; core::List<core::int> list52 = block { final core::List<core::int> #t76 = <core::int>[]; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::int #t77 in <core::int>[]) #t76.{core::List::add}(#t77); } =>#t76; core::Set<core::int> set52 = block { final core::Set<core::int> #t78 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::int #t79 in <core::int>[]) #t78.{core::Set::add}(#t79); #t78.{core::Set::add}(null); } =>#t78; core::Map<core::String, core::int> map52 = block { final core::Map<core::String, core::int> #t80 = <core::String, core::int>{}; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::MapEntry<core::String, core::int> #t81 in <core::String, core::int>{}.{core::Map::entries}) #t80.{core::Map::[]=}(#t81.{core::MapEntry::key}, #t81.{core::MapEntry::value}); #t80.{core::Map::[]=}("baz", null); } =>#t80; core::List<core::List<core::int>> list60 = block { final core::List<core::List<core::int>> #t82 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::List<core::int> #t83 in <core::List<core::int>>[<core::int>[]]) #t82.{core::List::add}(#t83); } =>#t82; core::Set<core::List<core::int>> set60 = block { final core::Set<core::List<core::int>> #t84 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::List<core::int> #t85 in <core::List<core::int>>[<core::int>[]]) #t84.{core::Set::add}(#t85); #t84.{core::Set::add}(null); } =>#t84; core::Map<core::String, core::List<core::int>> map60 = block { final core::Map<core::String, core::List<core::int>> #t86 = <core::String, core::List<core::int>>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::MapEntry<core::String, core::List<core::int>> #t87 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) #t86.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value}); #t86.{core::Map::[]=}("baz", null); } =>#t86; core::List<core::List<core::int>> list61 = block { final core::List<core::List<core::int>> #t88 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::List<core::int> #t89 in <core::List<core::int>>[<core::int>[]]) #t88.{core::List::add}(#t89); } =>#t88; core::Set<core::List<core::int>> set61 = block { final core::Set<core::List<core::int>> #t90 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::List<core::int> #t91 in <core::List<core::int>>[<core::int>[]]) #t90.{core::Set::add}(#t91); #t90.{core::Set::add}(null); } =>#t90; core::Map<core::String, core::List<core::int>> map61 = block { final core::Map<core::String, core::List<core::int>> #t92 = <core::String, core::List<core::int>>{}; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::MapEntry<core::String, core::List<core::int>> #t93 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) #t92.{core::Map::[]=}(#t93.{core::MapEntry::key}, #t93.{core::MapEntry::value}); #t92.{core::Map::[]=}("baz", null); } =>#t92; core::List<core::List<core::int>> list70 = block { final core::List<core::List<core::int>> #t94 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t94.{core::List::add}(<core::int>[]); } =>#t94; core::Set<core::List<core::int>> set70 = block { final core::Set<core::List<core::int>> #t95 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t95.{core::Set::add}(<core::int>[]); #t95.{core::Set::add}(null); } =>#t95; core::List<core::List<core::int>> list71 = block { final core::List<core::List<core::int>> #t96 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) #t96.{core::List::add}(<core::int>[]); } =>#t96; core::Set<core::List<core::int>> set71 = block { final core::Set<core::List<core::int>> #t97 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) #t97.{core::Set::add}(<core::int>[]); #t97.{core::Set::add}(null); } =>#t97; core::List<core::num> list80 = block { final core::List<core::num> #t98 = <core::num>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t98.{core::List::add}(42); else #t98.{core::List::add}(3.14); } =>#t98; core::Set<core::num> set80 = block { final core::Set<core::num> #t99 = col::LinkedHashSet::•<core::num>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t99.{core::Set::add}(42); else #t99.{core::Set::add}(3.14); @@ -768,7 +867,7 @@ } =>#t99; core::Map<core::String, core::num> map80 = block { final core::Map<core::String, core::num> #t100 = <core::String, core::num>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t100.{core::Map::[]=}("bar", 42); else #t100.{core::Map::[]=}("bar", 3.14); @@ -776,7 +875,7 @@ } =>#t100; core::List<core::num> list81 = block { final core::List<core::num> #t101 = <core::num>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::num #t102 in listInt) #t101.{core::List::add}(#t102); else @@ -785,7 +884,7 @@ } =>#t101; core::Set<core::num> set81 = block { final core::Set<core::num> #t104 = col::LinkedHashSet::•<core::num>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::num #t105 in listInt) #t104.{core::Set::add}(#t105); else @@ -795,7 +894,7 @@ } =>#t104; core::Map<core::String, core::num> map81 = block { final core::Map<core::String, core::num> #t107 = <core::String, core::num>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::MapEntry<core::String, core::num> #t108 in mapToInt.{core::Map::entries}) #t107.{core::Map::[]=}(#t108.{core::MapEntry::key}, #t108.{core::MapEntry::value}); else @@ -805,7 +904,7 @@ } =>#t107; core::List<dynamic> list82 = block { final core::List<dynamic> #t110 = <dynamic>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final dynamic #t111 in listInt) #t110.{core::List::add}(#t111); else @@ -814,7 +913,7 @@ } =>#t110; core::Set<dynamic> set82 = block { final core::Set<dynamic> #t113 = col::LinkedHashSet::•<dynamic>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final dynamic #t114 in listInt) #t113.{core::Set::add}(#t114); else @@ -824,7 +923,7 @@ } =>#t113; core::Set<dynamic> map82 = block { final core::Set<dynamic> #t116 = col::LinkedHashSet::•<dynamic>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t116.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:71:38: Error: Unexpected type 'Map<String, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. var map82 = {if (oracle(\"foo\")) ...mapToInt else ...dynVar, null}; @@ -836,7 +935,7 @@ } =>#t116; core::List<core::num> list83 = block { final core::List<core::num> #t118 = <core::num>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t118.{core::List::add}(42); else for (final core::num #t119 in listDouble) @@ -844,7 +943,7 @@ } =>#t118; core::Set<core::num> set83 = block { final core::Set<core::num> #t120 = col::LinkedHashSet::•<core::num>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::num #t121 in listInt) #t120.{core::Set::add}(#t121); else @@ -853,7 +952,7 @@ } =>#t120; core::Map<core::String, core::num> map83 = block { final core::Map<core::String, core::num> #t122 = <core::String, core::num>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::MapEntry<core::String, core::num> #t123 in mapToInt.{core::Map::entries}) #t122.{core::Map::[]=}(#t123.{core::MapEntry::key}, #t123.{core::MapEntry::value}); else @@ -862,24 +961,24 @@ } =>#t122; core::List<core::int> list90 = block { final core::List<core::int> #t124 = <core::int>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t124.{core::List::add}(dynVar as{TypeError} core::int); } =>#t124; core::Set<core::int> set90 = block { final core::Set<core::int> #t125 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t125.{core::Set::add}(dynVar as{TypeError} core::int); #t125.{core::Set::add}(null); } =>#t125; core::Map<core::String, core::int> map90 = block { final core::Map<core::String, core::int> #t126 = <core::String, core::int>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t126.{core::Map::[]=}("bar", dynVar as{TypeError} core::int); #t126.{core::Map::[]=}("baz", null); } =>#t126; core::List<core::int> list91 = block { final core::List<core::int> #t127 = <core::int>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final dynamic #t128 in dynVar as{TypeError} core::Iterable<dynamic>) { final core::int #t129 = #t128 as{TypeError} core::int; #t127.{core::List::add}(#t129); @@ -887,7 +986,7 @@ } =>#t127; core::Set<core::int> set91 = block { final core::Set<core::int> #t130 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final dynamic #t131 in dynVar as{TypeError} core::Iterable<dynamic>) { final core::int #t132 = #t131 as{TypeError} core::int; #t130.{core::Set::add}(#t132); @@ -896,7 +995,7 @@ } =>#t130; core::Map<core::String, core::int> map91 = block { final core::Map<core::String, core::int> #t133 = <core::String, core::int>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::MapEntry<dynamic, dynamic> #t134 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) { final core::String #t135 = #t134.{core::MapEntry::key} as{TypeError} core::String; final core::int #t136 = #t134.{core::MapEntry::value} as{TypeError} core::int; @@ -904,1081 +1003,1311 @@ } #t133.{core::Map::[]=}("baz", null); } =>#t133; + core::List<core::int> list100 = block { + final core::List<core::int> #t137 = <core::int>[]; + if(dynVar as{TypeError} core::bool) + #t137.{core::List::add}(42); + } =>#t137; + core::Set<core::int> set100 = block { + final core::Set<core::int> #t138 = col::LinkedHashSet::•<core::int>(); + if(dynVar as{TypeError} core::bool) + #t138.{core::Set::add}(42); + } =>#t138; + core::Map<core::int, core::int> map100 = block { + final core::Map<core::int, core::int> #t139 = <core::int, core::int>{}; + if(dynVar as{TypeError} core::bool) + #t139.{core::Map::[]=}(42, 42); + } =>#t139; } static method testIfElementErrors(core::Map<core::int, core::int> map) → dynamic { - <core::int>[invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:84:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'. -Try changing the type of the left hand side, or casting the right hand side to 'int'. - <int>[if (oracle(\"foo\")) \"bar\"]; - ^"]; - let final core::Set<core::int> #t137 = col::LinkedHashSet::•<core::int>() in let final dynamic #t138 = #t137.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:85:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'. -Try changing the type of the left hand side, or casting the right hand side to 'int'. - <int>{if (oracle(\"foo\")) \"bar\", null}; - ^") in let final dynamic #t139 = #t137.{core::Set::add}(null) in #t137; - <core::String, core::int>{null: invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:86:41: Error: A value of type 'String' can't be assigned to a variable of type 'int'. -Try changing the type of the left hand side, or casting the right hand side to 'int'. - <String, int>{if (oracle(\"foo\")) \"bar\": \"bar\", \"baz\": null}; - ^", "baz": null}; block { final core::List<core::int> #t140 = <core::int>[]; - if(self::oracle<core::String>("foo")) - for (final core::int #t141 in <core::int>[let final<BottomType> #t142 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:87:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t140.{core::List::add}(let final<BottomType> #t141 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:87:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +Try changing the type of the left hand side, or casting the right hand side to 'int'. + <int>[if (oracle(\"foo\")) \"bar\"]; + ^" in "bar" as{TypeError} core::int); + } =>#t140; + block { + final core::Set<core::int> #t142 = col::LinkedHashSet::•<core::int>(); + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t142.{core::Set::add}(let final<BottomType> #t143 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:88:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +Try changing the type of the left hand side, or casting the right hand side to 'int'. + <int>{if (oracle(\"foo\")) \"bar\", null}; + ^" in "bar" as{TypeError} core::int); + #t142.{core::Set::add}(null); + } =>#t142; + block { + final core::Map<core::String, core::int> #t144 = <core::String, core::int>{}; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t144.{core::Map::[]=}("bar", let final<BottomType> #t145 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:89:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +Try changing the type of the left hand side, or casting the right hand side to 'int'. + <String, int>{if (oracle(\"foo\")) \"bar\": \"bar\", \"baz\": null}; + ^" in "bar" as{TypeError} core::int); + #t144.{core::Map::[]=}("baz", null); + } =>#t144; + block { + final core::List<core::int> #t146 = <core::int>[]; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + for (final core::int #t147 in <core::int>[let final<BottomType> #t148 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int>[if (oracle(\"foo\")) ...[\"bar\"]]; ^" in "bar" as{TypeError} core::int]) - #t140.{core::List::add}(#t141); - } =>#t140; + #t146.{core::List::add}(#t147); + } =>#t146; block { - final core::Set<core::int> #t143 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) - for (final core::int #t144 in <core::int>[let final<BottomType> #t145 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:88:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + final core::Set<core::int> #t149 = col::LinkedHashSet::•<core::int>(); + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + for (final core::int #t150 in <core::int>[let final<BottomType> #t151 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int>{if (oracle(\"foo\")) ...[\"bar\"], null}; ^" in "bar" as{TypeError} core::int]) - #t143.{core::Set::add}(#t144); - #t143.{core::Set::add}(null); - } =>#t143; + #t149.{core::Set::add}(#t150); + #t149.{core::Set::add}(null); + } =>#t149; block { - final core::Map<core::String, core::int> #t146 = <core::String, core::int>{}; - if(self::oracle<core::String>("foo")) - for (final core::MapEntry<core::String, core::int> #t147 in <core::String, core::int>{"bar": let final<BottomType> #t148 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:89:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + final core::Map<core::String, core::int> #t152 = <core::String, core::int>{}; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + for (final core::MapEntry<core::String, core::int> #t153 in <core::String, core::int>{"bar": let final<BottomType> #t154 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <String, int>{if (oracle(\"foo\")) ...{\"bar\": \"bar\"}, \"baz\": null}; ^" in "bar" as{TypeError} core::int}.{core::Map::entries}) - #t146.{core::Map::[]=}(#t147.{core::MapEntry::key}, #t147.{core::MapEntry::value}); - #t146.{core::Map::[]=}("baz", null); - } =>#t146; + #t152.{core::Map::[]=}(#t153.{core::MapEntry::key}, #t153.{core::MapEntry::value}); + #t152.{core::Map::[]=}("baz", null); + } =>#t152; block { - final core::List<core::int> #t149 = <core::int>[]; - if(self::oracle<core::String>("foo")) - #t149.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:90:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + final core::List<core::int> #t155 = <core::int>[]; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t155.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:93:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>[if (oracle(\"foo\")) ...map]; - ^" as{TypeError} core::int); - } =>#t149; + ^"); + } =>#t155; block { - final core::Set<core::int> #t150 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) - #t150.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:91:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + final core::Set<core::int> #t156 = col::LinkedHashSet::•<core::int>(); + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t156.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:94:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>{if (oracle(\"foo\")) ...map, null}; - ^" as{TypeError} core::int); - #t150.{core::Set::add}(null); - } =>#t150; - <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:92:39: Error: Unexpected type 'List<String>' of a map spread entry. Expected 'dynamic' or a Map. + ^"); + #t156.{core::Set::add}(null); + } =>#t156; + <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:95:39: Error: Unexpected type 'List<String>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{if (oracle(\"foo\")) ...[\"bar\"], \"baz\": null}; - ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:92:39: Error: Unexpected type 'List<String>' of a map spread entry. Expected 'dynamic' or a Map. + ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:95:39: Error: Unexpected type 'List<String>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{if (oracle(\"foo\")) ...[\"bar\"], \"baz\": null}; ^": null}; - <core::String>[invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:93:12: Error: A value of type 'num' can't be assigned to a variable of type 'String'. + block { + final core::List<core::String> #t157 = <core::String>[]; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t157.{core::List::add}(let final<BottomType> #t158 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:96:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'. Try changing the type of the left hand side, or casting the right hand side to 'String'. <String>[if (oracle(\"foo\")) 42 else 3.14]; - ^"]; - let final core::Set<core::String> #t151 = col::LinkedHashSet::•<core::String>() in let final dynamic #t152 = #t151.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:94:12: Error: A value of type 'num' can't be assigned to a variable of type 'String'. + ^" in 42 as{TypeError} core::String); + else + #t157.{core::List::add}(let final<BottomType> #t159 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:96:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + <String>[if (oracle(\"foo\")) 42 else 3.14]; + ^" in 3.14 as{TypeError} core::String); + } =>#t157; + block { + final core::Set<core::String> #t160 = col::LinkedHashSet::•<core::String>(); + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t160.{core::Set::add}(let final<BottomType> #t161 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:97:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'. Try changing the type of the left hand side, or casting the right hand side to 'String'. <String>{if (oracle(\"foo\")) 42 else 3.14, null}; - ^") in let final dynamic #t153 = #t151.{core::Set::add}(null) in #t151; - <core::String, core::String>{null: invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:95:20: Error: A value of type 'num' can't be assigned to a variable of type 'String'. + ^" in 42 as{TypeError} core::String); + else + #t160.{core::Set::add}(let final<BottomType> #t162 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:97:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + <String>{if (oracle(\"foo\")) 42 else 3.14, null}; + ^" in 3.14 as{TypeError} core::String); + #t160.{core::Set::add}(null); + } =>#t160; + block { + final core::Map<core::String, core::String> #t163 = <core::String, core::String>{}; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t163.{core::Map::[]=}("bar", let final<BottomType> #t164 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:98:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'. Try changing the type of the left hand side, or casting the right hand side to 'String'. <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null}; - ^", "baz": null}; + ^" in 42 as{TypeError} core::String); + else + #t163.{core::Map::[]=}("baz", let final<BottomType> #t165 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:98:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null}; + ^" in 3.14 as{TypeError} core::String); + #t163.{core::Map::[]=}("baz", null); + } =>#t163; block { - final core::List<core::int> #t154 = <core::int>[]; - if(self::oracle<core::String>("foo")) - #t154.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:96:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + final core::List<core::int> #t166 = <core::int>[]; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t166.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:99:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>[if (oracle(\"foo\")) ...map else 42]; - ^" as{TypeError} core::int); + ^"); else - #t154.{core::List::add}(42 as{TypeError} core::int); - } =>#t154; + #t166.{core::List::add}(42); + } =>#t166; block { - final core::Set<core::int> #t155 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) - #t155.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:97:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + final core::Set<core::int> #t167 = col::LinkedHashSet::•<core::int>(); + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t167.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:100:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>{if (oracle(\"foo\")) ...map else 42, null}; - ^" as{TypeError} core::int); + ^"); else - #t155.{core::Set::add}(42 as{TypeError} core::int); - #t155.{core::Set::add}(null); - } =>#t155; - <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:98:39: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + #t167.{core::Set::add}(42); + #t167.{core::Set::add}(null); + } =>#t167; + <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:101:39: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{if (oracle(\"foo\")) ...[42] else \"bar\": 42, \"baz\": null}; - ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:98:39: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:101:39: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{if (oracle(\"foo\")) ...[42] else \"bar\": 42, \"baz\": null}; ^": null}; block { - final core::List<core::int> #t156 = <core::int>[]; - if(self::oracle<core::String>("foo")) - #t156.{core::List::add}(42 as{TypeError} core::int); + final core::List<core::int> #t168 = <core::int>[]; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t168.{core::List::add}(42); else - #t156.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:99:39: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + #t168.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:102:39: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>[if (oracle(\"foo\")) 42 else ...map]; - ^" as{TypeError} core::int); - } =>#t156; + ^"); + } =>#t168; block { - final core::Set<core::int> #t157 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) - #t157.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:100:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + final core::Set<core::int> #t169 = col::LinkedHashSet::•<core::int>(); + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t169.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:103:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>{if (oracle(\"foo\")) ...map else 42, null}; - ^" as{TypeError} core::int); + ^"); else - #t157.{core::Set::add}(42 as{TypeError} core::int); - #t157.{core::Set::add}(null); - } =>#t157; - <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:101:54: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + #t169.{core::Set::add}(42); + #t169.{core::Set::add}(null); + } =>#t169; + <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:104:54: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{if (oracle(\"foo\")) \"bar\": 42 else ...[42], \"baz\": null}; - ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:101:54: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:104:54: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{if (oracle(\"foo\")) \"bar\": 42 else ...[42], \"baz\": null}; ^": null}; + core::Set<dynamic> set10 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:106:24: Error: Both Iterable and Map spread elements encountered in ambiguous literal. + Set<dynamic> set10 = {if (oracle(\"foo\")) 42 else \"bar\": 3.14}; + ^"; + core::Map<dynamic, dynamic> map10 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:107:53: Error: Expected ':' after this. + Map<dynamic, dynamic> map10 = {if (oracle(\"foo\")) 42 else \"bar\": 3.14}; + ^": null}; + core::Set<dynamic> set11 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:108:24: Error: Both Iterable and Map spread elements encountered in ambiguous literal. + Set<dynamic> set11 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42}; + ^"; + core::Map<dynamic, dynamic> map11 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:109:70: Error: Expected ':' after this. + Map<dynamic, dynamic> map11 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42}; + ^": null}; + core::Map<<BottomType>, core::Null> map12 = <<BottomType>, core::Null>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:110:35: Error: Expected ':' after this. + var map12 = {if (oracle(\"foo\")) 42 else \"bar\": 3.14}; + ^": null}; + core::Map<<BottomType>, core::Null> map13 = <<BottomType>, core::Null>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:111:52: Error: Expected ':' after this. + var map13 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42}; + ^": null}; + core::List<core::int> list20 = block { + final core::List<core::int> #t170 = <core::int>[]; + if(let final<BottomType> #t171 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:112:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'. +Try changing the type of the left hand side, or casting the right hand side to 'bool'. + List<int> list20 = [if (42) 42]; + ^" in 42 as{TypeError} core::bool) + #t170.{core::List::add}(42); + } =>#t170; + core::Set<core::int> set20 = block { + final core::Set<core::int> #t172 = col::LinkedHashSet::•<core::int>(); + if(let final<BottomType> #t173 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'. +Try changing the type of the left hand side, or casting the right hand side to 'bool'. + Set<int> set20 = {if (42) 42}; + ^" in 42 as{TypeError} core::bool) + #t172.{core::Set::add}(42); + } =>#t172; + core::Map<core::int, core::int> map30 = block { + final core::Map<core::int, core::int> #t174 = <core::int, core::int>{}; + if(let final<BottomType> #t175 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:114:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'. +Try changing the type of the left hand side, or casting the right hand side to 'bool'. + Map<int, int> map30 = {if (42) 42: 42}; + ^" in 42 as{TypeError} core::bool) + #t174.{core::Map::[]=}(42, 42); + } =>#t174; + core::List<core::String> list40 = block { + final core::List<core::String> #t176 = <core::String>[]; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t176.{core::List::add}(let final<BottomType> #t177 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:115:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + List<String> list40 = <String>[if (oracle(\"foo\")) true else 42]; + ^" in true as{TypeError} core::String); + else + #t176.{core::List::add}(let final<BottomType> #t178 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:115:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + List<String> list40 = <String>[if (oracle(\"foo\")) true else 42]; + ^" in 42 as{TypeError} core::String); + } =>#t176; + core::Set<core::String> set40 = block { + final core::Set<core::String> #t179 = col::LinkedHashSet::•<core::String>(); + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t179.{core::Set::add}(let final<BottomType> #t180 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42}; + ^" in true as{TypeError} core::String); + else + #t179.{core::Set::add}(let final<BottomType> #t181 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:116:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42}; + ^" in 42 as{TypeError} core::String); + } =>#t179; + core::Map<core::String, core::int> map40 = block { + final core::Map<core::String, core::int> #t182 = <core::String, core::int>{}; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t182.{core::Map::[]=}(let final<BottomType> #t183 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:117:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42}; + ^" in true as{TypeError} core::String, 42); + else + #t182.{core::Map::[]=}(let final<BottomType> #t184 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:117:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42}; + ^" in 42 as{TypeError} core::String, 42); + } =>#t182; + core::Map<core::int, core::String> map41 = block { + final core::Map<core::int, core::String> #t185 = <core::int, core::String>{}; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t185.{core::Map::[]=}(42, let final<BottomType> #t186 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:118:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42}; + ^" in true as{TypeError} core::String); + else + #t185.{core::Map::[]=}(42, let final<BottomType> #t187 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:118:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42}; + ^" in 42 as{TypeError} core::String); + } =>#t185; } static method testForElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::int index, core::Map<core::String, core::int> mapStringInt, core::Map<core::String, core::double> mapStringDouble) → dynamic { core::List<core::int> list10 = block { - final core::List<core::int> #t158 = <core::int>[]; + final core::List<core::int> #t188 = <core::int>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t158.{core::List::add}(42); - } =>#t158; + #t188.{core::List::add}(42); + } =>#t188; core::Set<core::int> set10 = block { - final core::Set<core::int> #t159 = col::LinkedHashSet::•<core::int>(); + final core::Set<core::int> #t189 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t159.{core::Set::add}(42); - #t159.{core::Set::add}(null); - } =>#t159; - core::Map<core::String, core::int> map10 = block { - final core::Map<core::String, core::int> #t160 = <core::String, core::int>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t160.{core::Map::[]=}("bar", 42); - #t160.{core::Map::[]=}("baz", null); - } =>#t160; - core::List<dynamic> list11 = block { - final core::List<dynamic> #t161 = <dynamic>[]; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t161.{core::List::add}(dynVar); - } =>#t161; - core::Set<dynamic> set11 = block { - final core::Set<dynamic> #t162 = col::LinkedHashSet::•<dynamic>(); - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t162.{core::Set::add}(dynVar); - #t162.{core::Set::add}(null); - } =>#t162; - core::Map<core::String, dynamic> map11 = block { - final core::Map<core::String, dynamic> #t163 = <core::String, dynamic>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t163.{core::Map::[]=}("bar", dynVar); - #t163.{core::Map::[]=}("baz", null); - } =>#t163; - core::List<core::List<core::int>> list12 = block { - final core::List<core::List<core::int>> #t164 = <core::List<core::int>>[]; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t164.{core::List::add}(<core::int>[42]); - } =>#t164; - core::Set<core::List<core::int>> set12 = block { - final core::Set<core::List<core::int>> #t165 = col::LinkedHashSet::•<core::List<core::int>>(); - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t165.{core::Set::add}(<core::int>[42]); - #t165.{core::Set::add}(null); - } =>#t165; - core::Map<core::String, core::List<core::int>> map12 = block { - final core::Map<core::String, core::List<core::int>> #t166 = <core::String, core::List<core::int>>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t166.{core::Map::[]=}("bar", <core::int>[42]); - #t166.{core::Map::[]=}("baz", null); - } =>#t166; - core::List<core::int> list20 = block { - final core::List<core::int> #t167 = <core::int>[]; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::int #t168 in <core::int>[42]) - #t167.{core::List::add}(#t168); - } =>#t167; - core::Set<core::int> set20 = block { - final core::Set<core::int> #t169 = col::LinkedHashSet::•<core::int>(); - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::int #t170 in <core::int>[42]) - #t169.{core::Set::add}(#t170); - #t169.{core::Set::add}(null); - } =>#t169; - core::Map<core::String, core::int> map20 = block { - final core::Map<core::String, core::int> #t171 = <core::String, core::int>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::MapEntry<core::String, core::int> #t172 in <core::String, core::int>{"bar": 42}.{core::Map::entries}) - #t171.{core::Map::[]=}(#t172.{core::MapEntry::key}, #t172.{core::MapEntry::value}); - #t171.{core::Map::[]=}("baz", null); - } =>#t171; - core::List<dynamic> list21 = block { - final core::List<dynamic> #t173 = <dynamic>[]; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final dynamic #t174 in <dynamic>[dynVar]) - #t173.{core::List::add}(#t174); - } =>#t173; - core::Set<dynamic> set21 = block { - final core::Set<dynamic> #t175 = col::LinkedHashSet::•<dynamic>(); - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final dynamic #t176 in <dynamic>[dynVar]) - #t175.{core::Set::add}(#t176); - #t175.{core::Set::add}(null); - } =>#t175; - core::Map<core::String, dynamic> map21 = block { - final core::Map<core::String, dynamic> #t177 = <core::String, dynamic>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::MapEntry<core::String, dynamic> #t178 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries}) - #t177.{core::Map::[]=}(#t178.{core::MapEntry::key}, #t178.{core::MapEntry::value}); - #t177.{core::Map::[]=}("baz", null); - } =>#t177; - core::List<core::List<core::int>> list22 = block { - final core::List<core::List<core::int>> #t179 = <core::List<core::int>>[]; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::List<core::int> #t180 in <core::List<core::int>>[<core::int>[42]]) - #t179.{core::List::add}(#t180); - } =>#t179; - core::Set<core::List<core::int>> set22 = block { - final core::Set<core::List<core::int>> #t181 = col::LinkedHashSet::•<core::List<core::int>>(); - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::List<core::int> #t182 in <core::List<core::int>>[<core::int>[42]]) - #t181.{core::Set::add}(#t182); - #t181.{core::Set::add}(null); - } =>#t181; - core::Map<core::String, core::List<core::int>> map22 = block { - final core::Map<core::String, core::List<core::int>> #t183 = <core::String, core::List<core::int>>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::MapEntry<core::String, core::List<core::int>> #t184 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries}) - #t183.{core::Map::[]=}(#t184.{core::MapEntry::key}, #t184.{core::MapEntry::value}); - #t183.{core::Map::[]=}("baz", null); - } =>#t183; - core::List<core::int> list30 = block { - final core::List<core::int> #t185 = <core::int>[]; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::int #t186 in <core::int>[42]) - #t185.{core::List::add}(#t186); - } =>#t185; - core::Set<core::int> set30 = block { - final core::Set<core::int> #t187 = col::LinkedHashSet::•<core::int>(); - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::int #t188 in <core::int>[42]) - #t187.{core::Set::add}(#t188); - #t187.{core::Set::add}(null); - } =>#t187; - core::Map<core::String, core::int> map30 = block { - final core::Map<core::String, core::int> #t189 = <core::String, core::int>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::MapEntry<core::String, core::int> #t190 in <core::String, core::int>{"bar": 42}.{core::Map::entries}) - #t189.{core::Map::[]=}(#t190.{core::MapEntry::key}, #t190.{core::MapEntry::value}); - #t189.{core::Map::[]=}("baz", null); + #t189.{core::Set::add}(42); + #t189.{core::Set::add}(null); } =>#t189; - core::List<dynamic> list31 = block { + core::Map<core::String, core::int> map10 = block { + final core::Map<core::String, core::int> #t190 = <core::String, core::int>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t190.{core::Map::[]=}("bar", 42); + #t190.{core::Map::[]=}("baz", null); + } =>#t190; + core::List<dynamic> list11 = block { final core::List<dynamic> #t191 = <dynamic>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final dynamic #t192 in <dynamic>[dynVar]) - #t191.{core::List::add}(#t192); + #t191.{core::List::add}(dynVar); } =>#t191; - core::Set<dynamic> set31 = block { - final core::Set<dynamic> #t193 = col::LinkedHashSet::•<dynamic>(); + core::Set<dynamic> set11 = block { + final core::Set<dynamic> #t192 = col::LinkedHashSet::•<dynamic>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final dynamic #t194 in <dynamic>[dynVar]) - #t193.{core::Set::add}(#t194); - #t193.{core::Set::add}(null); + #t192.{core::Set::add}(dynVar); + #t192.{core::Set::add}(null); + } =>#t192; + core::Map<core::String, dynamic> map11 = block { + final core::Map<core::String, dynamic> #t193 = <core::String, dynamic>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t193.{core::Map::[]=}("bar", dynVar); + #t193.{core::Map::[]=}("baz", null); } =>#t193; - core::Map<core::String, dynamic> map31 = block { - final core::Map<core::String, dynamic> #t195 = <core::String, dynamic>{}; + core::List<core::List<core::int>> list12 = block { + final core::List<core::List<core::int>> #t194 = <core::List<core::int>>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::MapEntry<core::String, dynamic> #t196 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries}) - #t195.{core::Map::[]=}(#t196.{core::MapEntry::key}, #t196.{core::MapEntry::value}); - #t195.{core::Map::[]=}("baz", null); + #t194.{core::List::add}(<core::int>[42]); + } =>#t194; + core::Set<core::List<core::int>> set12 = block { + final core::Set<core::List<core::int>> #t195 = col::LinkedHashSet::•<core::List<core::int>>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t195.{core::Set::add}(<core::int>[42]); + #t195.{core::Set::add}(null); } =>#t195; - core::List<core::List<core::int>> list33 = block { - final core::List<core::List<core::int>> #t197 = <core::List<core::int>>[]; + core::Map<core::String, core::List<core::int>> map12 = block { + final core::Map<core::String, core::List<core::int>> #t196 = <core::String, core::List<core::int>>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::List<core::int> #t198 in <core::List<core::int>>[<core::int>[42]]) - #t197.{core::List::add}(#t198); + #t196.{core::Map::[]=}("bar", <core::int>[42]); + #t196.{core::Map::[]=}("baz", null); + } =>#t196; + core::List<core::int> list20 = block { + final core::List<core::int> #t197 = <core::int>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + for (final core::int #t198 in <core::int>[42]) + #t197.{core::List::add}(#t198); } =>#t197; - core::Set<core::List<core::int>> set33 = block { - final core::Set<core::List<core::int>> #t199 = col::LinkedHashSet::•<core::List<core::int>>(); + core::Set<core::int> set20 = block { + final core::Set<core::int> #t199 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::List<core::int> #t200 in <core::List<core::int>>[<core::int>[42]]) - #t199.{core::Set::add}(#t200); + for (final core::int #t200 in <core::int>[42]) + #t199.{core::Set::add}(#t200); #t199.{core::Set::add}(null); } =>#t199; - core::Map<core::String, core::List<core::int>> map33 = block { - final core::Map<core::String, core::List<core::int>> #t201 = <core::String, core::List<core::int>>{}; + core::Map<core::String, core::int> map20 = block { + final core::Map<core::String, core::int> #t201 = <core::String, core::int>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::MapEntry<core::String, core::List<core::int>> #t202 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries}) - #t201.{core::Map::[]=}(#t202.{core::MapEntry::key}, #t202.{core::MapEntry::value}); + for (final core::MapEntry<core::String, core::int> #t202 in <core::String, core::int>{"bar": 42}.{core::Map::entries}) + #t201.{core::Map::[]=}(#t202.{core::MapEntry::key}, #t202.{core::MapEntry::value}); #t201.{core::Map::[]=}("baz", null); } =>#t201; - core::List<core::List<core::int>> list40 = block { - final core::List<core::List<core::int>> #t203 = <core::List<core::int>>[]; + core::List<dynamic> list21 = block { + final core::List<dynamic> #t203 = <dynamic>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::List<core::int> #t204 in <core::List<core::int>>[<core::int>[]]) + for (final dynamic #t204 in <dynamic>[dynVar]) #t203.{core::List::add}(#t204); } =>#t203; - core::Set<core::List<core::int>> set40 = block { - final core::Set<core::List<core::int>> #t205 = col::LinkedHashSet::•<core::List<core::int>>(); + core::Set<dynamic> set21 = block { + final core::Set<dynamic> #t205 = col::LinkedHashSet::•<dynamic>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::List<core::int> #t206 in <core::List<core::int>>[<core::int>[]]) + for (final dynamic #t206 in <dynamic>[dynVar]) #t205.{core::Set::add}(#t206); #t205.{core::Set::add}(null); } =>#t205; - core::Map<core::String, core::List<core::int>> map40 = block { - final core::Map<core::String, core::List<core::int>> #t207 = <core::String, core::List<core::int>>{}; + core::Map<core::String, dynamic> map21 = block { + final core::Map<core::String, dynamic> #t207 = <core::String, dynamic>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::MapEntry<core::String, core::List<core::int>> #t208 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) + for (final core::MapEntry<core::String, dynamic> #t208 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries}) #t207.{core::Map::[]=}(#t208.{core::MapEntry::key}, #t208.{core::MapEntry::value}); #t207.{core::Map::[]=}("baz", null); } =>#t207; - core::List<core::List<core::int>> list41 = block { + core::List<core::List<core::int>> list22 = block { final core::List<core::List<core::int>> #t209 = <core::List<core::int>>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::List<core::int> #t210 in let final core::Set<core::List<core::int>> #t211 = col::LinkedHashSet::•<core::List<core::int>>() in let final dynamic #t212 = #t211.{core::Set::add}(<core::int>[]) in #t211) + for (final core::List<core::int> #t210 in <core::List<core::int>>[<core::int>[42]]) #t209.{core::List::add}(#t210); } =>#t209; - core::Set<core::List<core::int>> set41 = block { - final core::Set<core::List<core::int>> #t213 = col::LinkedHashSet::•<core::List<core::int>>(); + core::Set<core::List<core::int>> set22 = block { + final core::Set<core::List<core::int>> #t211 = col::LinkedHashSet::•<core::List<core::int>>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::List<core::int> #t214 in let final core::Set<core::List<core::int>> #t215 = col::LinkedHashSet::•<core::List<core::int>>() in let final dynamic #t216 = #t215.{core::Set::add}(<core::int>[]) in #t215) - #t213.{core::Set::add}(#t214); - #t213.{core::Set::add}(null); + for (final core::List<core::int> #t212 in <core::List<core::int>>[<core::int>[42]]) + #t211.{core::Set::add}(#t212); + #t211.{core::Set::add}(null); + } =>#t211; + core::Map<core::String, core::List<core::int>> map22 = block { + final core::Map<core::String, core::List<core::int>> #t213 = <core::String, core::List<core::int>>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + for (final core::MapEntry<core::String, core::List<core::int>> #t214 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries}) + #t213.{core::Map::[]=}(#t214.{core::MapEntry::key}, #t214.{core::MapEntry::value}); + #t213.{core::Map::[]=}("baz", null); } =>#t213; - core::List<core::List<core::int>> list42 = block { - final core::List<core::List<core::int>> #t217 = <core::List<core::int>>[]; + core::List<core::int> list30 = block { + final core::List<core::int> #t215 = <core::int>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::List<core::int> #t218 in <core::List<core::int>>[<core::int>[]]) - #t217.{core::List::add}(#t218); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::int #t216 in <core::int>[42]) + #t215.{core::List::add}(#t216); + } =>#t215; + core::Set<core::int> set30 = block { + final core::Set<core::int> #t217 = col::LinkedHashSet::•<core::int>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::int #t218 in <core::int>[42]) + #t217.{core::Set::add}(#t218); + #t217.{core::Set::add}(null); } =>#t217; - core::Set<core::List<core::int>> set42 = block { - final core::Set<core::List<core::int>> #t219 = col::LinkedHashSet::•<core::List<core::int>>(); + core::Map<core::String, core::int> map30 = block { + final core::Map<core::String, core::int> #t219 = <core::String, core::int>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::List<core::int> #t220 in <core::List<core::int>>[<core::int>[]]) - #t219.{core::Set::add}(#t220); - #t219.{core::Set::add}(null); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::MapEntry<core::String, core::int> #t220 in <core::String, core::int>{"bar": 42}.{core::Map::entries}) + #t219.{core::Map::[]=}(#t220.{core::MapEntry::key}, #t220.{core::MapEntry::value}); + #t219.{core::Map::[]=}("baz", null); } =>#t219; - core::Map<core::String, core::List<core::int>> map42 = block { - final core::Map<core::String, core::List<core::int>> #t221 = <core::String, core::List<core::int>>{}; + core::List<dynamic> list31 = block { + final core::List<dynamic> #t221 = <dynamic>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::MapEntry<core::String, core::List<core::int>> #t222 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) - #t221.{core::Map::[]=}(#t222.{core::MapEntry::key}, #t222.{core::MapEntry::value}); - #t221.{core::Map::[]=}("baz", null); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final dynamic #t222 in <dynamic>[dynVar]) + #t221.{core::List::add}(#t222); } =>#t221; - core::List<core::int> list50 = block { - final core::List<core::int> #t223 = <core::int>[]; + core::Set<dynamic> set31 = block { + final core::Set<dynamic> #t223 = col::LinkedHashSet::•<dynamic>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::int #t224 in <core::int>[]) - #t223.{core::List::add}(#t224); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final dynamic #t224 in <dynamic>[dynVar]) + #t223.{core::Set::add}(#t224); + #t223.{core::Set::add}(null); } =>#t223; - core::Set<core::int> set50 = block { - final core::Set<core::int> #t225 = col::LinkedHashSet::•<core::int>(); + core::Map<core::String, dynamic> map31 = block { + final core::Map<core::String, dynamic> #t225 = <core::String, dynamic>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::int #t226 in <core::int>[]) - #t225.{core::Set::add}(#t226); - #t225.{core::Set::add}(null); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::MapEntry<core::String, dynamic> #t226 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries}) + #t225.{core::Map::[]=}(#t226.{core::MapEntry::key}, #t226.{core::MapEntry::value}); + #t225.{core::Map::[]=}("baz", null); } =>#t225; - core::Map<core::String, core::int> map50 = block { - final core::Map<core::String, core::int> #t227 = <core::String, core::int>{}; + core::List<core::List<core::int>> list33 = block { + final core::List<core::List<core::int>> #t227 = <core::List<core::int>>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::MapEntry<core::String, core::int> #t228 in <core::String, core::int>{}.{core::Map::entries}) - #t227.{core::Map::[]=}(#t228.{core::MapEntry::key}, #t228.{core::MapEntry::value}); - #t227.{core::Map::[]=}("baz", null); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::List<core::int> #t228 in <core::List<core::int>>[<core::int>[42]]) + #t227.{core::List::add}(#t228); } =>#t227; - core::List<core::int> list51 = block { - final core::List<core::int> #t229 = <core::int>[]; + core::Set<core::List<core::int>> set33 = block { + final core::Set<core::List<core::int>> #t229 = col::LinkedHashSet::•<core::List<core::int>>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::int #t230 in let final core::Set<core::int> #t231 = col::LinkedHashSet::•<core::int>() in #t231) - #t229.{core::List::add}(#t230); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::List<core::int> #t230 in <core::List<core::int>>[<core::int>[42]]) + #t229.{core::Set::add}(#t230); + #t229.{core::Set::add}(null); } =>#t229; - core::Set<core::int> set51 = block { - final core::Set<core::int> #t232 = col::LinkedHashSet::•<core::int>(); + core::Map<core::String, core::List<core::int>> map33 = block { + final core::Map<core::String, core::List<core::int>> #t231 = <core::String, core::List<core::int>>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::int #t233 in let final core::Set<core::int> #t234 = col::LinkedHashSet::•<core::int>() in #t234) - #t232.{core::Set::add}(#t233); - #t232.{core::Set::add}(null); - } =>#t232; - core::List<core::int> list52 = block { - final core::List<core::int> #t235 = <core::int>[]; + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::MapEntry<core::String, core::List<core::int>> #t232 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries}) + #t231.{core::Map::[]=}(#t232.{core::MapEntry::key}, #t232.{core::MapEntry::value}); + #t231.{core::Map::[]=}("baz", null); + } =>#t231; + core::List<core::List<core::int>> list40 = block { + final core::List<core::List<core::int>> #t233 = <core::List<core::int>>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::int #t236 in <core::int>[]) - #t235.{core::List::add}(#t236); + for (final core::List<core::int> #t234 in <core::List<core::int>>[<core::int>[]]) + #t233.{core::List::add}(#t234); + } =>#t233; + core::Set<core::List<core::int>> set40 = block { + final core::Set<core::List<core::int>> #t235 = col::LinkedHashSet::•<core::List<core::int>>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + for (final core::List<core::int> #t236 in <core::List<core::int>>[<core::int>[]]) + #t235.{core::Set::add}(#t236); + #t235.{core::Set::add}(null); } =>#t235; - core::Set<core::int> set52 = block { - final core::Set<core::int> #t237 = col::LinkedHashSet::•<core::int>(); + core::Map<core::String, core::List<core::int>> map40 = block { + final core::Map<core::String, core::List<core::int>> #t237 = <core::String, core::List<core::int>>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::int #t238 in <core::int>[]) - #t237.{core::Set::add}(#t238); - #t237.{core::Set::add}(null); + for (final core::MapEntry<core::String, core::List<core::int>> #t238 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) + #t237.{core::Map::[]=}(#t238.{core::MapEntry::key}, #t238.{core::MapEntry::value}); + #t237.{core::Map::[]=}("baz", null); } =>#t237; - core::List<core::List<core::int>> list60 = block { + core::List<core::List<core::int>> list41 = block { final core::List<core::List<core::int>> #t239 = <core::List<core::int>>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::List<core::int> #t240 in <core::List<core::int>>[<core::int>[]]) + for (final core::List<core::int> #t240 in let final core::Set<core::List<core::int>> #t241 = col::LinkedHashSet::•<core::List<core::int>>() in let final dynamic #t242 = #t241.{core::Set::add}(<core::int>[]) in #t241) #t239.{core::List::add}(#t240); } =>#t239; - core::Set<core::List<core::int>> set60 = block { - final core::Set<core::List<core::int>> #t241 = col::LinkedHashSet::•<core::List<core::int>>(); + core::Set<core::List<core::int>> set41 = block { + final core::Set<core::List<core::int>> #t243 = col::LinkedHashSet::•<core::List<core::int>>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::List<core::int> #t242 in <core::List<core::int>>[<core::int>[]]) - #t241.{core::Set::add}(#t242); - #t241.{core::Set::add}(null); - } =>#t241; - core::Map<core::String, core::List<core::int>> map60 = block { - final core::Map<core::String, core::List<core::int>> #t243 = <core::String, core::List<core::int>>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::MapEntry<core::String, core::List<core::int>> #t244 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) - #t243.{core::Map::[]=}(#t244.{core::MapEntry::key}, #t244.{core::MapEntry::value}); - #t243.{core::Map::[]=}("baz", null); + for (final core::List<core::int> #t244 in let final core::Set<core::List<core::int>> #t245 = col::LinkedHashSet::•<core::List<core::int>>() in let final dynamic #t246 = #t245.{core::Set::add}(<core::int>[]) in #t245) + #t243.{core::Set::add}(#t244); + #t243.{core::Set::add}(null); } =>#t243; - core::List<core::List<core::int>> list61 = block { - final core::List<core::List<core::int>> #t245 = <core::List<core::int>>[]; + core::List<core::List<core::int>> list42 = block { + final core::List<core::List<core::int>> #t247 = <core::List<core::int>>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::List<core::int> #t246 in <core::List<core::int>>[<core::int>[]]) - #t245.{core::List::add}(#t246); - } =>#t245; - core::Set<core::List<core::int>> set61 = block { - final core::Set<core::List<core::int>> #t247 = col::LinkedHashSet::•<core::List<core::int>>(); - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::List<core::int> #t248 in <core::List<core::int>>[<core::int>[]]) - #t247.{core::Set::add}(#t248); - #t247.{core::Set::add}(null); + #t247.{core::List::add}(#t248); } =>#t247; - core::Map<core::String, core::List<core::int>> map61 = block { - final core::Map<core::String, core::List<core::int>> #t249 = <core::String, core::List<core::int>>{}; + core::Set<core::List<core::int>> set42 = block { + final core::Set<core::List<core::int>> #t249 = col::LinkedHashSet::•<core::List<core::int>>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::MapEntry<core::String, core::List<core::int>> #t250 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) - #t249.{core::Map::[]=}(#t250.{core::MapEntry::key}, #t250.{core::MapEntry::value}); - #t249.{core::Map::[]=}("baz", null); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::List<core::int> #t250 in <core::List<core::int>>[<core::int>[]]) + #t249.{core::Set::add}(#t250); + #t249.{core::Set::add}(null); } =>#t249; - core::List<core::List<core::int>> list70 = block { - final core::List<core::List<core::int>> #t251 = <core::List<core::int>>[]; + core::Map<core::String, core::List<core::int>> map42 = block { + final core::Map<core::String, core::List<core::int>> #t251 = <core::String, core::List<core::int>>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t251.{core::List::add}(<core::int>[]); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::MapEntry<core::String, core::List<core::int>> #t252 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) + #t251.{core::Map::[]=}(#t252.{core::MapEntry::key}, #t252.{core::MapEntry::value}); + #t251.{core::Map::[]=}("baz", null); } =>#t251; - core::Set<core::List<core::int>> set70 = block { - final core::Set<core::List<core::int>> #t252 = col::LinkedHashSet::•<core::List<core::int>>(); + core::List<core::int> list50 = block { + final core::List<core::int> #t253 = <core::int>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t252.{core::Set::add}(<core::int>[]); - #t252.{core::Set::add}(null); - } =>#t252; - core::Map<core::String, core::List<core::int>> map70 = block { - final core::Map<core::String, core::List<core::int>> #t253 = <core::String, core::List<core::int>>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t253.{core::Map::[]=}("bar", <core::int>[]); - #t253.{core::Map::[]=}("baz", null); + for (final core::int #t254 in <core::int>[]) + #t253.{core::List::add}(#t254); } =>#t253; - core::List<core::List<core::int>> list71 = block { - final core::List<core::List<core::int>> #t254 = <core::List<core::int>>[]; + core::Set<core::int> set50 = block { + final core::Set<core::int> #t255 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t254.{core::List::add}(<core::int>[]); - } =>#t254; - core::Set<core::List<core::int>> set71 = block { - final core::Set<core::List<core::int>> #t255 = col::LinkedHashSet::•<core::List<core::int>>(); - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t255.{core::Set::add}(<core::int>[]); + for (final core::int #t256 in <core::int>[]) + #t255.{core::Set::add}(#t256); #t255.{core::Set::add}(null); } =>#t255; - core::Map<core::String, core::List<core::int>> map71 = block { - final core::Map<core::String, core::List<core::int>> #t256 = <core::String, core::List<core::int>>{}; + core::Map<core::String, core::int> map50 = block { + final core::Map<core::String, core::int> #t257 = <core::String, core::int>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t256.{core::Map::[]=}("bar", <core::int>[]); - #t256.{core::Map::[]=}("baz", null); - } =>#t256; - core::List<core::num> list80 = block { - final core::List<core::num> #t257 = <core::num>[]; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t257.{core::List::add}(42); - else - #t257.{core::List::add}(3.14); + for (final core::MapEntry<core::String, core::int> #t258 in <core::String, core::int>{}.{core::Map::entries}) + #t257.{core::Map::[]=}(#t258.{core::MapEntry::key}, #t258.{core::MapEntry::value}); + #t257.{core::Map::[]=}("baz", null); } =>#t257; - core::Set<core::num> set80 = block { - final core::Set<core::num> #t258 = col::LinkedHashSet::•<core::num>(); + core::List<core::int> list51 = block { + final core::List<core::int> #t259 = <core::int>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t258.{core::Set::add}(42); - else - #t258.{core::Set::add}(3.14); - #t258.{core::Set::add}(null); - } =>#t258; - core::Map<core::String, core::num> map80 = block { - final core::Map<core::String, core::num> #t259 = <core::String, core::num>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t259.{core::Map::[]=}("bar", 42); - else - #t259.{core::Map::[]=}("bar", 3.14); - #t259.{core::Map::[]=}("baz", null); + for (final core::int #t260 in let final core::Set<core::int> #t261 = col::LinkedHashSet::•<core::int>() in #t261) + #t259.{core::List::add}(#t260); } =>#t259; - core::List<core::num> list81 = block { - final core::List<core::num> #t260 = <core::num>[]; + core::Set<core::int> set51 = block { + final core::Set<core::int> #t262 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::num #t261 in listInt) - #t260.{core::List::add}(#t261); - else - for (final core::num #t262 in listDouble) - #t260.{core::List::add}(#t262); - } =>#t260; - core::Set<core::num> set81 = block { - final core::Set<core::num> #t263 = col::LinkedHashSet::•<core::num>(); + for (final core::int #t263 in let final core::Set<core::int> #t264 = col::LinkedHashSet::•<core::int>() in #t264) + #t262.{core::Set::add}(#t263); + #t262.{core::Set::add}(null); + } =>#t262; + core::List<core::int> list52 = block { + final core::List<core::int> #t265 = <core::int>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::num #t264 in listInt) - #t263.{core::Set::add}(#t264); - else - for (final core::num #t265 in listDouble) - #t263.{core::Set::add}(#t265); - #t263.{core::Set::add}(null); - } =>#t263; - core::Map<core::String, core::num> map81 = block { - final core::Map<core::String, core::num> #t266 = <core::String, core::num>{}; + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::int #t266 in <core::int>[]) + #t265.{core::List::add}(#t266); + } =>#t265; + core::Set<core::int> set52 = block { + final core::Set<core::int> #t267 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::MapEntry<core::String, core::num> #t267 in mapStringInt.{core::Map::entries}) - #t266.{core::Map::[]=}(#t267.{core::MapEntry::key}, #t267.{core::MapEntry::value}); - else - for (final core::MapEntry<core::String, core::num> #t268 in mapStringDouble.{core::Map::entries}) - #t266.{core::Map::[]=}(#t268.{core::MapEntry::key}, #t268.{core::MapEntry::value}); - #t266.{core::Map::[]=}("baz", null); - } =>#t266; - core::List<dynamic> list82 = block { - final core::List<dynamic> #t269 = <dynamic>[]; + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::int #t268 in <core::int>[]) + #t267.{core::Set::add}(#t268); + #t267.{core::Set::add}(null); + } =>#t267; + core::List<core::List<core::int>> list60 = block { + final core::List<core::List<core::int>> #t269 = <core::List<core::int>>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final dynamic #t270 in listInt) - #t269.{core::List::add}(#t270); - else - for (final dynamic #t271 in dynVar as{TypeError} core::Iterable<dynamic>) - #t269.{core::List::add}(#t271); + for (final core::List<core::int> #t270 in <core::List<core::int>>[<core::int>[]]) + #t269.{core::List::add}(#t270); } =>#t269; - core::Set<dynamic> set82 = block { - final core::Set<dynamic> #t272 = col::LinkedHashSet::•<dynamic>(); + core::Set<core::List<core::int>> set60 = block { + final core::Set<core::List<core::int>> #t271 = col::LinkedHashSet::•<core::List<core::int>>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final dynamic #t273 in listInt) - #t272.{core::Set::add}(#t273); - else - for (final dynamic #t274 in dynVar as{TypeError} core::Iterable<dynamic>) - #t272.{core::Set::add}(#t274); - #t272.{core::Set::add}(null); - } =>#t272; - core::Map<dynamic, dynamic> map82 = block { - final core::Map<dynamic, dynamic> #t275 = <dynamic, dynamic>{}; + for (final core::List<core::int> #t272 in <core::List<core::int>>[<core::int>[]]) + #t271.{core::Set::add}(#t272); + #t271.{core::Set::add}(null); + } =>#t271; + core::Map<core::String, core::List<core::int>> map60 = block { + final core::Map<core::String, core::List<core::int>> #t273 = <core::String, core::List<core::int>>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::MapEntry<dynamic, dynamic> #t276 in mapStringInt.{core::Map::entries}) - #t275.{core::Map::[]=}(#t276.{core::MapEntry::key}, #t276.{core::MapEntry::value}); - else - for (final core::MapEntry<dynamic, dynamic> #t277 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) - #t275.{core::Map::[]=}(#t277.{core::MapEntry::key}, #t277.{core::MapEntry::value}); - #t275.{core::Map::[]=}("baz", null); + for (final core::MapEntry<core::String, core::List<core::int>> #t274 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) + #t273.{core::Map::[]=}(#t274.{core::MapEntry::key}, #t274.{core::MapEntry::value}); + #t273.{core::Map::[]=}("baz", null); + } =>#t273; + core::List<core::List<core::int>> list61 = block { + final core::List<core::List<core::int>> #t275 = <core::List<core::int>>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::List<core::int> #t276 in <core::List<core::int>>[<core::int>[]]) + #t275.{core::List::add}(#t276); } =>#t275; - core::List<core::num> list83 = block { - final core::List<core::num> #t278 = <core::num>[]; + core::Set<core::List<core::int>> set61 = block { + final core::Set<core::List<core::int>> #t277 = col::LinkedHashSet::•<core::List<core::int>>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t278.{core::List::add}(42); - else - for (final core::num #t279 in listDouble) - #t278.{core::List::add}(#t279); - } =>#t278; - core::Set<core::num> set83 = block { - final core::Set<core::num> #t280 = col::LinkedHashSet::•<core::num>(); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::List<core::int> #t278 in <core::List<core::int>>[<core::int>[]]) + #t277.{core::Set::add}(#t278); + #t277.{core::Set::add}(null); + } =>#t277; + core::Map<core::String, core::List<core::int>> map61 = block { + final core::Map<core::String, core::List<core::int>> #t279 = <core::String, core::List<core::int>>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::num #t281 in listInt) - #t280.{core::Set::add}(#t281); - else - #t280.{core::Set::add}(3.14); - #t280.{core::Set::add}(null); - } =>#t280; - core::Map<core::String, core::num> map83 = block { - final core::Map<core::String, core::num> #t282 = <core::String, core::num>{}; + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::MapEntry<core::String, core::List<core::int>> #t280 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) + #t279.{core::Map::[]=}(#t280.{core::MapEntry::key}, #t280.{core::MapEntry::value}); + #t279.{core::Map::[]=}("baz", null); + } =>#t279; + core::List<core::List<core::int>> list70 = block { + final core::List<core::List<core::int>> #t281 = <core::List<core::int>>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::MapEntry<core::String, core::num> #t283 in mapStringInt.{core::Map::entries}) - #t282.{core::Map::[]=}(#t283.{core::MapEntry::key}, #t283.{core::MapEntry::value}); - else - #t282.{core::Map::[]=}("bar", 3.14); - #t282.{core::Map::[]=}("baz", null); + #t281.{core::List::add}(<core::int>[]); + } =>#t281; + core::Set<core::List<core::int>> set70 = block { + final core::Set<core::List<core::int>> #t282 = col::LinkedHashSet::•<core::List<core::int>>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t282.{core::Set::add}(<core::int>[]); + #t282.{core::Set::add}(null); } =>#t282; - core::List<core::int> list90 = block { - final core::List<core::int> #t284 = <core::int>[]; + core::Map<core::String, core::List<core::int>> map70 = block { + final core::Map<core::String, core::List<core::int>> #t283 = <core::String, core::List<core::int>>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t284.{core::List::add}(dynVar as{TypeError} core::int); + #t283.{core::Map::[]=}("bar", <core::int>[]); + #t283.{core::Map::[]=}("baz", null); + } =>#t283; + core::List<core::List<core::int>> list71 = block { + final core::List<core::List<core::int>> #t284 = <core::List<core::int>>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t284.{core::List::add}(<core::int>[]); } =>#t284; - core::Set<core::int> set90 = block { - final core::Set<core::int> #t285 = col::LinkedHashSet::•<core::int>(); + core::Set<core::List<core::int>> set71 = block { + final core::Set<core::List<core::int>> #t285 = col::LinkedHashSet::•<core::List<core::int>>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t285.{core::Set::add}(dynVar as{TypeError} core::int); + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t285.{core::Set::add}(<core::int>[]); #t285.{core::Set::add}(null); } =>#t285; - core::Map<core::String, core::int> map90 = block { - final core::Map<core::String, core::int> #t286 = <core::String, core::int>{}; + core::Map<core::String, core::List<core::int>> map71 = block { + final core::Map<core::String, core::List<core::int>> #t286 = <core::String, core::List<core::int>>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t286.{core::Map::[]=}("bar", dynVar as{TypeError} core::int); + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t286.{core::Map::[]=}("bar", <core::int>[]); #t286.{core::Map::[]=}("baz", null); } =>#t286; - core::List<core::int> list91 = block { - final core::List<core::int> #t287 = <core::int>[]; + core::List<core::num> list80 = block { + final core::List<core::num> #t287 = <core::num>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final dynamic #t288 in dynVar as{TypeError} core::Iterable<dynamic>) { - final core::int #t289 = #t288 as{TypeError} core::int; - #t287.{core::List::add}(#t289); - } + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t287.{core::List::add}(42); + else + #t287.{core::List::add}(3.14); } =>#t287; - core::Set<core::int> set91 = block { - final core::Set<core::int> #t290 = col::LinkedHashSet::•<core::int>(); + core::Set<core::num> set80 = block { + final core::Set<core::num> #t288 = col::LinkedHashSet::•<core::num>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final dynamic #t291 in dynVar as{TypeError} core::Iterable<dynamic>) { - final core::int #t292 = #t291 as{TypeError} core::int; - #t290.{core::Set::add}(#t292); - } - #t290.{core::Set::add}(null); + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t288.{core::Set::add}(42); + else + #t288.{core::Set::add}(3.14); + #t288.{core::Set::add}(null); + } =>#t288; + core::Map<core::String, core::num> map80 = block { + final core::Map<core::String, core::num> #t289 = <core::String, core::num>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t289.{core::Map::[]=}("bar", 42); + else + #t289.{core::Map::[]=}("bar", 3.14); + #t289.{core::Map::[]=}("baz", null); + } =>#t289; + core::List<core::num> list81 = block { + final core::List<core::num> #t290 = <core::num>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::num #t291 in listInt) + #t290.{core::List::add}(#t291); + else + for (final core::num #t292 in listDouble) + #t290.{core::List::add}(#t292); } =>#t290; - core::Map<core::String, core::int> map91 = block { - final core::Map<core::String, core::int> #t293 = <core::String, core::int>{}; + core::Set<core::num> set81 = block { + final core::Set<core::num> #t293 = col::LinkedHashSet::•<core::num>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::MapEntry<dynamic, dynamic> #t294 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) { - final core::String #t295 = #t294.{core::MapEntry::key} as{TypeError} core::String; - final core::int #t296 = #t294.{core::MapEntry::value} as{TypeError} core::int; - #t293.{core::Map::[]=}(#t295, #t296); - } - #t293.{core::Map::[]=}("baz", null); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::num #t294 in listInt) + #t293.{core::Set::add}(#t294); + else + for (final core::num #t295 in listDouble) + #t293.{core::Set::add}(#t295); + #t293.{core::Set::add}(null); } =>#t293; - core::List<core::int> list100 = block { - final core::List<core::int> #t297 = <core::int>[]; - for (final dynamic #t298 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1)) - #t297.{core::List::add}(42); - } =>#t297; - core::Set<core::int> set100 = block { - final core::Set<core::int> #t299 = col::LinkedHashSet::•<core::int>(); - for (final dynamic #t300 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1)) - #t299.{core::Set::add}(42); + core::Map<core::String, core::num> map81 = block { + final core::Map<core::String, core::num> #t296 = <core::String, core::num>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::MapEntry<core::String, core::num> #t297 in mapStringInt.{core::Map::entries}) + #t296.{core::Map::[]=}(#t297.{core::MapEntry::key}, #t297.{core::MapEntry::value}); + else + for (final core::MapEntry<core::String, core::num> #t298 in mapStringDouble.{core::Map::entries}) + #t296.{core::Map::[]=}(#t298.{core::MapEntry::key}, #t298.{core::MapEntry::value}); + #t296.{core::Map::[]=}("baz", null); + } =>#t296; + core::List<dynamic> list82 = block { + final core::List<dynamic> #t299 = <dynamic>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final dynamic #t300 in listInt) + #t299.{core::List::add}(#t300); + else + for (final dynamic #t301 in dynVar as{TypeError} core::Iterable<dynamic>) + #t299.{core::List::add}(#t301); } =>#t299; - core::Map<core::String, core::int> map100 = block { - final core::Map<core::String, core::int> #t301 = <core::String, core::int>{}; - for (final dynamic #t302 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1)) - #t301.{core::Map::[]=}("bar", 42); - } =>#t301; - core::List<core::int> list110 = block { - final core::List<core::int> #t303 = <core::int>[]; - for (core::int i in <core::int>[1, 2, 3]) - #t303.{core::List::add}(i); - } =>#t303; - core::Set<core::int> set110 = block { - final core::Set<core::int> #t304 = col::LinkedHashSet::•<core::int>(); - for (core::int i in <core::int>[1, 2, 3]) - #t304.{core::Set::add}(i); - #t304.{core::Set::add}(null); - } =>#t304; - core::Map<core::String, core::int> map110 = block { - final core::Map<core::String, core::int> #t305 = <core::String, core::int>{}; - for (core::int i in <core::int>[1, 2, 3]) - #t305.{core::Map::[]=}("bar", i); + core::Set<dynamic> set82 = block { + final core::Set<dynamic> #t302 = col::LinkedHashSet::•<dynamic>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final dynamic #t303 in listInt) + #t302.{core::Set::add}(#t303); + else + for (final dynamic #t304 in dynVar as{TypeError} core::Iterable<dynamic>) + #t302.{core::Set::add}(#t304); + #t302.{core::Set::add}(null); + } =>#t302; + core::Map<dynamic, dynamic> map82 = block { + final core::Map<dynamic, dynamic> #t305 = <dynamic, dynamic>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::MapEntry<dynamic, dynamic> #t306 in mapStringInt.{core::Map::entries}) + #t305.{core::Map::[]=}(#t306.{core::MapEntry::key}, #t306.{core::MapEntry::value}); + else + for (final core::MapEntry<dynamic, dynamic> #t307 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) + #t305.{core::Map::[]=}(#t307.{core::MapEntry::key}, #t307.{core::MapEntry::value}); #t305.{core::Map::[]=}("baz", null); } =>#t305; - core::List<core::int> list120 = block { - final core::List<core::int> #t306 = <core::int>[]; - for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>) - #t306.{core::List::add}(i as{TypeError} core::int); - } =>#t306; - core::Set<core::int> set120 = block { - final core::Set<core::int> #t307 = col::LinkedHashSet::•<core::int>(); - for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>) - #t307.{core::Set::add}(i as{TypeError} core::int); - #t307.{core::Set::add}(null); - } =>#t307; - core::Map<core::String, core::int> map120 = block { - final core::Map<core::String, core::int> #t308 = <core::String, core::int>{}; - for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>) - #t308.{core::Map::[]=}("bar", i as{TypeError} core::int); - #t308.{core::Map::[]=}("baz", null); + core::List<core::num> list83 = block { + final core::List<core::num> #t308 = <core::num>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t308.{core::List::add}(42); + else + for (final core::num #t309 in listDouble) + #t308.{core::List::add}(#t309); } =>#t308; + core::Set<core::num> set83 = block { + final core::Set<core::num> #t310 = col::LinkedHashSet::•<core::num>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::num #t311 in listInt) + #t310.{core::Set::add}(#t311); + else + #t310.{core::Set::add}(3.14); + #t310.{core::Set::add}(null); + } =>#t310; + core::Map<core::String, core::num> map83 = block { + final core::Map<core::String, core::num> #t312 = <core::String, core::num>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::MapEntry<core::String, core::num> #t313 in mapStringInt.{core::Map::entries}) + #t312.{core::Map::[]=}(#t313.{core::MapEntry::key}, #t313.{core::MapEntry::value}); + else + #t312.{core::Map::[]=}("bar", 3.14); + #t312.{core::Map::[]=}("baz", null); + } =>#t312; + core::List<core::int> list90 = block { + final core::List<core::int> #t314 = <core::int>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t314.{core::List::add}(dynVar as{TypeError} core::int); + } =>#t314; + core::Set<core::int> set90 = block { + final core::Set<core::int> #t315 = col::LinkedHashSet::•<core::int>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t315.{core::Set::add}(dynVar as{TypeError} core::int); + #t315.{core::Set::add}(null); + } =>#t315; + core::Map<core::String, core::int> map90 = block { + final core::Map<core::String, core::int> #t316 = <core::String, core::int>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t316.{core::Map::[]=}("bar", dynVar as{TypeError} core::int); + #t316.{core::Map::[]=}("baz", null); + } =>#t316; + core::List<core::int> list91 = block { + final core::List<core::int> #t317 = <core::int>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + for (final dynamic #t318 in dynVar as{TypeError} core::Iterable<dynamic>) { + final core::int #t319 = #t318 as{TypeError} core::int; + #t317.{core::List::add}(#t319); + } + } =>#t317; + core::Set<core::int> set91 = block { + final core::Set<core::int> #t320 = col::LinkedHashSet::•<core::int>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + for (final dynamic #t321 in dynVar as{TypeError} core::Iterable<dynamic>) { + final core::int #t322 = #t321 as{TypeError} core::int; + #t320.{core::Set::add}(#t322); + } + #t320.{core::Set::add}(null); + } =>#t320; + core::Map<core::String, core::int> map91 = block { + final core::Map<core::String, core::int> #t323 = <core::String, core::int>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + for (final core::MapEntry<dynamic, dynamic> #t324 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) { + final core::String #t325 = #t324.{core::MapEntry::key} as{TypeError} core::String; + final core::int #t326 = #t324.{core::MapEntry::value} as{TypeError} core::int; + #t323.{core::Map::[]=}(#t325, #t326); + } + #t323.{core::Map::[]=}("baz", null); + } =>#t323; + core::List<core::int> list100 = block { + final core::List<core::int> #t327 = <core::int>[]; + for (final core::int #t328 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1)) + #t327.{core::List::add}(42); + } =>#t327; + core::Set<core::int> set100 = block { + final core::Set<core::int> #t329 = col::LinkedHashSet::•<core::int>(); + for (final core::int #t330 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1)) + #t329.{core::Set::add}(42); + } =>#t329; + core::Map<core::String, core::int> map100 = block { + final core::Map<core::String, core::int> #t331 = <core::String, core::int>{}; + for (final core::int #t332 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1)) + #t331.{core::Map::[]=}("bar", 42); + } =>#t331; + core::List<core::int> list110 = block { + final core::List<core::int> #t333 = <core::int>[]; + for (core::int i in <core::int>[1, 2, 3]) + #t333.{core::List::add}(i); + } =>#t333; + core::Set<core::int> set110 = block { + final core::Set<core::int> #t334 = col::LinkedHashSet::•<core::int>(); + for (core::int i in <core::int>[1, 2, 3]) + #t334.{core::Set::add}(i); + #t334.{core::Set::add}(null); + } =>#t334; + core::Map<core::String, core::int> map110 = block { + final core::Map<core::String, core::int> #t335 = <core::String, core::int>{}; + for (core::int i in <core::int>[1, 2, 3]) + #t335.{core::Map::[]=}("bar", i); + #t335.{core::Map::[]=}("baz", null); + } =>#t335; + core::List<core::int> list120 = block { + final core::List<core::int> #t336 = <core::int>[]; + for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>) + #t336.{core::List::add}(i as{TypeError} core::int); + } =>#t336; + core::Set<core::int> set120 = block { + final core::Set<core::int> #t337 = col::LinkedHashSet::•<core::int>(); + for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>) + #t337.{core::Set::add}(i as{TypeError} core::int); + #t337.{core::Set::add}(null); + } =>#t337; + core::Map<core::String, core::int> map120 = block { + final core::Map<core::String, core::int> #t338 = <core::String, core::int>{}; + for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>) + #t338.{core::Map::[]=}("bar", i as{TypeError} core::int); + #t338.{core::Map::[]=}("baz", null); + } =>#t338; + core::List<core::int> list130 = block { + final core::List<core::int> #t339 = <core::int>[]; + for (core::int i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1)) + #t339.{core::List::add}(i); + } =>#t339; + core::Set<core::int> set130 = block { + final core::Set<core::int> #t340 = col::LinkedHashSet::•<core::int>(); + for (core::int i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1)) + #t340.{core::Set::add}(i); + } =>#t340; + core::Map<core::int, core::int> map130 = block { + final core::Map<core::int, core::int> #t341 = <core::int, core::int>{}; + for (core::int i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1)) + #t341.{core::Map::[]=}(i, i); + } =>#t341; } static method testForElementErrors(core::Map<core::int, core::int> map, core::List<core::int> list) → dynamic async { - <core::int>[invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:190:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + block { + final core::List<core::int> #t342 = <core::int>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t342.{core::List::add}(let final<BottomType> #t343 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:210:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int>[for (int i = 0; oracle(\"foo\"); i++) \"bar\"]; - ^"]; - let final core::Set<core::int> #t309 = col::LinkedHashSet::•<core::int>() in let final dynamic #t310 = #t309.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:191:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + ^" in "bar" as{TypeError} core::int); + } =>#t342; + block { + final core::Set<core::int> #t344 = col::LinkedHashSet::•<core::int>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t344.{core::Set::add}(let final<BottomType> #t345 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:211:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\", null}; - ^") in let final dynamic #t311 = #t309.{core::Set::add}(null) in #t309; - <core::int, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:192:14: Error: A value of type 'String' can't be assigned to a variable of type 'int'. -Try changing the type of the left hand side, or casting the right hand side to 'int'. - <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null}; - ^": invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:192:14: Error: A value of type 'String' can't be assigned to a variable of type 'int'. -Try changing the type of the left hand side, or casting the right hand side to 'int'. - <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null}; - ^", let final<BottomType> #t312 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:192:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. -Try changing the type of the left hand side, or casting the right hand side to 'int'. - <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null}; - ^" in "baz" as{TypeError} core::int: null}; + ^" in "bar" as{TypeError} core::int); + #t344.{core::Set::add}(null); + } =>#t344; block { - final core::List<core::int> #t313 = <core::int>[]; + final core::Map<core::int, core::int> #t346 = <core::int, core::int>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::int #t314 in <core::int>[let final<BottomType> #t315 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:193:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + #t346.{core::Map::[]=}(let final<BottomType> #t347 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:212:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +Try changing the type of the left hand side, or casting the right hand side to 'int'. + <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null}; + ^" in "bar" as{TypeError} core::int, let final<BottomType> #t348 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:212:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +Try changing the type of the left hand side, or casting the right hand side to 'int'. + <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null}; + ^" in "bar" as{TypeError} core::int); + #t346.{core::Map::[]=}(let final<BottomType> #t349 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:212:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +Try changing the type of the left hand side, or casting the right hand side to 'int'. + <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null}; + ^" in "baz" as{TypeError} core::int, null); + } =>#t346; + block { + final core::List<core::int> #t350 = <core::int>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + for (final core::int #t351 in <core::int>[let final<BottomType> #t352 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int>[for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"]]; ^" in "bar" as{TypeError} core::int]) - #t313.{core::List::add}(#t314); - } =>#t313; + #t350.{core::List::add}(#t351); + } =>#t350; block { - final core::Set<core::int> #t316 = col::LinkedHashSet::•<core::int>(); + final core::Set<core::int> #t353 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::int #t317 in <core::int>[let final<BottomType> #t318 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:194:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + for (final core::int #t354 in <core::int>[let final<BottomType> #t355 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int>{for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"], null}; ^" in "bar" as{TypeError} core::int]) - #t316.{core::Set::add}(#t317); - #t316.{core::Set::add}(null); - } =>#t316; + #t353.{core::Set::add}(#t354); + #t353.{core::Set::add}(null); + } =>#t353; block { - final core::Map<core::int, core::int> #t319 = <core::int, core::int>{}; + final core::Map<core::int, core::int> #t356 = <core::int, core::int>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::MapEntry<core::int, core::int> #t320 in <core::int, core::int>{let final<BottomType> #t321 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:195:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + for (final core::MapEntry<core::int, core::int> #t357 in <core::int, core::int>{let final<BottomType> #t358 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null}; - ^" in "bar" as{TypeError} core::int: let final<BottomType> #t322 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:195:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + ^" in "bar" as{TypeError} core::int: let final<BottomType> #t359 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null}; ^" in "bar" as{TypeError} core::int}.{core::Map::entries}) - #t319.{core::Map::[]=}(#t320.{core::MapEntry::key}, #t320.{core::MapEntry::value}); - #t319.{core::Map::[]=}(let final<BottomType> #t323 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:195:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + #t356.{core::Map::[]=}(#t357.{core::MapEntry::key}, #t357.{core::MapEntry::value}); + #t356.{core::Map::[]=}(let final<BottomType> #t360 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:215:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null}; ^" in "baz" as{TypeError} core::int, null); - } =>#t319; + } =>#t356; block { - final core::List<core::int> #t324 = <core::int>[]; + final core::List<core::int> #t361 = <core::int>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t324.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:196:48: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + #t361.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:216:48: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>[for (int i = 0; oracle(\"foo\"); i++) ...map]; - ^" as{TypeError} core::int); - } =>#t324; + ^"); + } =>#t361; block { - final core::Set<core::int> #t325 = col::LinkedHashSet::•<core::int>(); + final core::Set<core::int> #t362 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t325.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:197:48: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + #t362.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:217:48: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>{for (int i = 0; oracle(\"foo\"); i++) ...map, null}; - ^" as{TypeError} core::int); - #t325.{core::Set::add}(null); - } =>#t325; - <core::int, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:198:53: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + ^"); + #t362.{core::Set::add}(null); + } =>#t362; + <core::int, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:218:53: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...list, 42: null}; - ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:198:53: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:218:53: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...list, 42: null}; ^": null}; - <core::String>[invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:199:48: Error: A value of type 'num' can't be assigned to a variable of type 'String'. + block { + final core::List<core::String> #t363 = <core::String>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t363.{core::List::add}(let final<BottomType> #t364 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:219:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'. Try changing the type of the left hand side, or casting the right hand side to 'String'. <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14]; - ^"]; - let final core::Set<core::String> #t326 = col::LinkedHashSet::•<core::String>() in let final dynamic #t327 = #t326.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:200:48: Error: A value of type 'num' can't be assigned to a variable of type 'String'. + ^" in 42 as{TypeError} core::String); + else + #t363.{core::List::add}(let final<BottomType> #t365 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:219:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14]; + ^" in 3.14 as{TypeError} core::String); + } =>#t363; + block { + final core::Set<core::String> #t366 = col::LinkedHashSet::•<core::String>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t366.{core::Set::add}(let final<BottomType> #t367 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:220:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'. Try changing the type of the left hand side, or casting the right hand side to 'String'. <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null}; - ^") in let final dynamic #t328 = #t326.{core::Set::add}(null) in #t326; - <core::String, core::String>{null: invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:201:20: Error: A value of type 'num' can't be assigned to a variable of type 'String'. + ^" in 42 as{TypeError} core::String); + else + #t366.{core::Set::add}(let final<BottomType> #t368 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:220:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null}; + ^" in 3.14 as{TypeError} core::String); + #t366.{core::Set::add}(null); + } =>#t366; + block { + final core::Map<core::String, core::String> #t369 = <core::String, core::String>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t369.{core::Map::[]=}("bar", let final<BottomType> #t370 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:221:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'. Try changing the type of the left hand side, or casting the right hand side to 'String'. <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null}; - ^", "baz": null}; + ^" in 42 as{TypeError} core::String); + else + #t369.{core::Map::[]=}("bar", let final<BottomType> #t371 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:221:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null}; + ^" in 3.14 as{TypeError} core::String); + #t369.{core::Map::[]=}("baz", null); + } =>#t369; block { - final core::List<core::int> #t329 = <core::int>[]; + final core::List<core::int> #t372 = <core::int>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t329.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:202:62: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t372.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:222:62: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...map else 42]; - ^" as{TypeError} core::int); + ^"); else - #t329.{core::List::add}(42 as{TypeError} core::int); - } =>#t329; + #t372.{core::List::add}(42); + } =>#t372; block { - final core::Set<core::int> #t330 = col::LinkedHashSet::•<core::int>(); + final core::Set<core::int> #t373 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t330.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:203:62: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t373.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:223:62: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...map else 42, null}; - ^" as{TypeError} core::int); + ^"); else - #t330.{core::Set::add}(42 as{TypeError} core::int); - #t330.{core::Set::add}(null); - } =>#t330; - <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:204:70: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + #t373.{core::Set::add}(42); + #t373.{core::Set::add}(null); + } =>#t373; + <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:70: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...list else \"bar\": 42, \"baz\": null}; - ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:204:70: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:70: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...list else \"bar\": 42, \"baz\": null}; ^": null}; block { - final core::List<core::int> #t331 = <core::int>[]; + final core::List<core::int> #t374 = <core::int>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t331.{core::List::add}(42 as{TypeError} core::int); + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t374.{core::List::add}(42); else - #t331.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:205:70: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + #t374.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:225:70: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else ...map]; - ^" as{TypeError} core::int); - } =>#t331; + ^"); + } =>#t374; block { - final core::Set<core::int> #t332 = col::LinkedHashSet::•<core::int>(); + final core::Set<core::int> #t375 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t332.{core::Set::add}(42 as{TypeError} core::int); + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t375.{core::Set::add}(42); else - #t332.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:206:70: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + #t375.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:226:70: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else ...map, null}; - ^" as{TypeError} core::int); - #t332.{core::Set::add}(null); - } =>#t332; - <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:207:85: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + ^"); + #t375.{core::Set::add}(null); + } =>#t375; + <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:227:85: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else ...list, \"baz\": null}; - ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:207:85: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:227:85: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else ...list, \"baz\": null}; ^": null}; final core::int i = 0; block { - final core::List<core::int> #t333 = <core::int>[]; - for (final core::int #t334 in <core::int>[1]) { - invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:210:14: Error: Setter not found: 'i'. + final core::List<core::int> #t376 = <core::int>[]; + for (final core::int #t377 in <core::int>[1]) { + invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:230:14: Error: Setter not found: 'i'. <int>[for (i in <int>[1]) i]; ^"; - #t333.{core::List::add}(i); + #t376.{core::List::add}(i); } - } =>#t333; + } =>#t376; block { - final core::Set<core::int> #t335 = col::LinkedHashSet::•<core::int>(); - for (final core::int #t336 in <core::int>[1]) { - invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:211:14: Error: Setter not found: 'i'. + final core::Set<core::int> #t378 = col::LinkedHashSet::•<core::int>(); + for (final core::int #t379 in <core::int>[1]) { + invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:231:14: Error: Setter not found: 'i'. <int>{for (i in <int>[1]) i, null}; ^"; - #t335.{core::Set::add}(i); + #t378.{core::Set::add}(i); } - #t335.{core::Set::add}(null); - } =>#t335; + #t378.{core::Set::add}(null); + } =>#t378; block { - final core::Map<core::String, core::int> #t337 = <core::String, core::int>{}; - for (final core::int #t338 in <core::int>[1]) { - invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:212:21: Error: Setter not found: 'i'. + final core::Map<core::String, core::int> #t380 = <core::String, core::int>{}; + for (final core::int #t381 in <core::int>[1]) { + invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:232:21: Error: Setter not found: 'i'. \t<String, int>{for (i in <int>[1]) \"bar\": i, \"baz\": null}; \t ^"; - #t337.{core::Map::[]=}("bar", i); + #t380.{core::Map::[]=}("bar", i); } - #t337.{core::Map::[]=}("baz", null); - } =>#t337; + #t380.{core::Map::[]=}("baz", null); + } =>#t380; core::List<dynamic> list10 = block { - final core::List<dynamic> #t339 = <dynamic>[]; - for (dynamic i in let final<BottomType> #t340 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:214:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. + final core::List<dynamic> #t382 = <dynamic>[]; + for (dynamic i in let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:234:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. - 'Iterable' is from 'dart:core'. var list10 = [for (var i in \"not iterable\") i]; ^" in "not iterable" as{TypeError} core::Iterable<dynamic>) - #t339.{core::List::add}(i); - } =>#t339; + #t382.{core::List::add}(i); + } =>#t382; core::Set<dynamic> set10 = block { - final core::Set<dynamic> #t341 = col::LinkedHashSet::•<dynamic>(); - for (dynamic i in let final<BottomType> #t342 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:215:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. + final core::Set<dynamic> #t384 = col::LinkedHashSet::•<dynamic>(); + for (dynamic i in let final<BottomType> #t385 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:235:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. - 'Iterable' is from 'dart:core'. var set10 = {for (var i in \"not iterable\") i, null}; ^" in "not iterable" as{TypeError} core::Iterable<dynamic>) - #t341.{core::Set::add}(i); - #t341.{core::Set::add}(null); - } =>#t341; + #t384.{core::Set::add}(i); + #t384.{core::Set::add}(null); + } =>#t384; core::Map<core::String, dynamic> map10 = block { - final core::Map<core::String, dynamic> #t343 = <core::String, dynamic>{}; - for (dynamic i in let final<BottomType> #t344 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:216:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. + final core::Map<core::String, dynamic> #t386 = <core::String, dynamic>{}; + for (dynamic i in let final<BottomType> #t387 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:236:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. - 'Iterable' is from 'dart:core'. var map10 = {for (var i in \"not iterable\") \"bar\": i, \"baz\": null}; ^" in "not iterable" as{TypeError} core::Iterable<dynamic>) - #t343.{core::Map::[]=}("bar", i); - #t343.{core::Map::[]=}("baz", null); - } =>#t343; + #t386.{core::Map::[]=}("bar", i); + #t386.{core::Map::[]=}("baz", null); + } =>#t386; core::List<core::int> list20 = block { - final core::List<core::int> #t345 = <core::int>[]; - for (core::int i in <core::int>[let final<BottomType> #t346 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:217:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + final core::List<core::int> #t388 = <core::int>[]; + for (core::int i in <core::int>[let final<BottomType> #t389 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var list20 = [for (int i in [\"not\", \"int\"]) i]; - ^" in "not" as{TypeError} core::int, let final<BottomType> #t347 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:217:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + ^" in "not" as{TypeError} core::int, let final<BottomType> #t390 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var list20 = [for (int i in [\"not\", \"int\"]) i]; ^" in "int" as{TypeError} core::int]) - #t345.{core::List::add}(i); - } =>#t345; + #t388.{core::List::add}(i); + } =>#t388; core::Set<core::int> set20 = block { - final core::Set<core::int> #t348 = col::LinkedHashSet::•<core::int>(); - for (core::int i in <core::int>[let final<BottomType> #t349 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:218:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + final core::Set<core::int> #t391 = col::LinkedHashSet::•<core::int>(); + for (core::int i in <core::int>[let final<BottomType> #t392 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var set20 = {for (int i in [\"not\", \"int\"]) i, null}; - ^" in "not" as{TypeError} core::int, let final<BottomType> #t350 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:218:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + ^" in "not" as{TypeError} core::int, let final<BottomType> #t393 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var set20 = {for (int i in [\"not\", \"int\"]) i, null}; ^" in "int" as{TypeError} core::int]) - #t348.{core::Set::add}(i); - #t348.{core::Set::add}(null); - } =>#t348; + #t391.{core::Set::add}(i); + #t391.{core::Set::add}(null); + } =>#t391; core::Map<core::String, core::int> map20 = block { - final core::Map<core::String, core::int> #t351 = <core::String, core::int>{}; - for (core::int i in <core::int>[let final<BottomType> #t352 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:219:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + final core::Map<core::String, core::int> #t394 = <core::String, core::int>{}; + for (core::int i in <core::int>[let final<BottomType> #t395 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null}; - ^" in "not" as{TypeError} core::int, let final<BottomType> #t353 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:219:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + ^" in "not" as{TypeError} core::int, let final<BottomType> #t396 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null}; ^" in "int" as{TypeError} core::int]) - #t351.{core::Map::[]=}("bar", i); - #t351.{core::Map::[]=}("baz", null); - } =>#t351; + #t394.{core::Map::[]=}("bar", i); + #t394.{core::Map::[]=}("baz", null); + } =>#t394; core::List<dynamic> list30 = block { - final core::List<dynamic> #t354 = <dynamic>[]; - await for (dynamic i in let final<BottomType> #t355 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:220:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. + final core::List<dynamic> #t397 = <dynamic>[]; + await for (dynamic i in let final<BottomType> #t398 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:240:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. - 'Stream' is from 'dart:async'. var list30 = [await for (var i in \"not stream\") i]; ^" in "not stream" as{TypeError} asy::Stream<dynamic>) - #t354.{core::List::add}(i); - } =>#t354; + #t397.{core::List::add}(i); + } =>#t397; core::Set<dynamic> set30 = block { - final core::Set<dynamic> #t356 = col::LinkedHashSet::•<dynamic>(); - await for (dynamic i in let final<BottomType> #t357 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:221:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. + final core::Set<dynamic> #t399 = col::LinkedHashSet::•<dynamic>(); + await for (dynamic i in let final<BottomType> #t400 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:241:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. - 'Stream' is from 'dart:async'. var set30 = {await for (var i in \"not stream\") i, null}; ^" in "not stream" as{TypeError} asy::Stream<dynamic>) - #t356.{core::Set::add}(i); - #t356.{core::Set::add}(null); - } =>#t356; + #t399.{core::Set::add}(i); + #t399.{core::Set::add}(null); + } =>#t399; core::Map<core::String, dynamic> map30 = block { - final core::Map<core::String, dynamic> #t358 = <core::String, dynamic>{}; - await for (dynamic i in let final<BottomType> #t359 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:222:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. + final core::Map<core::String, dynamic> #t401 = <core::String, dynamic>{}; + await for (dynamic i in let final<BottomType> #t402 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:242:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. - 'Stream' is from 'dart:async'. var map30 = {await for (var i in \"not stream\") \"bar\": i, \"baz\": null}; ^" in "not stream" as{TypeError} asy::Stream<dynamic>) - #t358.{core::Map::[]=}("bar", i); - #t358.{core::Map::[]=}("baz", null); - } =>#t358; + #t401.{core::Map::[]=}("bar", i); + #t401.{core::Map::[]=}("baz", null); + } =>#t401; core::List<core::int> list40 = block { - final core::List<core::int> #t360 = <core::int>[]; - await for (core::int i in asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t361 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:223:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + final core::List<core::int> #t403 = <core::int>[]; + await for (core::int i in asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t404 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i]; - ^" in "not" as{TypeError} core::int, let final<BottomType> #t362 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:223:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + ^" in "not" as{TypeError} core::int, let final<BottomType> #t405 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i]; ^" in "int" as{TypeError} core::int])) - #t360.{core::List::add}(i); - } =>#t360; + #t403.{core::List::add}(i); + } =>#t403; core::Set<core::int> set40 = block { - final core::Set<core::int> #t363 = col::LinkedHashSet::•<core::int>(); - await for (core::int i in asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t364 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + final core::Set<core::int> #t406 = col::LinkedHashSet::•<core::int>(); + await for (core::int i in asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t407 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null}; - ^" in "not" as{TypeError} core::int, let final<BottomType> #t365 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + ^" in "not" as{TypeError} core::int, let final<BottomType> #t408 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null}; ^" in "int" as{TypeError} core::int])) - #t363.{core::Set::add}(i); - #t363.{core::Set::add}(null); - } =>#t363; + #t406.{core::Set::add}(i); + #t406.{core::Set::add}(null); + } =>#t406; core::Map<core::String, core::int> map40 = block { - final core::Map<core::String, core::int> #t366 = <core::String, core::int>{}; - await for (core::int i in asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t367 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:225:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + final core::Map<core::String, core::int> #t409 = <core::String, core::int>{}; + await for (core::int i in asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t410 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null}; - ^" in "not" as{TypeError} core::int, let final<BottomType> #t368 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:225:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + ^" in "not" as{TypeError} core::int, let final<BottomType> #t411 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null}; ^" in "int" as{TypeError} core::int])) - #t366.{core::Map::[]=}("bar", i); - #t366.{core::Map::[]=}("baz", null); - } =>#t366; + #t409.{core::Map::[]=}("bar", i); + #t409.{core::Map::[]=}("baz", null); + } =>#t409; core::List<core::int> list50 = block { - final core::List<core::int> #t369 = <core::int>[]; + final core::List<core::int> #t412 = <core::int>[]; for (; ; ) - #t369.{core::List::add}(42); - } =>#t369; + #t412.{core::List::add}(42); + } =>#t412; core::Set<core::int> set50 = block { - final core::Set<core::int> #t370 = col::LinkedHashSet::•<core::int>(); + final core::Set<core::int> #t413 = col::LinkedHashSet::•<core::int>(); for (; ; ) - #t370.{core::Set::add}(42); - #t370.{core::Set::add}(null); - } =>#t370; + #t413.{core::Set::add}(42); + #t413.{core::Set::add}(null); + } =>#t413; core::Map<core::String, core::int> map50 = block { - final core::Map<core::String, core::int> #t371 = <core::String, core::int>{}; + final core::Map<core::String, core::int> #t414 = <core::String, core::int>{}; for (; ; ) - #t371.{core::Map::[]=}("bar", 42); - #t371.{core::Map::[]=}("baz", null); - } =>#t371; + #t414.{core::Map::[]=}("bar", 42); + #t414.{core::Map::[]=}("baz", null); + } =>#t414; core::List<core::int> list60 = block { - final core::List<core::int> #t372 = <core::int>[]; - for (; let final<BottomType> #t373 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:229:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. + final core::List<core::int> #t415 = <core::int>[]; + for (; let final<BottomType> #t416 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:249:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. Try changing the type of the left hand side, or casting the right hand side to 'bool'. var list60 = [for (; \"not bool\";) 42]; ^" in "not bool" as{TypeError} core::bool; ) - #t372.{core::List::add}(42); - } =>#t372; + #t415.{core::List::add}(42); + } =>#t415; core::Set<core::int> set60 = block { - final core::Set<core::int> #t374 = col::LinkedHashSet::•<core::int>(); - for (; let final<BottomType> #t375 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:230:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. + final core::Set<core::int> #t417 = col::LinkedHashSet::•<core::int>(); + for (; let final<BottomType> #t418 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. Try changing the type of the left hand side, or casting the right hand side to 'bool'. var set60 = {for (; \"not bool\";) 42, null}; ^" in "not bool" as{TypeError} core::bool; ) - #t374.{core::Set::add}(42); - #t374.{core::Set::add}(null); - } =>#t374; + #t417.{core::Set::add}(42); + #t417.{core::Set::add}(null); + } =>#t417; core::Map<core::String, core::int> map60 = block { - final core::Map<core::String, core::int> #t376 = <core::String, core::int>{}; - for (; let final<BottomType> #t377 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:231:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. + final core::Map<core::String, core::int> #t419 = <core::String, core::int>{}; + for (; let final<BottomType> #t420 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:251:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. Try changing the type of the left hand side, or casting the right hand side to 'bool'. var map60 = {for (; \"not bool\";) \"bar\": 42, \"baz\": null}; ^" in "not bool" as{TypeError} core::bool; ) - #t376.{core::Map::[]=}("bar", 42); - #t376.{core::Map::[]=}("baz", null); - } =>#t376; + #t419.{core::Map::[]=}("bar", 42); + #t419.{core::Map::[]=}("baz", null); + } =>#t419; } static method testForElementErrorsNotAsync(asy::Stream<core::int> stream) → dynamic { block { - final core::List<core::int> #t378 = <core::int>[]; + final core::List<core::int> #t421 = <core::int>[]; await for (core::int i in stream) - #t378.{core::List::add}(i); - } =>#t378; + #t421.{core::List::add}(i); + } =>#t421; block { - final core::Set<core::int> #t379 = col::LinkedHashSet::•<core::int>(); + final core::Set<core::int> #t422 = col::LinkedHashSet::•<core::int>(); await for (core::int i in stream) - #t379.{core::Set::add}(i); - } =>#t379; + #t422.{core::Set::add}(i); + } =>#t422; block { - final core::Map<core::String, core::int> #t380 = <core::String, core::int>{}; + final core::Map<core::String, core::int> #t423 = <core::String, core::int>{}; await for (core::int i in stream) - #t380.{core::Map::[]=}("bar", i); - } =>#t380; + #t423.{core::Map::[]=}("bar", i); + } =>#t423; +} +static method testPromotion(self::A a) → dynamic { + core::List<core::int> list10 = block { + final core::List<core::int> #t424 = <core::int>[]; + if(a is self::B) + #t424.{core::List::add}(a{self::B}.{self::B::foo}); + } =>#t424; + core::Set<core::int> set10 = block { + final core::Set<core::int> #t425 = col::LinkedHashSet::•<core::int>(); + if(a is self::B) + #t425.{core::Set::add}(a{self::B}.{self::B::foo}); + } =>#t425; + core::Map<core::int, core::int> map10 = block { + final core::Map<core::int, core::int> #t426 = <core::int, core::int>{}; + if(a is self::B) + #t426.{core::Map::[]=}(a{self::B}.{self::B::foo}, a{self::B}.{self::B::foo}); + } =>#t426; } static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.transformed.expect index 14b2064..3c4ea93 100644 --- a/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.transformed.expect
@@ -11,379 +11,466 @@ // var map82 = {if (oracle("foo")) ...mapToInt else ...dynVar, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:84:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:106:44: Error: Expected ':' after this. +// Set<dynamic> set10 = {if (oracle("foo")) 42 else "bar": 3.14}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:107:53: Error: Expected ':' after this. +// Map<dynamic, dynamic> map10 = {if (oracle("foo")) 42 else "bar": 3.14}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:108:61: Error: Expected ':' after this. +// Set<dynamic> set11 = {if (oracle("foo")) "bar": 3.14 else 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:109:70: Error: Expected ':' after this. +// Map<dynamic, dynamic> map11 = {if (oracle("foo")) "bar": 3.14 else 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:110:35: Error: Expected ':' after this. +// var map12 = {if (oracle("foo")) 42 else "bar": 3.14}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:111:52: Error: Expected ':' after this. +// var map13 = {if (oracle("foo")) "bar": 3.14 else 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:87:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int>[if (oracle("foo")) "bar"]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:85:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:88:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int>{if (oracle("foo")) "bar", null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:86:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:89:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <String, int>{if (oracle("foo")) "bar": "bar", "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:86:41: Error: A value of type 'String' can't be assigned to a variable of type 'int'. -// Try changing the type of the left hand side, or casting the right hand side to 'int'. -// <String, int>{if (oracle("foo")) "bar": "bar", "baz": null}; -// ^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:87:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int>[if (oracle("foo")) ...["bar"]]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:88:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int>{if (oracle("foo")) ...["bar"], null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:89:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:90:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:93:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>[if (oracle("foo")) ...map]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:91:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:94:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>{if (oracle("foo")) ...map, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:92:39: Error: Unexpected type 'List<String>' of a map spread entry. Expected 'dynamic' or a Map. +// pkg/front_end/testcases/control_flow_collection_inference.dart:95:39: Error: Unexpected type 'List<String>' of a map spread entry. Expected 'dynamic' or a Map. // - 'List' is from 'dart:core'. // <String, int>{if (oracle("foo")) ...["bar"], "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:93:12: Error: A value of type 'num' can't be assigned to a variable of type 'String'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:96:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'. // Try changing the type of the left hand side, or casting the right hand side to 'String'. // <String>[if (oracle("foo")) 42 else 3.14]; -// ^ +// ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:94:12: Error: A value of type 'num' can't be assigned to a variable of type 'String'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:96:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// <String>[if (oracle("foo")) 42 else 3.14]; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:97:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'. // Try changing the type of the left hand side, or casting the right hand side to 'String'. // <String>{if (oracle("foo")) 42 else 3.14, null}; -// ^ +// ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:95:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:97:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// <String>{if (oracle("foo")) 42 else 3.14, null}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:98:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'. // Try changing the type of the left hand side, or casting the right hand side to 'String'. // <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:95:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:98:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'. // Try changing the type of the left hand side, or casting the right hand side to 'String'. // <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:95:20: Error: A value of type 'num' can't be assigned to a variable of type 'String'. -// Try changing the type of the left hand side, or casting the right hand side to 'String'. -// <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null}; -// ^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:96:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:99:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>[if (oracle("foo")) ...map else 42]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:97:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. -// - 'Map' is from 'dart:core'. -// <int>{if (oracle("foo")) ...map else 42, null}; -// ^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:98:39: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. -// - 'List' is from 'dart:core'. -// <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null}; -// ^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:99:39: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. -// - 'Map' is from 'dart:core'. -// <int>[if (oracle("foo")) 42 else ...map]; -// ^ -// // pkg/front_end/testcases/control_flow_collection_inference.dart:100:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>{if (oracle("foo")) ...map else 42, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:101:54: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. +// pkg/front_end/testcases/control_flow_collection_inference.dart:101:39: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. +// - 'List' is from 'dart:core'. +// <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:102:39: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// - 'Map' is from 'dart:core'. +// <int>[if (oracle("foo")) 42 else ...map]; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:103:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// - 'Map' is from 'dart:core'. +// <int>{if (oracle("foo")) ...map else 42, null}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:104:54: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. // - 'List' is from 'dart:core'. // <String, int>{if (oracle("foo")) "bar": 42 else ...[42], "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:210:14: Error: Setter not found: 'i'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:106:24: Error: Both Iterable and Map spread elements encountered in ambiguous literal. +// Set<dynamic> set10 = {if (oracle("foo")) 42 else "bar": 3.14}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:108:24: Error: Both Iterable and Map spread elements encountered in ambiguous literal. +// Set<dynamic> set11 = {if (oracle("foo")) "bar": 3.14 else 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:112:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'. +// Try changing the type of the left hand side, or casting the right hand side to 'bool'. +// List<int> list20 = [if (42) 42]; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'. +// Try changing the type of the left hand side, or casting the right hand side to 'bool'. +// Set<int> set20 = {if (42) 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:114:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'. +// Try changing the type of the left hand side, or casting the right hand side to 'bool'. +// Map<int, int> map30 = {if (42) 42: 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:115:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// List<String> list40 = <String>[if (oracle("foo")) true else 42]; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:115:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// List<String> list40 = <String>[if (oracle("foo")) true else 42]; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// Set<String> set40 = <String>{if (oracle("foo")) true else 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:116:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// Set<String> set40 = <String>{if (oracle("foo")) true else 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:117:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:117:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:118:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:118:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:230:14: Error: Setter not found: 'i'. // <int>[for (i in <int>[1]) i]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:211:14: Error: Setter not found: 'i'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:231:14: Error: Setter not found: 'i'. // <int>{for (i in <int>[1]) i, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:212:21: Error: Setter not found: 'i'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:232:21: Error: Setter not found: 'i'. // <String, int>{for (i in <int>[1]) "bar": i, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:226:17: Error: The keyword 'await' isn't allowed for a normal 'for' statement. +// pkg/front_end/testcases/control_flow_collection_inference.dart:246:17: Error: The keyword 'await' isn't allowed for a normal 'for' statement. // Try removing the keyword, or use a for-each statement. // var list50 = [await for (;;) 42]; // ^^^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:227:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement. +// pkg/front_end/testcases/control_flow_collection_inference.dart:247:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement. // Try removing the keyword, or use a for-each statement. // var set50 = {await for (;;) 42, null}; // ^^^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:228:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement. +// pkg/front_end/testcases/control_flow_collection_inference.dart:248:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement. // Try removing the keyword, or use a for-each statement. // var map50 = {await for (;;) "bar": 42, "baz": null}; // ^^^^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:190:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:210:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int>[for (int i = 0; oracle("foo"); i++) "bar"]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:191:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:211:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int>{for (int i = 0; oracle("foo"); i++) "bar", null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:192:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:212:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:192:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:212:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:192:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:212:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:192:14: Error: A value of type 'String' can't be assigned to a variable of type 'int'. -// Try changing the type of the left hand side, or casting the right hand side to 'int'. -// <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null}; -// ^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:193:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int>[for (int i = 0; oracle("foo"); i++) ...["bar"]]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:194:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int>{for (int i = 0; oracle("foo"); i++) ...["bar"], null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:195:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:195:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:195:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:215:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:196:48: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:216:48: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>[for (int i = 0; oracle("foo"); i++) ...map]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:197:48: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:217:48: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>{for (int i = 0; oracle("foo"); i++) ...map, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:198:53: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. +// pkg/front_end/testcases/control_flow_collection_inference.dart:218:53: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. // - 'List' is from 'dart:core'. // <int, int>{for (int i = 0; oracle("foo"); i++) ...list, 42: null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:199:48: Error: A value of type 'num' can't be assigned to a variable of type 'String'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:219:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'. // Try changing the type of the left hand side, or casting the right hand side to 'String'. // <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14]; -// ^ +// ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:200:48: Error: A value of type 'num' can't be assigned to a variable of type 'String'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:219:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14]; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:220:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'. // Try changing the type of the left hand side, or casting the right hand side to 'String'. // <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null}; -// ^ +// ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:201:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:220:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +// Try changing the type of the left hand side, or casting the right hand side to 'String'. +// <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null}; +// ^ +// +// pkg/front_end/testcases/control_flow_collection_inference.dart:221:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'. // Try changing the type of the left hand side, or casting the right hand side to 'String'. // <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:201:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:221:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'. // Try changing the type of the left hand side, or casting the right hand side to 'String'. // <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:201:20: Error: A value of type 'num' can't be assigned to a variable of type 'String'. -// Try changing the type of the left hand side, or casting the right hand side to 'String'. -// <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null}; -// ^ -// -// pkg/front_end/testcases/control_flow_collection_inference.dart:202:62: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:222:62: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:203:62: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:223:62: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:204:70: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. +// pkg/front_end/testcases/control_flow_collection_inference.dart:224:70: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. // - 'List' is from 'dart:core'. // <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:205:70: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:225:70: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:206:70: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. +// pkg/front_end/testcases/control_flow_collection_inference.dart:226:70: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. // - 'Map' is from 'dart:core'. // <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:207:85: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. +// pkg/front_end/testcases/control_flow_collection_inference.dart:227:85: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. // - 'List' is from 'dart:core'. // <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:214:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:234:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. // - 'Iterable' is from 'dart:core'. // var list10 = [for (var i in "not iterable") i]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:215:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:235:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. // - 'Iterable' is from 'dart:core'. // var set10 = {for (var i in "not iterable") i, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:216:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:236:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. // - 'Iterable' is from 'dart:core'. // var map10 = {for (var i in "not iterable") "bar": i, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:217:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var list20 = [for (int i in ["not", "int"]) i]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:217:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var list20 = [for (int i in ["not", "int"]) i]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:218:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var set20 = {for (int i in ["not", "int"]) i, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:218:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var set20 = {for (int i in ["not", "int"]) i, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:219:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var map20 = {for (int i in ["not", "int"]) "bar": i, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:219:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var map20 = {for (int i in ["not", "int"]) "bar": i, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:220:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:240:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. // - 'Stream' is from 'dart:async'. // var list30 = [await for (var i in "not stream") i]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:221:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:241:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. // - 'Stream' is from 'dart:async'. // var set30 = {await for (var i in "not stream") i, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:222:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:242:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. // - 'Stream' is from 'dart:async'. // var map30 = {await for (var i in "not stream") "bar": i, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:223:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var list40 = [await for (int i in Stream.fromIterable(["not", "int"])) i]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:223:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var list40 = [await for (int i in Stream.fromIterable(["not", "int"])) i]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:224:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var set40 = {await for (int i in Stream.fromIterable(["not", "int"])) i, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:224:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var set40 = {await for (int i in Stream.fromIterable(["not", "int"])) i, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:225:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var map40 = {await for (int i in Stream.fromIterable(["not", "int"])) "bar": i, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:225:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. // Try changing the type of the left hand side, or casting the right hand side to 'int'. // var map40 = {await for (int i in Stream.fromIterable(["not", "int"])) "bar": i, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:229:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:249:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. // Try changing the type of the left hand side, or casting the right hand side to 'bool'. // var list60 = [for (; "not bool";) 42]; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:230:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. // Try changing the type of the left hand side, or casting the right hand side to 'bool'. // var set60 = {for (; "not bool";) 42, null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:231:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:251:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. // Try changing the type of the left hand side, or casting the right hand side to 'bool'. // var map60 = {for (; "not bool";) "bar": 42, "baz": null}; // ^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:235:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:255:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop. // <int>[await for (int i in stream) i]; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:236:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:256:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop. // <int>{await for (int i in stream) i}; // ^^ // -// pkg/front_end/testcases/control_flow_collection_inference.dart:237:34: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. +// pkg/front_end/testcases/control_flow_collection_inference.dart:257:34: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'. // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop. // <String, int>{await for (int i in stream) "bar": i}; // ^^ @@ -393,198 +480,210 @@ import "dart:collection" as col; import "dart:async" as asy; +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +class B extends self::A { + synthetic constructor •() → self::B + : super self::A::•() + ; + get foo() → core::int + return 42; +} static method oracle<T extends core::Object = dynamic>([self::oracle::T t = null]) → dynamic return true; static method testIfElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::Map<core::String, core::int> mapToInt, core::Map<core::String, core::double> mapToDouble) → dynamic { core::List<core::int> list10 = block { final core::List<core::int> #t1 = <core::int>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t1.{core::List::add}(42); } =>#t1; core::Set<core::int> set10 = block { final core::Set<core::int> #t2 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t2.{core::Set::add}(42); #t2.{core::Set::add}(null); } =>#t2; core::Map<core::String, core::int> map10 = block { final core::Map<core::String, core::int> #t3 = <core::String, core::int>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t3.{core::Map::[]=}("bar", 42); #t3.{core::Map::[]=}("baz", null); } =>#t3; core::List<dynamic> list11 = block { final core::List<dynamic> #t4 = <dynamic>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t4.{core::List::add}(dynVar); } =>#t4; core::Set<dynamic> set11 = block { final core::Set<dynamic> #t5 = col::LinkedHashSet::•<dynamic>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t5.{core::Set::add}(dynVar); #t5.{core::Set::add}(null); } =>#t5; core::Map<core::String, dynamic> map11 = block { final core::Map<core::String, dynamic> #t6 = <core::String, dynamic>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t6.{core::Map::[]=}("bar", dynVar); #t6.{core::Map::[]=}("baz", null); } =>#t6; core::List<core::List<core::int>> list12 = block { final core::List<core::List<core::int>> #t7 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t7.{core::List::add}(<core::int>[42]); } =>#t7; core::Set<core::List<core::int>> set12 = block { final core::Set<core::List<core::int>> #t8 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t8.{core::Set::add}(<core::int>[42]); #t8.{core::Set::add}(null); } =>#t8; core::Map<core::String, core::List<core::int>> map12 = block { final core::Map<core::String, core::List<core::int>> #t9 = <core::String, core::List<core::int>>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t9.{core::Map::[]=}("bar", <core::int>[42]); #t9.{core::Map::[]=}("baz", null); } =>#t9; core::List<core::int> list20 = block { final core::List<core::int> #t10 = <core::int>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::int #t11 in <core::int>[42]) #t10.{core::List::add}(#t11); } =>#t10; core::Set<core::int> set20 = block { final core::Set<core::int> #t12 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::int #t13 in <core::int>[42]) #t12.{core::Set::add}(#t13); #t12.{core::Set::add}(null); } =>#t12; core::Map<core::String, core::int> map20 = block { final core::Map<core::String, core::int> #t14 = <core::String, core::int>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::MapEntry<core::String, core::int> #t15 in <core::String, core::int>{"bar": 42}.{core::Map::entries}) #t14.{core::Map::[]=}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value}); #t14.{core::Map::[]=}("baz", null); } =>#t14; core::List<dynamic> list21 = block { final core::List<dynamic> #t16 = <dynamic>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final dynamic #t17 in <dynamic>[dynVar]) #t16.{core::List::add}(#t17); } =>#t16; core::Set<dynamic> set21 = block { final core::Set<dynamic> #t18 = col::LinkedHashSet::•<dynamic>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final dynamic #t19 in <dynamic>[dynVar]) #t18.{core::Set::add}(#t19); #t18.{core::Set::add}(null); } =>#t18; core::Map<core::String, dynamic> map21 = block { final core::Map<core::String, dynamic> #t20 = <core::String, dynamic>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::MapEntry<core::String, dynamic> #t21 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries}) #t20.{core::Map::[]=}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value}); #t20.{core::Map::[]=}("baz", null); } =>#t20; core::List<core::List<core::int>> list22 = block { final core::List<core::List<core::int>> #t22 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::List<core::int> #t23 in <core::List<core::int>>[<core::int>[42]]) #t22.{core::List::add}(#t23); } =>#t22; core::Set<core::List<core::int>> set22 = block { final core::Set<core::List<core::int>> #t24 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::List<core::int> #t25 in <core::List<core::int>>[<core::int>[42]]) #t24.{core::Set::add}(#t25); #t24.{core::Set::add}(null); } =>#t24; core::Map<core::String, core::List<core::int>> map22 = block { final core::Map<core::String, core::List<core::int>> #t26 = <core::String, core::List<core::int>>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::MapEntry<core::String, core::List<core::int>> #t27 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries}) #t26.{core::Map::[]=}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value}); #t26.{core::Map::[]=}("baz", null); } =>#t26; core::List<core::int> list30 = block { final core::List<core::int> #t28 = <core::int>[]; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::int #t29 in <core::int>[42]) #t28.{core::List::add}(#t29); } =>#t28; core::Set<core::int> set30 = block { final core::Set<core::int> #t30 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::int #t31 in <core::int>[42]) #t30.{core::Set::add}(#t31); #t30.{core::Set::add}(null); } =>#t30; core::Map<core::String, core::int> map30 = block { final core::Map<core::String, core::int> #t32 = <core::String, core::int>{}; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::MapEntry<core::String, core::int> #t33 in <core::String, core::int>{"bar": 42}.{core::Map::entries}) #t32.{core::Map::[]=}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value}); #t32.{core::Map::[]=}("baz", null); } =>#t32; core::List<dynamic> list31 = block { final core::List<dynamic> #t34 = <dynamic>[]; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final dynamic #t35 in <dynamic>[dynVar]) #t34.{core::List::add}(#t35); } =>#t34; core::Set<dynamic> set31 = block { final core::Set<dynamic> #t36 = col::LinkedHashSet::•<dynamic>(); - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final dynamic #t37 in <dynamic>[dynVar]) #t36.{core::Set::add}(#t37); #t36.{core::Set::add}(null); } =>#t36; core::Map<core::String, dynamic> map31 = block { final core::Map<core::String, dynamic> #t38 = <core::String, dynamic>{}; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::MapEntry<core::String, dynamic> #t39 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries}) #t38.{core::Map::[]=}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value}); #t38.{core::Map::[]=}("baz", null); } =>#t38; core::List<core::List<core::int>> list33 = block { final core::List<core::List<core::int>> #t40 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::List<core::int> #t41 in <core::List<core::int>>[<core::int>[42]]) #t40.{core::List::add}(#t41); } =>#t40; core::Set<core::List<core::int>> set33 = block { final core::Set<core::List<core::int>> #t42 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::List<core::int> #t43 in <core::List<core::int>>[<core::int>[42]]) #t42.{core::Set::add}(#t43); #t42.{core::Set::add}(null); } =>#t42; core::Map<core::String, core::List<core::int>> map33 = block { final core::Map<core::String, core::List<core::int>> #t44 = <core::String, core::List<core::int>>{}; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::MapEntry<core::String, core::List<core::int>> #t45 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries}) #t44.{core::Map::[]=}(#t45.{core::MapEntry::key}, #t45.{core::MapEntry::value}); #t44.{core::Map::[]=}("baz", null); } =>#t44; core::List<core::List<core::int>> list40 = block { final core::List<core::List<core::int>> #t46 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::List<core::int> #t47 in <core::List<core::int>>[<core::int>[]]) #t46.{core::List::add}(#t47); } =>#t46; core::Set<core::List<core::int>> set40 = block { final core::Set<core::List<core::int>> #t48 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::List<core::int> #t49 in <core::List<core::int>>[<core::int>[]]) #t48.{core::Set::add}(#t49); #t48.{core::Set::add}(null); @@ -594,173 +693,173 @@ ^"; core::List<core::List<core::int>> list41 = block { final core::List<core::List<core::int>> #t50 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::List<core::int> #t51 in let final core::Set<core::List<core::int>> #t52 = col::LinkedHashSet::•<core::List<core::int>>() in let final core::bool #t53 = #t52.{core::Set::add}(<core::int>[]) in #t52) #t50.{core::List::add}(#t51); } =>#t50; core::Set<core::List<core::int>> set41 = block { final core::Set<core::List<core::int>> #t54 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::List<core::int> #t55 in let final core::Set<core::List<core::int>> #t56 = col::LinkedHashSet::•<core::List<core::int>>() in let final core::bool #t57 = #t56.{core::Set::add}(<core::int>[]) in #t56) #t54.{core::Set::add}(#t55); #t54.{core::Set::add}(null); } =>#t54; core::List<core::List<core::int>> list42 = block { final core::List<core::List<core::int>> #t58 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::List<core::int> #t59 in <core::List<core::int>>[<core::int>[]]) #t58.{core::List::add}(#t59); } =>#t58; core::Set<core::List<core::int>> set42 = block { final core::Set<core::List<core::int>> #t60 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::List<core::int> #t61 in <core::List<core::int>>[<core::int>[]]) #t60.{core::Set::add}(#t61); #t60.{core::Set::add}(null); } =>#t60; core::Map<core::String, core::List<core::int>> map42 = block { final core::Map<core::String, core::List<core::int>> #t62 = <core::String, core::List<core::int>>{}; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::MapEntry<core::String, core::List<core::int>> #t63 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) #t62.{core::Map::[]=}(#t63.{core::MapEntry::key}, #t63.{core::MapEntry::value}); #t62.{core::Map::[]=}("baz", null); } =>#t62; core::List<core::int> list50 = block { final core::List<core::int> #t64 = <core::int>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::int #t65 in <core::int>[]) #t64.{core::List::add}(#t65); } =>#t64; core::Set<core::int> set50 = block { final core::Set<core::int> #t66 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::int #t67 in <core::int>[]) #t66.{core::Set::add}(#t67); #t66.{core::Set::add}(null); } =>#t66; core::Map<core::String, core::int> map50 = block { final core::Map<core::String, core::int> #t68 = <core::String, core::int>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::MapEntry<core::String, core::int> #t69 in <core::String, core::int>{}.{core::Map::entries}) #t68.{core::Map::[]=}(#t69.{core::MapEntry::key}, #t69.{core::MapEntry::value}); #t68.{core::Map::[]=}("baz", null); } =>#t68; core::List<core::int> list51 = block { final core::List<core::int> #t70 = <core::int>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::int #t71 in let final core::Set<core::int> #t72 = col::LinkedHashSet::•<core::int>() in #t72) #t70.{core::List::add}(#t71); } =>#t70; core::Set<core::int> set51 = block { final core::Set<core::int> #t73 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::int #t74 in let final core::Set<core::int> #t75 = col::LinkedHashSet::•<core::int>() in #t75) #t73.{core::Set::add}(#t74); #t73.{core::Set::add}(null); } =>#t73; core::List<core::int> list52 = block { final core::List<core::int> #t76 = <core::int>[]; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::int #t77 in <core::int>[]) #t76.{core::List::add}(#t77); } =>#t76; core::Set<core::int> set52 = block { final core::Set<core::int> #t78 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::int #t79 in <core::int>[]) #t78.{core::Set::add}(#t79); #t78.{core::Set::add}(null); } =>#t78; core::Map<core::String, core::int> map52 = block { final core::Map<core::String, core::int> #t80 = <core::String, core::int>{}; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::MapEntry<core::String, core::int> #t81 in <core::String, core::int>{}.{core::Map::entries}) #t80.{core::Map::[]=}(#t81.{core::MapEntry::key}, #t81.{core::MapEntry::value}); #t80.{core::Map::[]=}("baz", null); } =>#t80; core::List<core::List<core::int>> list60 = block { final core::List<core::List<core::int>> #t82 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::List<core::int> #t83 in <core::List<core::int>>[<core::int>[]]) #t82.{core::List::add}(#t83); } =>#t82; core::Set<core::List<core::int>> set60 = block { final core::Set<core::List<core::int>> #t84 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::List<core::int> #t85 in <core::List<core::int>>[<core::int>[]]) #t84.{core::Set::add}(#t85); #t84.{core::Set::add}(null); } =>#t84; core::Map<core::String, core::List<core::int>> map60 = block { final core::Map<core::String, core::List<core::int>> #t86 = <core::String, core::List<core::int>>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::MapEntry<core::String, core::List<core::int>> #t87 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) #t86.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value}); #t86.{core::Map::[]=}("baz", null); } =>#t86; core::List<core::List<core::int>> list61 = block { final core::List<core::List<core::int>> #t88 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::List<core::int> #t89 in <core::List<core::int>>[<core::int>[]]) #t88.{core::List::add}(#t89); } =>#t88; core::Set<core::List<core::int>> set61 = block { final core::Set<core::List<core::int>> #t90 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::List<core::int> #t91 in <core::List<core::int>>[<core::int>[]]) #t90.{core::Set::add}(#t91); #t90.{core::Set::add}(null); } =>#t90; core::Map<core::String, core::List<core::int>> map61 = block { final core::Map<core::String, core::List<core::int>> #t92 = <core::String, core::List<core::int>>{}; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::MapEntry<core::String, core::List<core::int>> #t93 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) #t92.{core::Map::[]=}(#t93.{core::MapEntry::key}, #t93.{core::MapEntry::value}); #t92.{core::Map::[]=}("baz", null); } =>#t92; core::List<core::List<core::int>> list70 = block { final core::List<core::List<core::int>> #t94 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t94.{core::List::add}(<core::int>[]); } =>#t94; core::Set<core::List<core::int>> set70 = block { final core::Set<core::List<core::int>> #t95 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t95.{core::Set::add}(<core::int>[]); #t95.{core::Set::add}(null); } =>#t95; core::List<core::List<core::int>> list71 = block { final core::List<core::List<core::int>> #t96 = <core::List<core::int>>[]; - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) #t96.{core::List::add}(<core::int>[]); } =>#t96; core::Set<core::List<core::int>> set71 = block { final core::Set<core::List<core::int>> #t97 = col::LinkedHashSet::•<core::List<core::int>>(); - if(self::oracle<core::String>("foo")) - if(self::oracle<dynamic>()) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + if(self::oracle<dynamic>() as{TypeError} core::bool) #t97.{core::Set::add}(<core::int>[]); #t97.{core::Set::add}(null); } =>#t97; core::List<core::num> list80 = block { final core::List<core::num> #t98 = <core::num>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t98.{core::List::add}(42); else #t98.{core::List::add}(3.14); } =>#t98; core::Set<core::num> set80 = block { final core::Set<core::num> #t99 = col::LinkedHashSet::•<core::num>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t99.{core::Set::add}(42); else #t99.{core::Set::add}(3.14); @@ -768,7 +867,7 @@ } =>#t99; core::Map<core::String, core::num> map80 = block { final core::Map<core::String, core::num> #t100 = <core::String, core::num>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t100.{core::Map::[]=}("bar", 42); else #t100.{core::Map::[]=}("bar", 3.14); @@ -776,7 +875,7 @@ } =>#t100; core::List<core::num> list81 = block { final core::List<core::num> #t101 = <core::num>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::num #t102 in listInt) #t101.{core::List::add}(#t102); else @@ -785,7 +884,7 @@ } =>#t101; core::Set<core::num> set81 = block { final core::Set<core::num> #t104 = col::LinkedHashSet::•<core::num>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::num #t105 in listInt) #t104.{core::Set::add}(#t105); else @@ -795,7 +894,7 @@ } =>#t104; core::Map<core::String, core::num> map81 = block { final core::Map<core::String, core::num> #t107 = <core::String, core::num>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::MapEntry<core::String, core::num> #t108 in mapToInt.{core::Map::entries}) #t107.{core::Map::[]=}(#t108.{core::MapEntry::key}, #t108.{core::MapEntry::value}); else @@ -805,7 +904,7 @@ } =>#t107; core::List<dynamic> list82 = block { final core::List<dynamic> #t110 = <dynamic>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final dynamic #t111 in listInt) #t110.{core::List::add}(#t111); else @@ -814,7 +913,7 @@ } =>#t110; core::Set<dynamic> set82 = block { final core::Set<dynamic> #t113 = col::LinkedHashSet::•<dynamic>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final dynamic #t114 in listInt) #t113.{core::Set::add}(#t114); else @@ -824,7 +923,7 @@ } =>#t113; core::Set<dynamic> map82 = block { final core::Set<dynamic> #t116 = col::LinkedHashSet::•<dynamic>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t116.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:71:38: Error: Unexpected type 'Map<String, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. var map82 = {if (oracle(\"foo\")) ...mapToInt else ...dynVar, null}; @@ -836,7 +935,7 @@ } =>#t116; core::List<core::num> list83 = block { final core::List<core::num> #t118 = <core::num>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t118.{core::List::add}(42); else for (final core::num #t119 in listDouble) @@ -844,7 +943,7 @@ } =>#t118; core::Set<core::num> set83 = block { final core::Set<core::num> #t120 = col::LinkedHashSet::•<core::num>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::num #t121 in listInt) #t120.{core::Set::add}(#t121); else @@ -853,7 +952,7 @@ } =>#t120; core::Map<core::String, core::num> map83 = block { final core::Map<core::String, core::num> #t122 = <core::String, core::num>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::MapEntry<core::String, core::num> #t123 in mapToInt.{core::Map::entries}) #t122.{core::Map::[]=}(#t123.{core::MapEntry::key}, #t123.{core::MapEntry::value}); else @@ -862,24 +961,24 @@ } =>#t122; core::List<core::int> list90 = block { final core::List<core::int> #t124 = <core::int>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t124.{core::List::add}(dynVar as{TypeError} core::int); } =>#t124; core::Set<core::int> set90 = block { final core::Set<core::int> #t125 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t125.{core::Set::add}(dynVar as{TypeError} core::int); #t125.{core::Set::add}(null); } =>#t125; core::Map<core::String, core::int> map90 = block { final core::Map<core::String, core::int> #t126 = <core::String, core::int>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) #t126.{core::Map::[]=}("bar", dynVar as{TypeError} core::int); #t126.{core::Map::[]=}("baz", null); } =>#t126; core::List<core::int> list91 = block { final core::List<core::int> #t127 = <core::int>[]; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final dynamic #t128 in dynVar as{TypeError} core::Iterable<dynamic>) { final core::int #t129 = #t128 as{TypeError} core::int; #t127.{core::List::add}(#t129); @@ -887,7 +986,7 @@ } =>#t127; core::Set<core::int> set91 = block { final core::Set<core::int> #t130 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final dynamic #t131 in dynVar as{TypeError} core::Iterable<dynamic>) { final core::int #t132 = #t131 as{TypeError} core::int; #t130.{core::Set::add}(#t132); @@ -896,7 +995,7 @@ } =>#t130; core::Map<core::String, core::int> map91 = block { final core::Map<core::String, core::int> #t133 = <core::String, core::int>{}; - if(self::oracle<core::String>("foo")) + if(self::oracle<core::String>("foo") as{TypeError} core::bool) for (final core::MapEntry<dynamic, dynamic> #t134 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) { final core::String #t135 = #t134.{core::MapEntry::key} as{TypeError} core::String; final core::int #t136 = #t134.{core::MapEntry::value} as{TypeError} core::int; @@ -904,719 +1003,886 @@ } #t133.{core::Map::[]=}("baz", null); } =>#t133; + core::List<core::int> list100 = block { + final core::List<core::int> #t137 = <core::int>[]; + if(dynVar as{TypeError} core::bool) + #t137.{core::List::add}(42); + } =>#t137; + core::Set<core::int> set100 = block { + final core::Set<core::int> #t138 = col::LinkedHashSet::•<core::int>(); + if(dynVar as{TypeError} core::bool) + #t138.{core::Set::add}(42); + } =>#t138; + core::Map<core::int, core::int> map100 = block { + final core::Map<core::int, core::int> #t139 = <core::int, core::int>{}; + if(dynVar as{TypeError} core::bool) + #t139.{core::Map::[]=}(42, 42); + } =>#t139; } static method testIfElementErrors(core::Map<core::int, core::int> map) → dynamic { - <core::int>[invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:84:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'. -Try changing the type of the left hand side, or casting the right hand side to 'int'. - <int>[if (oracle(\"foo\")) \"bar\"]; - ^"]; - let final core::Set<core::int> #t137 = col::LinkedHashSet::•<core::int>() in let final core::bool #t138 = #t137.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:85:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'. -Try changing the type of the left hand side, or casting the right hand side to 'int'. - <int>{if (oracle(\"foo\")) \"bar\", null}; - ^") in let final core::bool #t139 = #t137.{core::Set::add}(null) in #t137; - <core::String, core::int>{null: invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:86:41: Error: A value of type 'String' can't be assigned to a variable of type 'int'. -Try changing the type of the left hand side, or casting the right hand side to 'int'. - <String, int>{if (oracle(\"foo\")) \"bar\": \"bar\", \"baz\": null}; - ^", "baz": null}; block { final core::List<core::int> #t140 = <core::int>[]; - if(self::oracle<core::String>("foo")) - for (final core::int #t141 in <core::int>[let final<BottomType> #t142 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:87:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t140.{core::List::add}(let final<BottomType> #t141 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:87:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +Try changing the type of the left hand side, or casting the right hand side to 'int'. + <int>[if (oracle(\"foo\")) \"bar\"]; + ^" in "bar" as{TypeError} core::int); + } =>#t140; + block { + final core::Set<core::int> #t142 = col::LinkedHashSet::•<core::int>(); + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t142.{core::Set::add}(let final<BottomType> #t143 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:88:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +Try changing the type of the left hand side, or casting the right hand side to 'int'. + <int>{if (oracle(\"foo\")) \"bar\", null}; + ^" in "bar" as{TypeError} core::int); + #t142.{core::Set::add}(null); + } =>#t142; + block { + final core::Map<core::String, core::int> #t144 = <core::String, core::int>{}; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t144.{core::Map::[]=}("bar", let final<BottomType> #t145 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:89:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +Try changing the type of the left hand side, or casting the right hand side to 'int'. + <String, int>{if (oracle(\"foo\")) \"bar\": \"bar\", \"baz\": null}; + ^" in "bar" as{TypeError} core::int); + #t144.{core::Map::[]=}("baz", null); + } =>#t144; + block { + final core::List<core::int> #t146 = <core::int>[]; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + for (final core::int #t147 in <core::int>[let final<BottomType> #t148 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int>[if (oracle(\"foo\")) ...[\"bar\"]]; ^" in "bar" as{TypeError} core::int]) - #t140.{core::List::add}(#t141); - } =>#t140; + #t146.{core::List::add}(#t147); + } =>#t146; block { - final core::Set<core::int> #t143 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) - for (final core::int #t144 in <core::int>[let final<BottomType> #t145 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:88:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + final core::Set<core::int> #t149 = col::LinkedHashSet::•<core::int>(); + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + for (final core::int #t150 in <core::int>[let final<BottomType> #t151 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int>{if (oracle(\"foo\")) ...[\"bar\"], null}; ^" in "bar" as{TypeError} core::int]) - #t143.{core::Set::add}(#t144); - #t143.{core::Set::add}(null); - } =>#t143; + #t149.{core::Set::add}(#t150); + #t149.{core::Set::add}(null); + } =>#t149; block { - final core::Map<core::String, core::int> #t146 = <core::String, core::int>{}; - if(self::oracle<core::String>("foo")) - for (final core::MapEntry<core::String, core::int> #t147 in <core::String, core::int>{"bar": let final<BottomType> #t148 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:89:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + final core::Map<core::String, core::int> #t152 = <core::String, core::int>{}; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + for (final core::MapEntry<core::String, core::int> #t153 in <core::String, core::int>{"bar": let final<BottomType> #t154 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <String, int>{if (oracle(\"foo\")) ...{\"bar\": \"bar\"}, \"baz\": null}; ^" in "bar" as{TypeError} core::int}.{core::Map::entries}) - #t146.{core::Map::[]=}(#t147.{core::MapEntry::key}, #t147.{core::MapEntry::value}); - #t146.{core::Map::[]=}("baz", null); - } =>#t146; + #t152.{core::Map::[]=}(#t153.{core::MapEntry::key}, #t153.{core::MapEntry::value}); + #t152.{core::Map::[]=}("baz", null); + } =>#t152; block { - final core::List<core::int> #t149 = <core::int>[]; - if(self::oracle<core::String>("foo")) - #t149.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:90:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + final core::List<core::int> #t155 = <core::int>[]; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t155.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:93:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>[if (oracle(\"foo\")) ...map]; - ^" as{TypeError} core::int); - } =>#t149; + ^"); + } =>#t155; block { - final core::Set<core::int> #t150 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) - #t150.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:91:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + final core::Set<core::int> #t156 = col::LinkedHashSet::•<core::int>(); + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t156.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:94:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>{if (oracle(\"foo\")) ...map, null}; - ^" as{TypeError} core::int); - #t150.{core::Set::add}(null); - } =>#t150; - <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:92:39: Error: Unexpected type 'List<String>' of a map spread entry. Expected 'dynamic' or a Map. + ^"); + #t156.{core::Set::add}(null); + } =>#t156; + <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:95:39: Error: Unexpected type 'List<String>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{if (oracle(\"foo\")) ...[\"bar\"], \"baz\": null}; - ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:92:39: Error: Unexpected type 'List<String>' of a map spread entry. Expected 'dynamic' or a Map. + ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:95:39: Error: Unexpected type 'List<String>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{if (oracle(\"foo\")) ...[\"bar\"], \"baz\": null}; ^": null}; - <core::String>[invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:93:12: Error: A value of type 'num' can't be assigned to a variable of type 'String'. + block { + final core::List<core::String> #t157 = <core::String>[]; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t157.{core::List::add}(let final<BottomType> #t158 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:96:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'. Try changing the type of the left hand side, or casting the right hand side to 'String'. <String>[if (oracle(\"foo\")) 42 else 3.14]; - ^"]; - let final core::Set<core::String> #t151 = col::LinkedHashSet::•<core::String>() in let final core::bool #t152 = #t151.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:94:12: Error: A value of type 'num' can't be assigned to a variable of type 'String'. + ^" in 42 as{TypeError} core::String); + else + #t157.{core::List::add}(let final<BottomType> #t159 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:96:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + <String>[if (oracle(\"foo\")) 42 else 3.14]; + ^" in 3.14 as{TypeError} core::String); + } =>#t157; + block { + final core::Set<core::String> #t160 = col::LinkedHashSet::•<core::String>(); + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t160.{core::Set::add}(let final<BottomType> #t161 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:97:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'. Try changing the type of the left hand side, or casting the right hand side to 'String'. <String>{if (oracle(\"foo\")) 42 else 3.14, null}; - ^") in let final core::bool #t153 = #t151.{core::Set::add}(null) in #t151; - <core::String, core::String>{null: invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:95:20: Error: A value of type 'num' can't be assigned to a variable of type 'String'. + ^" in 42 as{TypeError} core::String); + else + #t160.{core::Set::add}(let final<BottomType> #t162 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:97:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + <String>{if (oracle(\"foo\")) 42 else 3.14, null}; + ^" in 3.14 as{TypeError} core::String); + #t160.{core::Set::add}(null); + } =>#t160; + block { + final core::Map<core::String, core::String> #t163 = <core::String, core::String>{}; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t163.{core::Map::[]=}("bar", let final<BottomType> #t164 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:98:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'. Try changing the type of the left hand side, or casting the right hand side to 'String'. <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null}; - ^", "baz": null}; + ^" in 42 as{TypeError} core::String); + else + #t163.{core::Map::[]=}("baz", let final<BottomType> #t165 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:98:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null}; + ^" in 3.14 as{TypeError} core::String); + #t163.{core::Map::[]=}("baz", null); + } =>#t163; block { - final core::List<core::int> #t154 = <core::int>[]; - if(self::oracle<core::String>("foo")) - #t154.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:96:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + final core::List<core::int> #t166 = <core::int>[]; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t166.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:99:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>[if (oracle(\"foo\")) ...map else 42]; - ^" as{TypeError} core::int); + ^"); else - #t154.{core::List::add}(42 as{TypeError} core::int); - } =>#t154; + #t166.{core::List::add}(42); + } =>#t166; block { - final core::Set<core::int> #t155 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) - #t155.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:97:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + final core::Set<core::int> #t167 = col::LinkedHashSet::•<core::int>(); + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t167.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:100:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>{if (oracle(\"foo\")) ...map else 42, null}; - ^" as{TypeError} core::int); + ^"); else - #t155.{core::Set::add}(42 as{TypeError} core::int); - #t155.{core::Set::add}(null); - } =>#t155; - <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:98:39: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + #t167.{core::Set::add}(42); + #t167.{core::Set::add}(null); + } =>#t167; + <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:101:39: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{if (oracle(\"foo\")) ...[42] else \"bar\": 42, \"baz\": null}; - ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:98:39: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:101:39: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{if (oracle(\"foo\")) ...[42] else \"bar\": 42, \"baz\": null}; ^": null}; block { - final core::List<core::int> #t156 = <core::int>[]; - if(self::oracle<core::String>("foo")) - #t156.{core::List::add}(42 as{TypeError} core::int); + final core::List<core::int> #t168 = <core::int>[]; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t168.{core::List::add}(42); else - #t156.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:99:39: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + #t168.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:102:39: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>[if (oracle(\"foo\")) 42 else ...map]; - ^" as{TypeError} core::int); - } =>#t156; + ^"); + } =>#t168; block { - final core::Set<core::int> #t157 = col::LinkedHashSet::•<core::int>(); - if(self::oracle<core::String>("foo")) - #t157.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:100:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + final core::Set<core::int> #t169 = col::LinkedHashSet::•<core::int>(); + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t169.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:103:31: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>{if (oracle(\"foo\")) ...map else 42, null}; - ^" as{TypeError} core::int); + ^"); else - #t157.{core::Set::add}(42 as{TypeError} core::int); - #t157.{core::Set::add}(null); - } =>#t157; - <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:101:54: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + #t169.{core::Set::add}(42); + #t169.{core::Set::add}(null); + } =>#t169; + <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:104:54: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{if (oracle(\"foo\")) \"bar\": 42 else ...[42], \"baz\": null}; - ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:101:54: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:104:54: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{if (oracle(\"foo\")) \"bar\": 42 else ...[42], \"baz\": null}; ^": null}; + core::Set<dynamic> set10 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:106:24: Error: Both Iterable and Map spread elements encountered in ambiguous literal. + Set<dynamic> set10 = {if (oracle(\"foo\")) 42 else \"bar\": 3.14}; + ^"; + core::Map<dynamic, dynamic> map10 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:107:53: Error: Expected ':' after this. + Map<dynamic, dynamic> map10 = {if (oracle(\"foo\")) 42 else \"bar\": 3.14}; + ^": null}; + core::Set<dynamic> set11 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:108:24: Error: Both Iterable and Map spread elements encountered in ambiguous literal. + Set<dynamic> set11 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42}; + ^"; + core::Map<dynamic, dynamic> map11 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:109:70: Error: Expected ':' after this. + Map<dynamic, dynamic> map11 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42}; + ^": null}; + core::Map<<BottomType>, core::Null> map12 = <<BottomType>, core::Null>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:110:35: Error: Expected ':' after this. + var map12 = {if (oracle(\"foo\")) 42 else \"bar\": 3.14}; + ^": null}; + core::Map<<BottomType>, core::Null> map13 = <<BottomType>, core::Null>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:111:52: Error: Expected ':' after this. + var map13 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42}; + ^": null}; + core::List<core::int> list20 = block { + final core::List<core::int> #t170 = <core::int>[]; + if(let final<BottomType> #t171 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:112:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'. +Try changing the type of the left hand side, or casting the right hand side to 'bool'. + List<int> list20 = [if (42) 42]; + ^" in 42 as{TypeError} core::bool) + #t170.{core::List::add}(42); + } =>#t170; + core::Set<core::int> set20 = block { + final core::Set<core::int> #t172 = col::LinkedHashSet::•<core::int>(); + if(let final<BottomType> #t173 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'. +Try changing the type of the left hand side, or casting the right hand side to 'bool'. + Set<int> set20 = {if (42) 42}; + ^" in 42 as{TypeError} core::bool) + #t172.{core::Set::add}(42); + } =>#t172; + core::Map<core::int, core::int> map30 = block { + final core::Map<core::int, core::int> #t174 = <core::int, core::int>{}; + if(let final<BottomType> #t175 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:114:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'. +Try changing the type of the left hand side, or casting the right hand side to 'bool'. + Map<int, int> map30 = {if (42) 42: 42}; + ^" in 42 as{TypeError} core::bool) + #t174.{core::Map::[]=}(42, 42); + } =>#t174; + core::List<core::String> list40 = block { + final core::List<core::String> #t176 = <core::String>[]; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t176.{core::List::add}(let final<BottomType> #t177 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:115:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + List<String> list40 = <String>[if (oracle(\"foo\")) true else 42]; + ^" in true as{TypeError} core::String); + else + #t176.{core::List::add}(let final<BottomType> #t178 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:115:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + List<String> list40 = <String>[if (oracle(\"foo\")) true else 42]; + ^" in 42 as{TypeError} core::String); + } =>#t176; + core::Set<core::String> set40 = block { + final core::Set<core::String> #t179 = col::LinkedHashSet::•<core::String>(); + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t179.{core::Set::add}(let final<BottomType> #t180 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42}; + ^" in true as{TypeError} core::String); + else + #t179.{core::Set::add}(let final<BottomType> #t181 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:116:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42}; + ^" in 42 as{TypeError} core::String); + } =>#t179; + core::Map<core::String, core::int> map40 = block { + final core::Map<core::String, core::int> #t182 = <core::String, core::int>{}; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t182.{core::Map::[]=}(let final<BottomType> #t183 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:117:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42}; + ^" in true as{TypeError} core::String, 42); + else + #t182.{core::Map::[]=}(let final<BottomType> #t184 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:117:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42}; + ^" in 42 as{TypeError} core::String, 42); + } =>#t182; + core::Map<core::int, core::String> map41 = block { + final core::Map<core::int, core::String> #t185 = <core::int, core::String>{}; + if(self::oracle<core::String>("foo") as{TypeError} core::bool) + #t185.{core::Map::[]=}(42, let final<BottomType> #t186 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:118:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42}; + ^" in true as{TypeError} core::String); + else + #t185.{core::Map::[]=}(42, let final<BottomType> #t187 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:118:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42}; + ^" in 42 as{TypeError} core::String); + } =>#t185; } static method testForElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::int index, core::Map<core::String, core::int> mapStringInt, core::Map<core::String, core::double> mapStringDouble) → dynamic { core::List<core::int> list10 = block { - final core::List<core::int> #t158 = <core::int>[]; + final core::List<core::int> #t188 = <core::int>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t158.{core::List::add}(42); - } =>#t158; + #t188.{core::List::add}(42); + } =>#t188; core::Set<core::int> set10 = block { - final core::Set<core::int> #t159 = col::LinkedHashSet::•<core::int>(); + final core::Set<core::int> #t189 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t159.{core::Set::add}(42); - #t159.{core::Set::add}(null); - } =>#t159; - core::Map<core::String, core::int> map10 = block { - final core::Map<core::String, core::int> #t160 = <core::String, core::int>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t160.{core::Map::[]=}("bar", 42); - #t160.{core::Map::[]=}("baz", null); - } =>#t160; - core::List<dynamic> list11 = block { - final core::List<dynamic> #t161 = <dynamic>[]; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t161.{core::List::add}(dynVar); - } =>#t161; - core::Set<dynamic> set11 = block { - final core::Set<dynamic> #t162 = col::LinkedHashSet::•<dynamic>(); - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t162.{core::Set::add}(dynVar); - #t162.{core::Set::add}(null); - } =>#t162; - core::Map<core::String, dynamic> map11 = block { - final core::Map<core::String, dynamic> #t163 = <core::String, dynamic>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t163.{core::Map::[]=}("bar", dynVar); - #t163.{core::Map::[]=}("baz", null); - } =>#t163; - core::List<core::List<core::int>> list12 = block { - final core::List<core::List<core::int>> #t164 = <core::List<core::int>>[]; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t164.{core::List::add}(<core::int>[42]); - } =>#t164; - core::Set<core::List<core::int>> set12 = block { - final core::Set<core::List<core::int>> #t165 = col::LinkedHashSet::•<core::List<core::int>>(); - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t165.{core::Set::add}(<core::int>[42]); - #t165.{core::Set::add}(null); - } =>#t165; - core::Map<core::String, core::List<core::int>> map12 = block { - final core::Map<core::String, core::List<core::int>> #t166 = <core::String, core::List<core::int>>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t166.{core::Map::[]=}("bar", <core::int>[42]); - #t166.{core::Map::[]=}("baz", null); - } =>#t166; - core::List<core::int> list20 = block { - final core::List<core::int> #t167 = <core::int>[]; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::int #t168 in <core::int>[42]) - #t167.{core::List::add}(#t168); - } =>#t167; - core::Set<core::int> set20 = block { - final core::Set<core::int> #t169 = col::LinkedHashSet::•<core::int>(); - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::int #t170 in <core::int>[42]) - #t169.{core::Set::add}(#t170); - #t169.{core::Set::add}(null); - } =>#t169; - core::Map<core::String, core::int> map20 = block { - final core::Map<core::String, core::int> #t171 = <core::String, core::int>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::MapEntry<core::String, core::int> #t172 in <core::String, core::int>{"bar": 42}.{core::Map::entries}) - #t171.{core::Map::[]=}(#t172.{core::MapEntry::key}, #t172.{core::MapEntry::value}); - #t171.{core::Map::[]=}("baz", null); - } =>#t171; - core::List<dynamic> list21 = block { - final core::List<dynamic> #t173 = <dynamic>[]; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final dynamic #t174 in <dynamic>[dynVar]) - #t173.{core::List::add}(#t174); - } =>#t173; - core::Set<dynamic> set21 = block { - final core::Set<dynamic> #t175 = col::LinkedHashSet::•<dynamic>(); - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final dynamic #t176 in <dynamic>[dynVar]) - #t175.{core::Set::add}(#t176); - #t175.{core::Set::add}(null); - } =>#t175; - core::Map<core::String, dynamic> map21 = block { - final core::Map<core::String, dynamic> #t177 = <core::String, dynamic>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::MapEntry<core::String, dynamic> #t178 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries}) - #t177.{core::Map::[]=}(#t178.{core::MapEntry::key}, #t178.{core::MapEntry::value}); - #t177.{core::Map::[]=}("baz", null); - } =>#t177; - core::List<core::List<core::int>> list22 = block { - final core::List<core::List<core::int>> #t179 = <core::List<core::int>>[]; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::List<core::int> #t180 in <core::List<core::int>>[<core::int>[42]]) - #t179.{core::List::add}(#t180); - } =>#t179; - core::Set<core::List<core::int>> set22 = block { - final core::Set<core::List<core::int>> #t181 = col::LinkedHashSet::•<core::List<core::int>>(); - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::List<core::int> #t182 in <core::List<core::int>>[<core::int>[42]]) - #t181.{core::Set::add}(#t182); - #t181.{core::Set::add}(null); - } =>#t181; - core::Map<core::String, core::List<core::int>> map22 = block { - final core::Map<core::String, core::List<core::int>> #t183 = <core::String, core::List<core::int>>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::MapEntry<core::String, core::List<core::int>> #t184 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries}) - #t183.{core::Map::[]=}(#t184.{core::MapEntry::key}, #t184.{core::MapEntry::value}); - #t183.{core::Map::[]=}("baz", null); - } =>#t183; - core::List<core::int> list30 = block { - final core::List<core::int> #t185 = <core::int>[]; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::int #t186 in <core::int>[42]) - #t185.{core::List::add}(#t186); - } =>#t185; - core::Set<core::int> set30 = block { - final core::Set<core::int> #t187 = col::LinkedHashSet::•<core::int>(); - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::int #t188 in <core::int>[42]) - #t187.{core::Set::add}(#t188); - #t187.{core::Set::add}(null); - } =>#t187; - core::Map<core::String, core::int> map30 = block { - final core::Map<core::String, core::int> #t189 = <core::String, core::int>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::MapEntry<core::String, core::int> #t190 in <core::String, core::int>{"bar": 42}.{core::Map::entries}) - #t189.{core::Map::[]=}(#t190.{core::MapEntry::key}, #t190.{core::MapEntry::value}); - #t189.{core::Map::[]=}("baz", null); + #t189.{core::Set::add}(42); + #t189.{core::Set::add}(null); } =>#t189; - core::List<dynamic> list31 = block { + core::Map<core::String, core::int> map10 = block { + final core::Map<core::String, core::int> #t190 = <core::String, core::int>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t190.{core::Map::[]=}("bar", 42); + #t190.{core::Map::[]=}("baz", null); + } =>#t190; + core::List<dynamic> list11 = block { final core::List<dynamic> #t191 = <dynamic>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final dynamic #t192 in <dynamic>[dynVar]) - #t191.{core::List::add}(#t192); + #t191.{core::List::add}(dynVar); } =>#t191; - core::Set<dynamic> set31 = block { - final core::Set<dynamic> #t193 = col::LinkedHashSet::•<dynamic>(); + core::Set<dynamic> set11 = block { + final core::Set<dynamic> #t192 = col::LinkedHashSet::•<dynamic>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final dynamic #t194 in <dynamic>[dynVar]) - #t193.{core::Set::add}(#t194); - #t193.{core::Set::add}(null); + #t192.{core::Set::add}(dynVar); + #t192.{core::Set::add}(null); + } =>#t192; + core::Map<core::String, dynamic> map11 = block { + final core::Map<core::String, dynamic> #t193 = <core::String, dynamic>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t193.{core::Map::[]=}("bar", dynVar); + #t193.{core::Map::[]=}("baz", null); } =>#t193; - core::Map<core::String, dynamic> map31 = block { - final core::Map<core::String, dynamic> #t195 = <core::String, dynamic>{}; + core::List<core::List<core::int>> list12 = block { + final core::List<core::List<core::int>> #t194 = <core::List<core::int>>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::MapEntry<core::String, dynamic> #t196 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries}) - #t195.{core::Map::[]=}(#t196.{core::MapEntry::key}, #t196.{core::MapEntry::value}); - #t195.{core::Map::[]=}("baz", null); + #t194.{core::List::add}(<core::int>[42]); + } =>#t194; + core::Set<core::List<core::int>> set12 = block { + final core::Set<core::List<core::int>> #t195 = col::LinkedHashSet::•<core::List<core::int>>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t195.{core::Set::add}(<core::int>[42]); + #t195.{core::Set::add}(null); } =>#t195; - core::List<core::List<core::int>> list33 = block { - final core::List<core::List<core::int>> #t197 = <core::List<core::int>>[]; + core::Map<core::String, core::List<core::int>> map12 = block { + final core::Map<core::String, core::List<core::int>> #t196 = <core::String, core::List<core::int>>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::List<core::int> #t198 in <core::List<core::int>>[<core::int>[42]]) - #t197.{core::List::add}(#t198); + #t196.{core::Map::[]=}("bar", <core::int>[42]); + #t196.{core::Map::[]=}("baz", null); + } =>#t196; + core::List<core::int> list20 = block { + final core::List<core::int> #t197 = <core::int>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + for (final core::int #t198 in <core::int>[42]) + #t197.{core::List::add}(#t198); } =>#t197; - core::Set<core::List<core::int>> set33 = block { - final core::Set<core::List<core::int>> #t199 = col::LinkedHashSet::•<core::List<core::int>>(); + core::Set<core::int> set20 = block { + final core::Set<core::int> #t199 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::List<core::int> #t200 in <core::List<core::int>>[<core::int>[42]]) - #t199.{core::Set::add}(#t200); + for (final core::int #t200 in <core::int>[42]) + #t199.{core::Set::add}(#t200); #t199.{core::Set::add}(null); } =>#t199; - core::Map<core::String, core::List<core::int>> map33 = block { - final core::Map<core::String, core::List<core::int>> #t201 = <core::String, core::List<core::int>>{}; + core::Map<core::String, core::int> map20 = block { + final core::Map<core::String, core::int> #t201 = <core::String, core::int>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::MapEntry<core::String, core::List<core::int>> #t202 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries}) - #t201.{core::Map::[]=}(#t202.{core::MapEntry::key}, #t202.{core::MapEntry::value}); + for (final core::MapEntry<core::String, core::int> #t202 in <core::String, core::int>{"bar": 42}.{core::Map::entries}) + #t201.{core::Map::[]=}(#t202.{core::MapEntry::key}, #t202.{core::MapEntry::value}); #t201.{core::Map::[]=}("baz", null); } =>#t201; - core::List<core::List<core::int>> list40 = block { - final core::List<core::List<core::int>> #t203 = <core::List<core::int>>[]; + core::List<dynamic> list21 = block { + final core::List<dynamic> #t203 = <dynamic>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::List<core::int> #t204 in <core::List<core::int>>[<core::int>[]]) + for (final dynamic #t204 in <dynamic>[dynVar]) #t203.{core::List::add}(#t204); } =>#t203; - core::Set<core::List<core::int>> set40 = block { - final core::Set<core::List<core::int>> #t205 = col::LinkedHashSet::•<core::List<core::int>>(); + core::Set<dynamic> set21 = block { + final core::Set<dynamic> #t205 = col::LinkedHashSet::•<dynamic>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::List<core::int> #t206 in <core::List<core::int>>[<core::int>[]]) + for (final dynamic #t206 in <dynamic>[dynVar]) #t205.{core::Set::add}(#t206); #t205.{core::Set::add}(null); } =>#t205; - core::Map<core::String, core::List<core::int>> map40 = block { - final core::Map<core::String, core::List<core::int>> #t207 = <core::String, core::List<core::int>>{}; + core::Map<core::String, dynamic> map21 = block { + final core::Map<core::String, dynamic> #t207 = <core::String, dynamic>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::MapEntry<core::String, core::List<core::int>> #t208 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) + for (final core::MapEntry<core::String, dynamic> #t208 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries}) #t207.{core::Map::[]=}(#t208.{core::MapEntry::key}, #t208.{core::MapEntry::value}); #t207.{core::Map::[]=}("baz", null); } =>#t207; - core::List<core::List<core::int>> list41 = block { + core::List<core::List<core::int>> list22 = block { final core::List<core::List<core::int>> #t209 = <core::List<core::int>>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::List<core::int> #t210 in let final core::Set<core::List<core::int>> #t211 = col::LinkedHashSet::•<core::List<core::int>>() in let final core::bool #t212 = #t211.{core::Set::add}(<core::int>[]) in #t211) + for (final core::List<core::int> #t210 in <core::List<core::int>>[<core::int>[42]]) #t209.{core::List::add}(#t210); } =>#t209; - core::Set<core::List<core::int>> set41 = block { - final core::Set<core::List<core::int>> #t213 = col::LinkedHashSet::•<core::List<core::int>>(); + core::Set<core::List<core::int>> set22 = block { + final core::Set<core::List<core::int>> #t211 = col::LinkedHashSet::•<core::List<core::int>>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::List<core::int> #t214 in let final core::Set<core::List<core::int>> #t215 = col::LinkedHashSet::•<core::List<core::int>>() in let final core::bool #t216 = #t215.{core::Set::add}(<core::int>[]) in #t215) - #t213.{core::Set::add}(#t214); - #t213.{core::Set::add}(null); + for (final core::List<core::int> #t212 in <core::List<core::int>>[<core::int>[42]]) + #t211.{core::Set::add}(#t212); + #t211.{core::Set::add}(null); + } =>#t211; + core::Map<core::String, core::List<core::int>> map22 = block { + final core::Map<core::String, core::List<core::int>> #t213 = <core::String, core::List<core::int>>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + for (final core::MapEntry<core::String, core::List<core::int>> #t214 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries}) + #t213.{core::Map::[]=}(#t214.{core::MapEntry::key}, #t214.{core::MapEntry::value}); + #t213.{core::Map::[]=}("baz", null); } =>#t213; - core::List<core::List<core::int>> list42 = block { - final core::List<core::List<core::int>> #t217 = <core::List<core::int>>[]; + core::List<core::int> list30 = block { + final core::List<core::int> #t215 = <core::int>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::List<core::int> #t218 in <core::List<core::int>>[<core::int>[]]) - #t217.{core::List::add}(#t218); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::int #t216 in <core::int>[42]) + #t215.{core::List::add}(#t216); + } =>#t215; + core::Set<core::int> set30 = block { + final core::Set<core::int> #t217 = col::LinkedHashSet::•<core::int>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::int #t218 in <core::int>[42]) + #t217.{core::Set::add}(#t218); + #t217.{core::Set::add}(null); } =>#t217; - core::Set<core::List<core::int>> set42 = block { - final core::Set<core::List<core::int>> #t219 = col::LinkedHashSet::•<core::List<core::int>>(); + core::Map<core::String, core::int> map30 = block { + final core::Map<core::String, core::int> #t219 = <core::String, core::int>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::List<core::int> #t220 in <core::List<core::int>>[<core::int>[]]) - #t219.{core::Set::add}(#t220); - #t219.{core::Set::add}(null); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::MapEntry<core::String, core::int> #t220 in <core::String, core::int>{"bar": 42}.{core::Map::entries}) + #t219.{core::Map::[]=}(#t220.{core::MapEntry::key}, #t220.{core::MapEntry::value}); + #t219.{core::Map::[]=}("baz", null); } =>#t219; - core::Map<core::String, core::List<core::int>> map42 = block { - final core::Map<core::String, core::List<core::int>> #t221 = <core::String, core::List<core::int>>{}; + core::List<dynamic> list31 = block { + final core::List<dynamic> #t221 = <dynamic>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::MapEntry<core::String, core::List<core::int>> #t222 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) - #t221.{core::Map::[]=}(#t222.{core::MapEntry::key}, #t222.{core::MapEntry::value}); - #t221.{core::Map::[]=}("baz", null); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final dynamic #t222 in <dynamic>[dynVar]) + #t221.{core::List::add}(#t222); } =>#t221; - core::List<core::int> list50 = block { - final core::List<core::int> #t223 = <core::int>[]; + core::Set<dynamic> set31 = block { + final core::Set<dynamic> #t223 = col::LinkedHashSet::•<dynamic>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::int #t224 in <core::int>[]) - #t223.{core::List::add}(#t224); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final dynamic #t224 in <dynamic>[dynVar]) + #t223.{core::Set::add}(#t224); + #t223.{core::Set::add}(null); } =>#t223; - core::Set<core::int> set50 = block { - final core::Set<core::int> #t225 = col::LinkedHashSet::•<core::int>(); + core::Map<core::String, dynamic> map31 = block { + final core::Map<core::String, dynamic> #t225 = <core::String, dynamic>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::int #t226 in <core::int>[]) - #t225.{core::Set::add}(#t226); - #t225.{core::Set::add}(null); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::MapEntry<core::String, dynamic> #t226 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries}) + #t225.{core::Map::[]=}(#t226.{core::MapEntry::key}, #t226.{core::MapEntry::value}); + #t225.{core::Map::[]=}("baz", null); } =>#t225; - core::Map<core::String, core::int> map50 = block { - final core::Map<core::String, core::int> #t227 = <core::String, core::int>{}; + core::List<core::List<core::int>> list33 = block { + final core::List<core::List<core::int>> #t227 = <core::List<core::int>>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::MapEntry<core::String, core::int> #t228 in <core::String, core::int>{}.{core::Map::entries}) - #t227.{core::Map::[]=}(#t228.{core::MapEntry::key}, #t228.{core::MapEntry::value}); - #t227.{core::Map::[]=}("baz", null); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::List<core::int> #t228 in <core::List<core::int>>[<core::int>[42]]) + #t227.{core::List::add}(#t228); } =>#t227; - core::List<core::int> list51 = block { - final core::List<core::int> #t229 = <core::int>[]; + core::Set<core::List<core::int>> set33 = block { + final core::Set<core::List<core::int>> #t229 = col::LinkedHashSet::•<core::List<core::int>>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::int #t230 in let final core::Set<core::int> #t231 = col::LinkedHashSet::•<core::int>() in #t231) - #t229.{core::List::add}(#t230); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::List<core::int> #t230 in <core::List<core::int>>[<core::int>[42]]) + #t229.{core::Set::add}(#t230); + #t229.{core::Set::add}(null); } =>#t229; - core::Set<core::int> set51 = block { - final core::Set<core::int> #t232 = col::LinkedHashSet::•<core::int>(); + core::Map<core::String, core::List<core::int>> map33 = block { + final core::Map<core::String, core::List<core::int>> #t231 = <core::String, core::List<core::int>>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::int #t233 in let final core::Set<core::int> #t234 = col::LinkedHashSet::•<core::int>() in #t234) - #t232.{core::Set::add}(#t233); - #t232.{core::Set::add}(null); - } =>#t232; - core::List<core::int> list52 = block { - final core::List<core::int> #t235 = <core::int>[]; + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::MapEntry<core::String, core::List<core::int>> #t232 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries}) + #t231.{core::Map::[]=}(#t232.{core::MapEntry::key}, #t232.{core::MapEntry::value}); + #t231.{core::Map::[]=}("baz", null); + } =>#t231; + core::List<core::List<core::int>> list40 = block { + final core::List<core::List<core::int>> #t233 = <core::List<core::int>>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::int #t236 in <core::int>[]) - #t235.{core::List::add}(#t236); + for (final core::List<core::int> #t234 in <core::List<core::int>>[<core::int>[]]) + #t233.{core::List::add}(#t234); + } =>#t233; + core::Set<core::List<core::int>> set40 = block { + final core::Set<core::List<core::int>> #t235 = col::LinkedHashSet::•<core::List<core::int>>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + for (final core::List<core::int> #t236 in <core::List<core::int>>[<core::int>[]]) + #t235.{core::Set::add}(#t236); + #t235.{core::Set::add}(null); } =>#t235; - core::Set<core::int> set52 = block { - final core::Set<core::int> #t237 = col::LinkedHashSet::•<core::int>(); + core::Map<core::String, core::List<core::int>> map40 = block { + final core::Map<core::String, core::List<core::int>> #t237 = <core::String, core::List<core::int>>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::int #t238 in <core::int>[]) - #t237.{core::Set::add}(#t238); - #t237.{core::Set::add}(null); + for (final core::MapEntry<core::String, core::List<core::int>> #t238 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) + #t237.{core::Map::[]=}(#t238.{core::MapEntry::key}, #t238.{core::MapEntry::value}); + #t237.{core::Map::[]=}("baz", null); } =>#t237; - core::List<core::List<core::int>> list60 = block { + core::List<core::List<core::int>> list41 = block { final core::List<core::List<core::int>> #t239 = <core::List<core::int>>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::List<core::int> #t240 in <core::List<core::int>>[<core::int>[]]) + for (final core::List<core::int> #t240 in let final core::Set<core::List<core::int>> #t241 = col::LinkedHashSet::•<core::List<core::int>>() in let final core::bool #t242 = #t241.{core::Set::add}(<core::int>[]) in #t241) #t239.{core::List::add}(#t240); } =>#t239; - core::Set<core::List<core::int>> set60 = block { - final core::Set<core::List<core::int>> #t241 = col::LinkedHashSet::•<core::List<core::int>>(); + core::Set<core::List<core::int>> set41 = block { + final core::Set<core::List<core::int>> #t243 = col::LinkedHashSet::•<core::List<core::int>>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::List<core::int> #t242 in <core::List<core::int>>[<core::int>[]]) - #t241.{core::Set::add}(#t242); - #t241.{core::Set::add}(null); - } =>#t241; - core::Map<core::String, core::List<core::int>> map60 = block { - final core::Map<core::String, core::List<core::int>> #t243 = <core::String, core::List<core::int>>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::MapEntry<core::String, core::List<core::int>> #t244 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) - #t243.{core::Map::[]=}(#t244.{core::MapEntry::key}, #t244.{core::MapEntry::value}); - #t243.{core::Map::[]=}("baz", null); + for (final core::List<core::int> #t244 in let final core::Set<core::List<core::int>> #t245 = col::LinkedHashSet::•<core::List<core::int>>() in let final core::bool #t246 = #t245.{core::Set::add}(<core::int>[]) in #t245) + #t243.{core::Set::add}(#t244); + #t243.{core::Set::add}(null); } =>#t243; - core::List<core::List<core::int>> list61 = block { - final core::List<core::List<core::int>> #t245 = <core::List<core::int>>[]; + core::List<core::List<core::int>> list42 = block { + final core::List<core::List<core::int>> #t247 = <core::List<core::int>>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::List<core::int> #t246 in <core::List<core::int>>[<core::int>[]]) - #t245.{core::List::add}(#t246); - } =>#t245; - core::Set<core::List<core::int>> set61 = block { - final core::Set<core::List<core::int>> #t247 = col::LinkedHashSet::•<core::List<core::int>>(); - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) + if(self::oracle<dynamic>() as{TypeError} core::bool) for (final core::List<core::int> #t248 in <core::List<core::int>>[<core::int>[]]) - #t247.{core::Set::add}(#t248); - #t247.{core::Set::add}(null); + #t247.{core::List::add}(#t248); } =>#t247; - core::Map<core::String, core::List<core::int>> map61 = block { - final core::Map<core::String, core::List<core::int>> #t249 = <core::String, core::List<core::int>>{}; + core::Set<core::List<core::int>> set42 = block { + final core::Set<core::List<core::int>> #t249 = col::LinkedHashSet::•<core::List<core::int>>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::MapEntry<core::String, core::List<core::int>> #t250 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) - #t249.{core::Map::[]=}(#t250.{core::MapEntry::key}, #t250.{core::MapEntry::value}); - #t249.{core::Map::[]=}("baz", null); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::List<core::int> #t250 in <core::List<core::int>>[<core::int>[]]) + #t249.{core::Set::add}(#t250); + #t249.{core::Set::add}(null); } =>#t249; - core::List<core::List<core::int>> list70 = block { - final core::List<core::List<core::int>> #t251 = <core::List<core::int>>[]; + core::Map<core::String, core::List<core::int>> map42 = block { + final core::Map<core::String, core::List<core::int>> #t251 = <core::String, core::List<core::int>>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t251.{core::List::add}(<core::int>[]); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::MapEntry<core::String, core::List<core::int>> #t252 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) + #t251.{core::Map::[]=}(#t252.{core::MapEntry::key}, #t252.{core::MapEntry::value}); + #t251.{core::Map::[]=}("baz", null); } =>#t251; - core::Set<core::List<core::int>> set70 = block { - final core::Set<core::List<core::int>> #t252 = col::LinkedHashSet::•<core::List<core::int>>(); + core::List<core::int> list50 = block { + final core::List<core::int> #t253 = <core::int>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t252.{core::Set::add}(<core::int>[]); - #t252.{core::Set::add}(null); - } =>#t252; - core::Map<core::String, core::List<core::int>> map70 = block { - final core::Map<core::String, core::List<core::int>> #t253 = <core::String, core::List<core::int>>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t253.{core::Map::[]=}("bar", <core::int>[]); - #t253.{core::Map::[]=}("baz", null); + for (final core::int #t254 in <core::int>[]) + #t253.{core::List::add}(#t254); } =>#t253; - core::List<core::List<core::int>> list71 = block { - final core::List<core::List<core::int>> #t254 = <core::List<core::int>>[]; + core::Set<core::int> set50 = block { + final core::Set<core::int> #t255 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t254.{core::List::add}(<core::int>[]); - } =>#t254; - core::Set<core::List<core::int>> set71 = block { - final core::Set<core::List<core::int>> #t255 = col::LinkedHashSet::•<core::List<core::int>>(); - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t255.{core::Set::add}(<core::int>[]); + for (final core::int #t256 in <core::int>[]) + #t255.{core::Set::add}(#t256); #t255.{core::Set::add}(null); } =>#t255; - core::Map<core::String, core::List<core::int>> map71 = block { - final core::Map<core::String, core::List<core::int>> #t256 = <core::String, core::List<core::int>>{}; + core::Map<core::String, core::int> map50 = block { + final core::Map<core::String, core::int> #t257 = <core::String, core::int>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t256.{core::Map::[]=}("bar", <core::int>[]); - #t256.{core::Map::[]=}("baz", null); - } =>#t256; - core::List<core::num> list80 = block { - final core::List<core::num> #t257 = <core::num>[]; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t257.{core::List::add}(42); - else - #t257.{core::List::add}(3.14); + for (final core::MapEntry<core::String, core::int> #t258 in <core::String, core::int>{}.{core::Map::entries}) + #t257.{core::Map::[]=}(#t258.{core::MapEntry::key}, #t258.{core::MapEntry::value}); + #t257.{core::Map::[]=}("baz", null); } =>#t257; - core::Set<core::num> set80 = block { - final core::Set<core::num> #t258 = col::LinkedHashSet::•<core::num>(); + core::List<core::int> list51 = block { + final core::List<core::int> #t259 = <core::int>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t258.{core::Set::add}(42); - else - #t258.{core::Set::add}(3.14); - #t258.{core::Set::add}(null); - } =>#t258; - core::Map<core::String, core::num> map80 = block { - final core::Map<core::String, core::num> #t259 = <core::String, core::num>{}; - for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t259.{core::Map::[]=}("bar", 42); - else - #t259.{core::Map::[]=}("bar", 3.14); - #t259.{core::Map::[]=}("baz", null); + for (final core::int #t260 in let final core::Set<core::int> #t261 = col::LinkedHashSet::•<core::int>() in #t261) + #t259.{core::List::add}(#t260); } =>#t259; - core::List<core::num> list81 = block { - final core::List<core::num> #t260 = <core::num>[]; + core::Set<core::int> set51 = block { + final core::Set<core::int> #t262 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::num #t261 in listInt) - #t260.{core::List::add}(#t261); - else - for (final core::num #t262 in listDouble) - #t260.{core::List::add}(#t262); - } =>#t260; - core::Set<core::num> set81 = block { - final core::Set<core::num> #t263 = col::LinkedHashSet::•<core::num>(); + for (final core::int #t263 in let final core::Set<core::int> #t264 = col::LinkedHashSet::•<core::int>() in #t264) + #t262.{core::Set::add}(#t263); + #t262.{core::Set::add}(null); + } =>#t262; + core::List<core::int> list52 = block { + final core::List<core::int> #t265 = <core::int>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::num #t264 in listInt) - #t263.{core::Set::add}(#t264); - else - for (final core::num #t265 in listDouble) - #t263.{core::Set::add}(#t265); - #t263.{core::Set::add}(null); - } =>#t263; - core::Map<core::String, core::num> map81 = block { - final core::Map<core::String, core::num> #t266 = <core::String, core::num>{}; + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::int #t266 in <core::int>[]) + #t265.{core::List::add}(#t266); + } =>#t265; + core::Set<core::int> set52 = block { + final core::Set<core::int> #t267 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::MapEntry<core::String, core::num> #t267 in mapStringInt.{core::Map::entries}) - #t266.{core::Map::[]=}(#t267.{core::MapEntry::key}, #t267.{core::MapEntry::value}); - else - for (final core::MapEntry<core::String, core::num> #t268 in mapStringDouble.{core::Map::entries}) - #t266.{core::Map::[]=}(#t268.{core::MapEntry::key}, #t268.{core::MapEntry::value}); - #t266.{core::Map::[]=}("baz", null); - } =>#t266; - core::List<dynamic> list82 = block { - final core::List<dynamic> #t269 = <dynamic>[]; + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::int #t268 in <core::int>[]) + #t267.{core::Set::add}(#t268); + #t267.{core::Set::add}(null); + } =>#t267; + core::List<core::List<core::int>> list60 = block { + final core::List<core::List<core::int>> #t269 = <core::List<core::int>>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final dynamic #t270 in listInt) - #t269.{core::List::add}(#t270); - else - for (final dynamic #t271 in dynVar as{TypeError} core::Iterable<dynamic>) - #t269.{core::List::add}(#t271); + for (final core::List<core::int> #t270 in <core::List<core::int>>[<core::int>[]]) + #t269.{core::List::add}(#t270); } =>#t269; - core::Set<dynamic> set82 = block { - final core::Set<dynamic> #t272 = col::LinkedHashSet::•<dynamic>(); + core::Set<core::List<core::int>> set60 = block { + final core::Set<core::List<core::int>> #t271 = col::LinkedHashSet::•<core::List<core::int>>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final dynamic #t273 in listInt) - #t272.{core::Set::add}(#t273); - else - for (final dynamic #t274 in dynVar as{TypeError} core::Iterable<dynamic>) - #t272.{core::Set::add}(#t274); - #t272.{core::Set::add}(null); - } =>#t272; - core::Map<dynamic, dynamic> map82 = block { - final core::Map<dynamic, dynamic> #t275 = <dynamic, dynamic>{}; + for (final core::List<core::int> #t272 in <core::List<core::int>>[<core::int>[]]) + #t271.{core::Set::add}(#t272); + #t271.{core::Set::add}(null); + } =>#t271; + core::Map<core::String, core::List<core::int>> map60 = block { + final core::Map<core::String, core::List<core::int>> #t273 = <core::String, core::List<core::int>>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::MapEntry<dynamic, dynamic> #t276 in mapStringInt.{core::Map::entries}) - #t275.{core::Map::[]=}(#t276.{core::MapEntry::key}, #t276.{core::MapEntry::value}); - else - for (final core::MapEntry<dynamic, dynamic> #t277 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) - #t275.{core::Map::[]=}(#t277.{core::MapEntry::key}, #t277.{core::MapEntry::value}); - #t275.{core::Map::[]=}("baz", null); + for (final core::MapEntry<core::String, core::List<core::int>> #t274 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) + #t273.{core::Map::[]=}(#t274.{core::MapEntry::key}, #t274.{core::MapEntry::value}); + #t273.{core::Map::[]=}("baz", null); + } =>#t273; + core::List<core::List<core::int>> list61 = block { + final core::List<core::List<core::int>> #t275 = <core::List<core::int>>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::List<core::int> #t276 in <core::List<core::int>>[<core::int>[]]) + #t275.{core::List::add}(#t276); } =>#t275; - core::List<core::num> list83 = block { - final core::List<core::num> #t278 = <core::num>[]; + core::Set<core::List<core::int>> set61 = block { + final core::Set<core::List<core::int>> #t277 = col::LinkedHashSet::•<core::List<core::int>>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t278.{core::List::add}(42); - else - for (final core::num #t279 in listDouble) - #t278.{core::List::add}(#t279); - } =>#t278; - core::Set<core::num> set83 = block { - final core::Set<core::num> #t280 = col::LinkedHashSet::•<core::num>(); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::List<core::int> #t278 in <core::List<core::int>>[<core::int>[]]) + #t277.{core::Set::add}(#t278); + #t277.{core::Set::add}(null); + } =>#t277; + core::Map<core::String, core::List<core::int>> map61 = block { + final core::Map<core::String, core::List<core::int>> #t279 = <core::String, core::List<core::int>>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::num #t281 in listInt) - #t280.{core::Set::add}(#t281); - else - #t280.{core::Set::add}(3.14); - #t280.{core::Set::add}(null); - } =>#t280; - core::Map<core::String, core::num> map83 = block { - final core::Map<core::String, core::num> #t282 = <core::String, core::num>{}; + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::MapEntry<core::String, core::List<core::int>> #t280 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries}) + #t279.{core::Map::[]=}(#t280.{core::MapEntry::key}, #t280.{core::MapEntry::value}); + #t279.{core::Map::[]=}("baz", null); + } =>#t279; + core::List<core::List<core::int>> list70 = block { + final core::List<core::List<core::int>> #t281 = <core::List<core::int>>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - for (final core::MapEntry<core::String, core::num> #t283 in mapStringInt.{core::Map::entries}) - #t282.{core::Map::[]=}(#t283.{core::MapEntry::key}, #t283.{core::MapEntry::value}); - else - #t282.{core::Map::[]=}("bar", 3.14); - #t282.{core::Map::[]=}("baz", null); + #t281.{core::List::add}(<core::int>[]); + } =>#t281; + core::Set<core::List<core::int>> set70 = block { + final core::Set<core::List<core::int>> #t282 = col::LinkedHashSet::•<core::List<core::int>>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t282.{core::Set::add}(<core::int>[]); + #t282.{core::Set::add}(null); } =>#t282; - core::List<core::int> list90 = block { - final core::List<core::int> #t284 = <core::int>[]; + core::Map<core::String, core::List<core::int>> map70 = block { + final core::Map<core::String, core::List<core::int>> #t283 = <core::String, core::List<core::int>>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t284.{core::List::add}(dynVar as{TypeError} core::int); + #t283.{core::Map::[]=}("bar", <core::int>[]); + #t283.{core::Map::[]=}("baz", null); + } =>#t283; + core::List<core::List<core::int>> list71 = block { + final core::List<core::List<core::int>> #t284 = <core::List<core::int>>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t284.{core::List::add}(<core::int>[]); } =>#t284; - core::Set<core::int> set90 = block { - final core::Set<core::int> #t285 = col::LinkedHashSet::•<core::int>(); + core::Set<core::List<core::int>> set71 = block { + final core::Set<core::List<core::int>> #t285 = col::LinkedHashSet::•<core::List<core::int>>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t285.{core::Set::add}(dynVar as{TypeError} core::int); + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t285.{core::Set::add}(<core::int>[]); #t285.{core::Set::add}(null); } =>#t285; - core::Map<core::String, core::int> map90 = block { - final core::Map<core::String, core::int> #t286 = <core::String, core::int>{}; + core::Map<core::String, core::List<core::int>> map71 = block { + final core::Map<core::String, core::List<core::int>> #t286 = <core::String, core::List<core::int>>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t286.{core::Map::[]=}("bar", dynVar as{TypeError} core::int); + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t286.{core::Map::[]=}("bar", <core::int>[]); #t286.{core::Map::[]=}("baz", null); } =>#t286; - core::List<core::int> list91 = block { - final core::List<core::int> #t287 = <core::int>[]; + core::List<core::num> list80 = block { + final core::List<core::num> #t287 = <core::num>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final dynamic #t288 in dynVar as{TypeError} core::Iterable<dynamic>) { - final core::int #t289 = #t288 as{TypeError} core::int; - #t287.{core::List::add}(#t289); - } + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t287.{core::List::add}(42); + else + #t287.{core::List::add}(3.14); } =>#t287; - core::Set<core::int> set91 = block { - final core::Set<core::int> #t290 = col::LinkedHashSet::•<core::int>(); + core::Set<core::num> set80 = block { + final core::Set<core::num> #t288 = col::LinkedHashSet::•<core::num>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final dynamic #t291 in dynVar as{TypeError} core::Iterable<dynamic>) { - final core::int #t292 = #t291 as{TypeError} core::int; - #t290.{core::Set::add}(#t292); - } - #t290.{core::Set::add}(null); + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t288.{core::Set::add}(42); + else + #t288.{core::Set::add}(3.14); + #t288.{core::Set::add}(null); + } =>#t288; + core::Map<core::String, core::num> map80 = block { + final core::Map<core::String, core::num> #t289 = <core::String, core::num>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t289.{core::Map::[]=}("bar", 42); + else + #t289.{core::Map::[]=}("bar", 3.14); + #t289.{core::Map::[]=}("baz", null); + } =>#t289; + core::List<core::num> list81 = block { + final core::List<core::num> #t290 = <core::num>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::num #t291 in listInt) + #t290.{core::List::add}(#t291); + else + for (final core::num #t292 in listDouble) + #t290.{core::List::add}(#t292); } =>#t290; - core::Map<core::String, core::int> map91 = block { - final core::Map<core::String, core::int> #t293 = <core::String, core::int>{}; + core::Set<core::num> set81 = block { + final core::Set<core::num> #t293 = col::LinkedHashSet::•<core::num>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::MapEntry<dynamic, dynamic> #t294 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) { - final core::String #t295 = #t294.{core::MapEntry::key} as{TypeError} core::String; - final core::int #t296 = #t294.{core::MapEntry::value} as{TypeError} core::int; - #t293.{core::Map::[]=}(#t295, #t296); - } - #t293.{core::Map::[]=}("baz", null); + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::num #t294 in listInt) + #t293.{core::Set::add}(#t294); + else + for (final core::num #t295 in listDouble) + #t293.{core::Set::add}(#t295); + #t293.{core::Set::add}(null); } =>#t293; - core::List<core::int> list100 = block { - final core::List<core::int> #t297 = <core::int>[]; - for (final dynamic #t298 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1)) - #t297.{core::List::add}(42); - } =>#t297; - core::Set<core::int> set100 = block { - final core::Set<core::int> #t299 = col::LinkedHashSet::•<core::int>(); - for (final dynamic #t300 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1)) - #t299.{core::Set::add}(42); + core::Map<core::String, core::num> map81 = block { + final core::Map<core::String, core::num> #t296 = <core::String, core::num>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::MapEntry<core::String, core::num> #t297 in mapStringInt.{core::Map::entries}) + #t296.{core::Map::[]=}(#t297.{core::MapEntry::key}, #t297.{core::MapEntry::value}); + else + for (final core::MapEntry<core::String, core::num> #t298 in mapStringDouble.{core::Map::entries}) + #t296.{core::Map::[]=}(#t298.{core::MapEntry::key}, #t298.{core::MapEntry::value}); + #t296.{core::Map::[]=}("baz", null); + } =>#t296; + core::List<dynamic> list82 = block { + final core::List<dynamic> #t299 = <dynamic>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final dynamic #t300 in listInt) + #t299.{core::List::add}(#t300); + else + for (final dynamic #t301 in dynVar as{TypeError} core::Iterable<dynamic>) + #t299.{core::List::add}(#t301); } =>#t299; - core::Map<core::String, core::int> map100 = block { - final core::Map<core::String, core::int> #t301 = <core::String, core::int>{}; - for (final dynamic #t302 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1)) - #t301.{core::Map::[]=}("bar", 42); - } =>#t301; - core::List<core::int> list110 = block { - final core::List<core::int> #t303 = <core::int>[]; - for (core::int i in <core::int>[1, 2, 3]) - #t303.{core::List::add}(i); - } =>#t303; - core::Set<core::int> set110 = block { - final core::Set<core::int> #t304 = col::LinkedHashSet::•<core::int>(); - for (core::int i in <core::int>[1, 2, 3]) - #t304.{core::Set::add}(i); - #t304.{core::Set::add}(null); - } =>#t304; - core::Map<core::String, core::int> map110 = block { - final core::Map<core::String, core::int> #t305 = <core::String, core::int>{}; - for (core::int i in <core::int>[1, 2, 3]) - #t305.{core::Map::[]=}("bar", i); + core::Set<dynamic> set82 = block { + final core::Set<dynamic> #t302 = col::LinkedHashSet::•<dynamic>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final dynamic #t303 in listInt) + #t302.{core::Set::add}(#t303); + else + for (final dynamic #t304 in dynVar as{TypeError} core::Iterable<dynamic>) + #t302.{core::Set::add}(#t304); + #t302.{core::Set::add}(null); + } =>#t302; + core::Map<dynamic, dynamic> map82 = block { + final core::Map<dynamic, dynamic> #t305 = <dynamic, dynamic>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::MapEntry<dynamic, dynamic> #t306 in mapStringInt.{core::Map::entries}) + #t305.{core::Map::[]=}(#t306.{core::MapEntry::key}, #t306.{core::MapEntry::value}); + else + for (final core::MapEntry<dynamic, dynamic> #t307 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) + #t305.{core::Map::[]=}(#t307.{core::MapEntry::key}, #t307.{core::MapEntry::value}); #t305.{core::Map::[]=}("baz", null); } =>#t305; - core::List<core::int> list120 = block { - final core::List<core::int> #t306 = <core::int>[]; - for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>) - #t306.{core::List::add}(i as{TypeError} core::int); - } =>#t306; - core::Set<core::int> set120 = block { - final core::Set<core::int> #t307 = col::LinkedHashSet::•<core::int>(); - for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>) - #t307.{core::Set::add}(i as{TypeError} core::int); - #t307.{core::Set::add}(null); - } =>#t307; - core::Map<core::String, core::int> map120 = block { - final core::Map<core::String, core::int> #t308 = <core::String, core::int>{}; - for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>) - #t308.{core::Map::[]=}("bar", i as{TypeError} core::int); - #t308.{core::Map::[]=}("baz", null); + core::List<core::num> list83 = block { + final core::List<core::num> #t308 = <core::num>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t308.{core::List::add}(42); + else + for (final core::num #t309 in listDouble) + #t308.{core::List::add}(#t309); } =>#t308; + core::Set<core::num> set83 = block { + final core::Set<core::num> #t310 = col::LinkedHashSet::•<core::num>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::num #t311 in listInt) + #t310.{core::Set::add}(#t311); + else + #t310.{core::Set::add}(3.14); + #t310.{core::Set::add}(null); + } =>#t310; + core::Map<core::String, core::num> map83 = block { + final core::Map<core::String, core::num> #t312 = <core::String, core::num>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + for (final core::MapEntry<core::String, core::num> #t313 in mapStringInt.{core::Map::entries}) + #t312.{core::Map::[]=}(#t313.{core::MapEntry::key}, #t313.{core::MapEntry::value}); + else + #t312.{core::Map::[]=}("bar", 3.14); + #t312.{core::Map::[]=}("baz", null); + } =>#t312; + core::List<core::int> list90 = block { + final core::List<core::int> #t314 = <core::int>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t314.{core::List::add}(dynVar as{TypeError} core::int); + } =>#t314; + core::Set<core::int> set90 = block { + final core::Set<core::int> #t315 = col::LinkedHashSet::•<core::int>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t315.{core::Set::add}(dynVar as{TypeError} core::int); + #t315.{core::Set::add}(null); + } =>#t315; + core::Map<core::String, core::int> map90 = block { + final core::Map<core::String, core::int> #t316 = <core::String, core::int>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t316.{core::Map::[]=}("bar", dynVar as{TypeError} core::int); + #t316.{core::Map::[]=}("baz", null); + } =>#t316; + core::List<core::int> list91 = block { + final core::List<core::int> #t317 = <core::int>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + for (final dynamic #t318 in dynVar as{TypeError} core::Iterable<dynamic>) { + final core::int #t319 = #t318 as{TypeError} core::int; + #t317.{core::List::add}(#t319); + } + } =>#t317; + core::Set<core::int> set91 = block { + final core::Set<core::int> #t320 = col::LinkedHashSet::•<core::int>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + for (final dynamic #t321 in dynVar as{TypeError} core::Iterable<dynamic>) { + final core::int #t322 = #t321 as{TypeError} core::int; + #t320.{core::Set::add}(#t322); + } + #t320.{core::Set::add}(null); + } =>#t320; + core::Map<core::String, core::int> map91 = block { + final core::Map<core::String, core::int> #t323 = <core::String, core::int>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + for (final core::MapEntry<dynamic, dynamic> #t324 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) { + final core::String #t325 = #t324.{core::MapEntry::key} as{TypeError} core::String; + final core::int #t326 = #t324.{core::MapEntry::value} as{TypeError} core::int; + #t323.{core::Map::[]=}(#t325, #t326); + } + #t323.{core::Map::[]=}("baz", null); + } =>#t323; + core::List<core::int> list100 = block { + final core::List<core::int> #t327 = <core::int>[]; + for (final core::int #t328 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1)) + #t327.{core::List::add}(42); + } =>#t327; + core::Set<core::int> set100 = block { + final core::Set<core::int> #t329 = col::LinkedHashSet::•<core::int>(); + for (final core::int #t330 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1)) + #t329.{core::Set::add}(42); + } =>#t329; + core::Map<core::String, core::int> map100 = block { + final core::Map<core::String, core::int> #t331 = <core::String, core::int>{}; + for (final core::int #t332 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1)) + #t331.{core::Map::[]=}("bar", 42); + } =>#t331; + core::List<core::int> list110 = block { + final core::List<core::int> #t333 = <core::int>[]; + for (core::int i in <core::int>[1, 2, 3]) + #t333.{core::List::add}(i); + } =>#t333; + core::Set<core::int> set110 = block { + final core::Set<core::int> #t334 = col::LinkedHashSet::•<core::int>(); + for (core::int i in <core::int>[1, 2, 3]) + #t334.{core::Set::add}(i); + #t334.{core::Set::add}(null); + } =>#t334; + core::Map<core::String, core::int> map110 = block { + final core::Map<core::String, core::int> #t335 = <core::String, core::int>{}; + for (core::int i in <core::int>[1, 2, 3]) + #t335.{core::Map::[]=}("bar", i); + #t335.{core::Map::[]=}("baz", null); + } =>#t335; + core::List<core::int> list120 = block { + final core::List<core::int> #t336 = <core::int>[]; + for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>) + #t336.{core::List::add}(i as{TypeError} core::int); + } =>#t336; + core::Set<core::int> set120 = block { + final core::Set<core::int> #t337 = col::LinkedHashSet::•<core::int>(); + for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>) + #t337.{core::Set::add}(i as{TypeError} core::int); + #t337.{core::Set::add}(null); + } =>#t337; + core::Map<core::String, core::int> map120 = block { + final core::Map<core::String, core::int> #t338 = <core::String, core::int>{}; + for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>) + #t338.{core::Map::[]=}("bar", i as{TypeError} core::int); + #t338.{core::Map::[]=}("baz", null); + } =>#t338; + core::List<core::int> list130 = block { + final core::List<core::int> #t339 = <core::int>[]; + for (core::int i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1)) + #t339.{core::List::add}(i); + } =>#t339; + core::Set<core::int> set130 = block { + final core::Set<core::int> #t340 = col::LinkedHashSet::•<core::int>(); + for (core::int i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1)) + #t340.{core::Set::add}(i); + } =>#t340; + core::Map<core::int, core::int> map130 = block { + final core::Map<core::int, core::int> #t341 = <core::int, core::int>{}; + for (core::int i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1)) + #t341.{core::Map::[]=}(i, i); + } =>#t341; } static method testForElementErrors(core::Map<core::int, core::int> map, core::List<core::int> list) → dynamic /* originally async */ { final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>(); @@ -1634,249 +1900,295 @@ try { #L1: { - <core::int>[invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:190:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + block { + final core::List<core::int> #t342 = <core::int>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t342.{core::List::add}(let final<BottomType> #t343 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:210:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int>[for (int i = 0; oracle(\"foo\"); i++) \"bar\"]; - ^"]; - let final core::Set<core::int> #t309 = col::LinkedHashSet::•<core::int>() in let final core::bool #t310 = #t309.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:191:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + ^" in "bar" as{TypeError} core::int); + } =>#t342; + block { + final core::Set<core::int> #t344 = col::LinkedHashSet::•<core::int>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + #t344.{core::Set::add}(let final<BottomType> #t345 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:211:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\", null}; - ^") in let final core::bool #t311 = #t309.{core::Set::add}(null) in #t309; - <core::int, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:192:14: Error: A value of type 'String' can't be assigned to a variable of type 'int'. -Try changing the type of the left hand side, or casting the right hand side to 'int'. - <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null}; - ^": invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:192:14: Error: A value of type 'String' can't be assigned to a variable of type 'int'. -Try changing the type of the left hand side, or casting the right hand side to 'int'. - <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null}; - ^", let final<BottomType> #t312 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:192:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. -Try changing the type of the left hand side, or casting the right hand side to 'int'. - <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null}; - ^" in "baz" as{TypeError} core::int: null}; + ^" in "bar" as{TypeError} core::int); + #t344.{core::Set::add}(null); + } =>#t344; block { - final core::List<core::int> #t313 = <core::int>[]; + final core::Map<core::int, core::int> #t346 = <core::int, core::int>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::int #t314 in <core::int>[let final<BottomType> #t315 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:193:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + #t346.{core::Map::[]=}(let final<BottomType> #t347 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:212:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +Try changing the type of the left hand side, or casting the right hand side to 'int'. + <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null}; + ^" in "bar" as{TypeError} core::int, let final<BottomType> #t348 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:212:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +Try changing the type of the left hand side, or casting the right hand side to 'int'. + <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null}; + ^" in "bar" as{TypeError} core::int); + #t346.{core::Map::[]=}(let final<BottomType> #t349 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:212:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. +Try changing the type of the left hand side, or casting the right hand side to 'int'. + <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null}; + ^" in "baz" as{TypeError} core::int, null); + } =>#t346; + block { + final core::List<core::int> #t350 = <core::int>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + for (final core::int #t351 in <core::int>[let final<BottomType> #t352 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int>[for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"]]; ^" in "bar" as{TypeError} core::int]) - #t313.{core::List::add}(#t314); - } =>#t313; + #t350.{core::List::add}(#t351); + } =>#t350; block { - final core::Set<core::int> #t316 = col::LinkedHashSet::•<core::int>(); + final core::Set<core::int> #t353 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::int #t317 in <core::int>[let final<BottomType> #t318 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:194:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + for (final core::int #t354 in <core::int>[let final<BottomType> #t355 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int>{for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"], null}; ^" in "bar" as{TypeError} core::int]) - #t316.{core::Set::add}(#t317); - #t316.{core::Set::add}(null); - } =>#t316; + #t353.{core::Set::add}(#t354); + #t353.{core::Set::add}(null); + } =>#t353; block { - final core::Map<core::int, core::int> #t319 = <core::int, core::int>{}; + final core::Map<core::int, core::int> #t356 = <core::int, core::int>{}; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - for (final core::MapEntry<core::int, core::int> #t320 in <core::int, core::int>{let final<BottomType> #t321 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:195:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + for (final core::MapEntry<core::int, core::int> #t357 in <core::int, core::int>{let final<BottomType> #t358 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null}; - ^" in "bar" as{TypeError} core::int: let final<BottomType> #t322 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:195:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + ^" in "bar" as{TypeError} core::int: let final<BottomType> #t359 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null}; ^" in "bar" as{TypeError} core::int}.{core::Map::entries}) - #t319.{core::Map::[]=}(#t320.{core::MapEntry::key}, #t320.{core::MapEntry::value}); - #t319.{core::Map::[]=}(let final<BottomType> #t323 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:195:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + #t356.{core::Map::[]=}(#t357.{core::MapEntry::key}, #t357.{core::MapEntry::value}); + #t356.{core::Map::[]=}(let final<BottomType> #t360 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:215:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null}; ^" in "baz" as{TypeError} core::int, null); - } =>#t319; + } =>#t356; block { - final core::List<core::int> #t324 = <core::int>[]; + final core::List<core::int> #t361 = <core::int>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t324.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:196:48: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + #t361.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:216:48: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>[for (int i = 0; oracle(\"foo\"); i++) ...map]; - ^" as{TypeError} core::int); - } =>#t324; + ^"); + } =>#t361; block { - final core::Set<core::int> #t325 = col::LinkedHashSet::•<core::int>(); + final core::Set<core::int> #t362 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - #t325.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:197:48: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + #t362.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:217:48: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>{for (int i = 0; oracle(\"foo\"); i++) ...map, null}; - ^" as{TypeError} core::int); - #t325.{core::Set::add}(null); - } =>#t325; - <core::int, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:198:53: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + ^"); + #t362.{core::Set::add}(null); + } =>#t362; + <core::int, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:218:53: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...list, 42: null}; - ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:198:53: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:218:53: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...list, 42: null}; ^": null}; - <core::String>[invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:199:48: Error: A value of type 'num' can't be assigned to a variable of type 'String'. + block { + final core::List<core::String> #t363 = <core::String>[]; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t363.{core::List::add}(let final<BottomType> #t364 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:219:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'. Try changing the type of the left hand side, or casting the right hand side to 'String'. <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14]; - ^"]; - let final core::Set<core::String> #t326 = col::LinkedHashSet::•<core::String>() in let final core::bool #t327 = #t326.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:200:48: Error: A value of type 'num' can't be assigned to a variable of type 'String'. + ^" in 42 as{TypeError} core::String); + else + #t363.{core::List::add}(let final<BottomType> #t365 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:219:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14]; + ^" in 3.14 as{TypeError} core::String); + } =>#t363; + block { + final core::Set<core::String> #t366 = col::LinkedHashSet::•<core::String>(); + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t366.{core::Set::add}(let final<BottomType> #t367 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:220:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'. Try changing the type of the left hand side, or casting the right hand side to 'String'. <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null}; - ^") in let final core::bool #t328 = #t326.{core::Set::add}(null) in #t326; - <core::String, core::String>{null: invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:201:20: Error: A value of type 'num' can't be assigned to a variable of type 'String'. + ^" in 42 as{TypeError} core::String); + else + #t366.{core::Set::add}(let final<BottomType> #t368 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:220:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null}; + ^" in 3.14 as{TypeError} core::String); + #t366.{core::Set::add}(null); + } =>#t366; + block { + final core::Map<core::String, core::String> #t369 = <core::String, core::String>{}; + for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t369.{core::Map::[]=}("bar", let final<BottomType> #t370 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:221:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'. Try changing the type of the left hand side, or casting the right hand side to 'String'. <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null}; - ^", "baz": null}; + ^" in 42 as{TypeError} core::String); + else + #t369.{core::Map::[]=}("bar", let final<BottomType> #t371 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:221:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'. +Try changing the type of the left hand side, or casting the right hand side to 'String'. + <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null}; + ^" in 3.14 as{TypeError} core::String); + #t369.{core::Map::[]=}("baz", null); + } =>#t369; block { - final core::List<core::int> #t329 = <core::int>[]; + final core::List<core::int> #t372 = <core::int>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t329.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:202:62: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t372.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:222:62: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...map else 42]; - ^" as{TypeError} core::int); + ^"); else - #t329.{core::List::add}(42 as{TypeError} core::int); - } =>#t329; + #t372.{core::List::add}(42); + } =>#t372; block { - final core::Set<core::int> #t330 = col::LinkedHashSet::•<core::int>(); + final core::Set<core::int> #t373 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t330.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:203:62: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t373.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:223:62: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...map else 42, null}; - ^" as{TypeError} core::int); + ^"); else - #t330.{core::Set::add}(42 as{TypeError} core::int); - #t330.{core::Set::add}(null); - } =>#t330; - <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:204:70: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + #t373.{core::Set::add}(42); + #t373.{core::Set::add}(null); + } =>#t373; + <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:70: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...list else \"bar\": 42, \"baz\": null}; - ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:204:70: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:70: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...list else \"bar\": 42, \"baz\": null}; ^": null}; block { - final core::List<core::int> #t331 = <core::int>[]; + final core::List<core::int> #t374 = <core::int>[]; for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t331.{core::List::add}(42 as{TypeError} core::int); + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t374.{core::List::add}(42); else - #t331.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:205:70: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + #t374.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:225:70: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else ...map]; - ^" as{TypeError} core::int); - } =>#t331; + ^"); + } =>#t374; block { - final core::Set<core::int> #t332 = col::LinkedHashSet::•<core::int>(); + final core::Set<core::int> #t375 = col::LinkedHashSet::•<core::int>(); for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1)) - if(self::oracle<dynamic>()) - #t332.{core::Set::add}(42 as{TypeError} core::int); + if(self::oracle<dynamic>() as{TypeError} core::bool) + #t375.{core::Set::add}(42); else - #t332.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:206:70: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. + #t375.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:226:70: Error: Unexpected type 'Map<int, int>' of a spread. Expected 'dynamic' or an Iterable. - 'Map' is from 'dart:core'. <int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else ...map, null}; - ^" as{TypeError} core::int); - #t332.{core::Set::add}(null); - } =>#t332; - <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:207:85: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + ^"); + #t375.{core::Set::add}(null); + } =>#t375; + <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:227:85: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else ...list, \"baz\": null}; - ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:207:85: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. + ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:227:85: Error: Unexpected type 'List<int>' of a map spread entry. Expected 'dynamic' or a Map. - 'List' is from 'dart:core'. <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else ...list, \"baz\": null}; ^": null}; final core::int i = 0; block { - final core::List<core::int> #t333 = <core::int>[]; - for (final core::int #t334 in <core::int>[1]) { - invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:210:14: Error: Setter not found: 'i'. + final core::List<core::int> #t376 = <core::int>[]; + for (final core::int #t377 in <core::int>[1]) { + invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:230:14: Error: Setter not found: 'i'. <int>[for (i in <int>[1]) i]; ^"; - #t333.{core::List::add}(i); + #t376.{core::List::add}(i); } - } =>#t333; + } =>#t376; block { - final core::Set<core::int> #t335 = col::LinkedHashSet::•<core::int>(); - for (final core::int #t336 in <core::int>[1]) { - invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:211:14: Error: Setter not found: 'i'. + final core::Set<core::int> #t378 = col::LinkedHashSet::•<core::int>(); + for (final core::int #t379 in <core::int>[1]) { + invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:231:14: Error: Setter not found: 'i'. <int>{for (i in <int>[1]) i, null}; ^"; - #t335.{core::Set::add}(i); + #t378.{core::Set::add}(i); } - #t335.{core::Set::add}(null); - } =>#t335; + #t378.{core::Set::add}(null); + } =>#t378; block { - final core::Map<core::String, core::int> #t337 = <core::String, core::int>{}; - for (final core::int #t338 in <core::int>[1]) { - invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:212:21: Error: Setter not found: 'i'. + final core::Map<core::String, core::int> #t380 = <core::String, core::int>{}; + for (final core::int #t381 in <core::int>[1]) { + invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:232:21: Error: Setter not found: 'i'. \t<String, int>{for (i in <int>[1]) \"bar\": i, \"baz\": null}; \t ^"; - #t337.{core::Map::[]=}("bar", i); + #t380.{core::Map::[]=}("bar", i); } - #t337.{core::Map::[]=}("baz", null); - } =>#t337; + #t380.{core::Map::[]=}("baz", null); + } =>#t380; core::List<dynamic> list10 = block { - final core::List<dynamic> #t339 = <dynamic>[]; - for (dynamic i in let final<BottomType> #t340 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:214:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. + final core::List<dynamic> #t382 = <dynamic>[]; + for (dynamic i in let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:234:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. - 'Iterable' is from 'dart:core'. var list10 = [for (var i in \"not iterable\") i]; ^" in "not iterable" as{TypeError} core::Iterable<dynamic>) - #t339.{core::List::add}(i); - } =>#t339; + #t382.{core::List::add}(i); + } =>#t382; core::Set<dynamic> set10 = block { - final core::Set<dynamic> #t341 = col::LinkedHashSet::•<dynamic>(); - for (dynamic i in let final<BottomType> #t342 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:215:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. + final core::Set<dynamic> #t384 = col::LinkedHashSet::•<dynamic>(); + for (dynamic i in let final<BottomType> #t385 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:235:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. - 'Iterable' is from 'dart:core'. var set10 = {for (var i in \"not iterable\") i, null}; ^" in "not iterable" as{TypeError} core::Iterable<dynamic>) - #t341.{core::Set::add}(i); - #t341.{core::Set::add}(null); - } =>#t341; + #t384.{core::Set::add}(i); + #t384.{core::Set::add}(null); + } =>#t384; core::Map<core::String, dynamic> map10 = block { - final core::Map<core::String, dynamic> #t343 = <core::String, dynamic>{}; - for (dynamic i in let final<BottomType> #t344 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:216:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. + final core::Map<core::String, dynamic> #t386 = <core::String, dynamic>{}; + for (dynamic i in let final<BottomType> #t387 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:236:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'. - 'Iterable' is from 'dart:core'. var map10 = {for (var i in \"not iterable\") \"bar\": i, \"baz\": null}; ^" in "not iterable" as{TypeError} core::Iterable<dynamic>) - #t343.{core::Map::[]=}("bar", i); - #t343.{core::Map::[]=}("baz", null); - } =>#t343; + #t386.{core::Map::[]=}("bar", i); + #t386.{core::Map::[]=}("baz", null); + } =>#t386; core::List<core::int> list20 = block { - final core::List<core::int> #t345 = <core::int>[]; - for (core::int i in <core::int>[let final<BottomType> #t346 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:217:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + final core::List<core::int> #t388 = <core::int>[]; + for (core::int i in <core::int>[let final<BottomType> #t389 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var list20 = [for (int i in [\"not\", \"int\"]) i]; - ^" in "not" as{TypeError} core::int, let final<BottomType> #t347 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:217:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + ^" in "not" as{TypeError} core::int, let final<BottomType> #t390 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var list20 = [for (int i in [\"not\", \"int\"]) i]; ^" in "int" as{TypeError} core::int]) - #t345.{core::List::add}(i); - } =>#t345; + #t388.{core::List::add}(i); + } =>#t388; core::Set<core::int> set20 = block { - final core::Set<core::int> #t348 = col::LinkedHashSet::•<core::int>(); - for (core::int i in <core::int>[let final<BottomType> #t349 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:218:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + final core::Set<core::int> #t391 = col::LinkedHashSet::•<core::int>(); + for (core::int i in <core::int>[let final<BottomType> #t392 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var set20 = {for (int i in [\"not\", \"int\"]) i, null}; - ^" in "not" as{TypeError} core::int, let final<BottomType> #t350 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:218:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + ^" in "not" as{TypeError} core::int, let final<BottomType> #t393 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var set20 = {for (int i in [\"not\", \"int\"]) i, null}; ^" in "int" as{TypeError} core::int]) - #t348.{core::Set::add}(i); - #t348.{core::Set::add}(null); - } =>#t348; + #t391.{core::Set::add}(i); + #t391.{core::Set::add}(null); + } =>#t391; core::Map<core::String, core::int> map20 = block { - final core::Map<core::String, core::int> #t351 = <core::String, core::int>{}; - for (core::int i in <core::int>[let final<BottomType> #t352 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:219:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + final core::Map<core::String, core::int> #t394 = <core::String, core::int>{}; + for (core::int i in <core::int>[let final<BottomType> #t395 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null}; - ^" in "not" as{TypeError} core::int, let final<BottomType> #t353 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:219:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + ^" in "not" as{TypeError} core::int, let final<BottomType> #t396 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null}; ^" in "int" as{TypeError} core::int]) - #t351.{core::Map::[]=}("bar", i); - #t351.{core::Map::[]=}("baz", null); - } =>#t351; - final core::List<dynamic> #t354 = <dynamic>[]; + #t394.{core::Map::[]=}("bar", i); + #t394.{core::Map::[]=}("baz", null); + } =>#t394; + final core::List<dynamic> #t397 = <dynamic>[]; { - dynamic :stream = let final<BottomType> #t355 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:220:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. + dynamic :stream = let final<BottomType> #t398 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:240:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. - 'Stream' is from 'dart:async'. var list30 = [await for (var i in \"not stream\") i]; ^" in "not stream" as{TypeError} asy::Stream<dynamic>; @@ -1886,25 +2198,25 @@ try #L2: while (true) { - dynamic #t356 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream); - [yield] let dynamic #t357 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null; + dynamic #t399 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream); + [yield] let dynamic #t400 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null; if(:result) { dynamic i = :for-iterator.{asy::_StreamIterator::current}; - #t354.{core::List::add}(i); + #t397.{core::List::add}(i); } else break #L2; } finally if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) { - [yield] let dynamic #t358 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null; + [yield] let dynamic #t401 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null; :result; } } - core::List<dynamic> list30 = block {} =>#t354; - final core::Set<dynamic> #t359 = col::LinkedHashSet::•<dynamic>(); + core::List<dynamic> list30 = block {} =>#t397; + final core::Set<dynamic> #t402 = col::LinkedHashSet::•<dynamic>(); { - dynamic :stream = let final<BottomType> #t360 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:221:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. + dynamic :stream = let final<BottomType> #t403 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:241:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. - 'Stream' is from 'dart:async'. var set30 = {await for (var i in \"not stream\") i, null}; ^" in "not stream" as{TypeError} asy::Stream<dynamic>; @@ -1914,27 +2226,27 @@ try #L3: while (true) { - dynamic #t361 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream); - [yield] let dynamic #t362 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null; + dynamic #t404 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream); + [yield] let dynamic #t405 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null; if(:result) { dynamic i = :for-iterator.{asy::_StreamIterator::current}; - #t359.{core::Set::add}(i); + #t402.{core::Set::add}(i); } else break #L3; } finally if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) { - [yield] let dynamic #t363 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null; + [yield] let dynamic #t406 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null; :result; } } core::Set<dynamic> set30 = block { - #t359.{core::Set::add}(null); - } =>#t359; - final core::Map<core::String, dynamic> #t364 = <core::String, dynamic>{}; + #t402.{core::Set::add}(null); + } =>#t402; + final core::Map<core::String, dynamic> #t407 = <core::String, dynamic>{}; { - dynamic :stream = let final<BottomType> #t365 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:222:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. + dynamic :stream = let final<BottomType> #t408 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:242:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'. - 'Stream' is from 'dart:async'. var map30 = {await for (var i in \"not stream\") \"bar\": i, \"baz\": null}; ^" in "not stream" as{TypeError} asy::Stream<dynamic>; @@ -1944,30 +2256,30 @@ try #L4: while (true) { - dynamic #t366 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream); - [yield] let dynamic #t367 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null; + dynamic #t409 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream); + [yield] let dynamic #t410 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null; if(:result) { dynamic i = :for-iterator.{asy::_StreamIterator::current}; - #t364.{core::Map::[]=}("bar", i); + #t407.{core::Map::[]=}("bar", i); } else break #L4; } finally if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) { - [yield] let dynamic #t368 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null; + [yield] let dynamic #t411 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null; :result; } } core::Map<core::String, dynamic> map30 = block { - #t364.{core::Map::[]=}("baz", null); - } =>#t364; - final core::List<core::int> #t369 = <core::int>[]; + #t407.{core::Map::[]=}("baz", null); + } =>#t407; + final core::List<core::int> #t412 = <core::int>[]; { - dynamic :stream = asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t370 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:223:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + dynamic :stream = asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t413 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i]; - ^" in "not" as{TypeError} core::int, let final<BottomType> #t371 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:223:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + ^" in "not" as{TypeError} core::int, let final<BottomType> #t414 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i]; ^" in "int" as{TypeError} core::int]); @@ -1977,28 +2289,28 @@ try #L5: while (true) { - dynamic #t372 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream); - [yield] let dynamic #t373 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null; + dynamic #t415 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream); + [yield] let dynamic #t416 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null; if(:result) { core::int i = :for-iterator.{asy::_StreamIterator::current}; - #t369.{core::List::add}(i); + #t412.{core::List::add}(i); } else break #L5; } finally if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) { - [yield] let dynamic #t374 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null; + [yield] let dynamic #t417 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null; :result; } } - core::List<core::int> list40 = block {} =>#t369; - final core::Set<core::int> #t375 = col::LinkedHashSet::•<core::int>(); + core::List<core::int> list40 = block {} =>#t412; + final core::Set<core::int> #t418 = col::LinkedHashSet::•<core::int>(); { - dynamic :stream = asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t376 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + dynamic :stream = asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t419 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null}; - ^" in "not" as{TypeError} core::int, let final<BottomType> #t377 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + ^" in "not" as{TypeError} core::int, let final<BottomType> #t420 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null}; ^" in "int" as{TypeError} core::int]); @@ -2008,30 +2320,30 @@ try #L6: while (true) { - dynamic #t378 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream); - [yield] let dynamic #t379 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null; + dynamic #t421 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream); + [yield] let dynamic #t422 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null; if(:result) { core::int i = :for-iterator.{asy::_StreamIterator::current}; - #t375.{core::Set::add}(i); + #t418.{core::Set::add}(i); } else break #L6; } finally if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) { - [yield] let dynamic #t380 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null; + [yield] let dynamic #t423 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null; :result; } } core::Set<core::int> set40 = block { - #t375.{core::Set::add}(null); - } =>#t375; - final core::Map<core::String, core::int> #t381 = <core::String, core::int>{}; + #t418.{core::Set::add}(null); + } =>#t418; + final core::Map<core::String, core::int> #t424 = <core::String, core::int>{}; { - dynamic :stream = asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t382 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:225:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + dynamic :stream = asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t425 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null}; - ^" in "not" as{TypeError} core::int, let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:225:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. + ^" in "not" as{TypeError} core::int, let final<BottomType> #t426 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'. Try changing the type of the left hand side, or casting the right hand side to 'int'. var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null}; ^" in "int" as{TypeError} core::int]); @@ -2041,67 +2353,67 @@ try #L7: while (true) { - dynamic #t384 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream); - [yield] let dynamic #t385 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null; + dynamic #t427 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream); + [yield] let dynamic #t428 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null; if(:result) { core::int i = :for-iterator.{asy::_StreamIterator::current}; - #t381.{core::Map::[]=}("bar", i); + #t424.{core::Map::[]=}("bar", i); } else break #L7; } finally if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) { - [yield] let dynamic #t386 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null; + [yield] let dynamic #t429 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null; :result; } } core::Map<core::String, core::int> map40 = block { - #t381.{core::Map::[]=}("baz", null); - } =>#t381; + #t424.{core::Map::[]=}("baz", null); + } =>#t424; core::List<core::int> list50 = block { - final core::List<core::int> #t387 = <core::int>[]; + final core::List<core::int> #t430 = <core::int>[]; for (; ; ) - #t387.{core::List::add}(42); - } =>#t387; + #t430.{core::List::add}(42); + } =>#t430; core::Set<core::int> set50 = block { - final core::Set<core::int> #t388 = col::LinkedHashSet::•<core::int>(); + final core::Set<core::int> #t431 = col::LinkedHashSet::•<core::int>(); for (; ; ) - #t388.{core::Set::add}(42); - #t388.{core::Set::add}(null); - } =>#t388; + #t431.{core::Set::add}(42); + #t431.{core::Set::add}(null); + } =>#t431; core::Map<core::String, core::int> map50 = block { - final core::Map<core::String, core::int> #t389 = <core::String, core::int>{}; + final core::Map<core::String, core::int> #t432 = <core::String, core::int>{}; for (; ; ) - #t389.{core::Map::[]=}("bar", 42); - #t389.{core::Map::[]=}("baz", null); - } =>#t389; + #t432.{core::Map::[]=}("bar", 42); + #t432.{core::Map::[]=}("baz", null); + } =>#t432; core::List<core::int> list60 = block { - final core::List<core::int> #t390 = <core::int>[]; - for (; let final<BottomType> #t391 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:229:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. + final core::List<core::int> #t433 = <core::int>[]; + for (; let final<BottomType> #t434 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:249:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. Try changing the type of the left hand side, or casting the right hand side to 'bool'. var list60 = [for (; \"not bool\";) 42]; ^" in "not bool" as{TypeError} core::bool; ) - #t390.{core::List::add}(42); - } =>#t390; + #t433.{core::List::add}(42); + } =>#t433; core::Set<core::int> set60 = block { - final core::Set<core::int> #t392 = col::LinkedHashSet::•<core::int>(); - for (; let final<BottomType> #t393 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:230:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. + final core::Set<core::int> #t435 = col::LinkedHashSet::•<core::int>(); + for (; let final<BottomType> #t436 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. Try changing the type of the left hand side, or casting the right hand side to 'bool'. var set60 = {for (; \"not bool\";) 42, null}; ^" in "not bool" as{TypeError} core::bool; ) - #t392.{core::Set::add}(42); - #t392.{core::Set::add}(null); - } =>#t392; + #t435.{core::Set::add}(42); + #t435.{core::Set::add}(null); + } =>#t435; core::Map<core::String, core::int> map60 = block { - final core::Map<core::String, core::int> #t394 = <core::String, core::int>{}; - for (; let final<BottomType> #t395 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:231:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. + final core::Map<core::String, core::int> #t437 = <core::String, core::int>{}; + for (; let final<BottomType> #t438 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:251:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'. Try changing the type of the left hand side, or casting the right hand side to 'bool'. var map60 = {for (; \"not bool\";) \"bar\": 42, \"baz\": null}; ^" in "not bool" as{TypeError} core::bool; ) - #t394.{core::Map::[]=}("bar", 42); - #t394.{core::Map::[]=}("baz", null); - } =>#t394; + #t437.{core::Map::[]=}("bar", 42); + #t437.{core::Map::[]=}("baz", null); + } =>#t437; } asy::_completeOnAsyncReturn(:async_completer, :return_value); return; @@ -2117,19 +2429,36 @@ } static method testForElementErrorsNotAsync(asy::Stream<core::int> stream) → dynamic { block { - final core::List<core::int> #t396 = <core::int>[]; + final core::List<core::int> #t439 = <core::int>[]; await for (core::int i in stream) - #t396.{core::List::add}(i); - } =>#t396; + #t439.{core::List::add}(i); + } =>#t439; block { - final core::Set<core::int> #t397 = col::LinkedHashSet::•<core::int>(); + final core::Set<core::int> #t440 = col::LinkedHashSet::•<core::int>(); await for (core::int i in stream) - #t397.{core::Set::add}(i); - } =>#t397; + #t440.{core::Set::add}(i); + } =>#t440; block { - final core::Map<core::String, core::int> #t398 = <core::String, core::int>{}; + final core::Map<core::String, core::int> #t441 = <core::String, core::int>{}; await for (core::int i in stream) - #t398.{core::Map::[]=}("bar", i); - } =>#t398; + #t441.{core::Map::[]=}("bar", i); + } =>#t441; +} +static method testPromotion(self::A a) → dynamic { + core::List<core::int> list10 = block { + final core::List<core::int> #t442 = <core::int>[]; + if(a is self::B) + #t442.{core::List::add}(a{self::B}.{self::B::foo}); + } =>#t442; + core::Set<core::int> set10 = block { + final core::Set<core::int> #t443 = col::LinkedHashSet::•<core::int>(); + if(a is self::B) + #t443.{core::Set::add}(a{self::B}.{self::B::foo}); + } =>#t443; + core::Map<core::int, core::int> map10 = block { + final core::Map<core::int, core::int> #t444 = <core::int, core::int>{}; + if(a is self::B) + #t444.{core::Map::[]=}(a{self::B}.{self::B::foo}, a{self::B}.{self::B::foo}); + } =>#t444; } static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart.type_promotion.expect b/pkg/front_end/testcases/control_flow_collection_inference.dart.type_promotion.expect index 1ac72fb..648acdc 100644 --- a/pkg/front_end/testcases/control_flow_collection_inference.dart.type_promotion.expect +++ b/pkg/front_end/testcases/control_flow_collection_inference.dart.type_promotion.expect
@@ -1,288 +1,306 @@ -pkg/front_end/testcases/control_flow_collection_inference.dart:106:49: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:123:49: Context: Write to i@7018 var list10 = [for (int i = 0; oracle("foo"); i++) 42]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:107:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:124:48: Context: Write to i@7018 var set10 = {for (int i = 0; oracle("foo"); i++) 42, null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:108:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:125:48: Context: Write to i@7018 var map10 = {for (int i = 0; oracle("foo"); i++) "bar": 42, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:109:49: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:126:49: Context: Write to i@7018 var list11 = [for (int i = 0; oracle("foo"); i++) dynVar]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:110:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:127:48: Context: Write to i@7018 var set11 = {for (int i = 0; oracle("foo"); i++) dynVar, null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:111:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:128:48: Context: Write to i@7018 var map11 = {for (int i = 0; oracle("foo"); i++) "bar": dynVar, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:112:49: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:129:49: Context: Write to i@7018 var list12 = [for (int i = 0; oracle("foo"); i++) [42]]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:113:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:130:48: Context: Write to i@7018 var set12 = {for (int i = 0; oracle("foo"); i++) [42], null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:114:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:131:48: Context: Write to i@7018 var map12 = {for (int i = 0; oracle("foo"); i++) "bar": [42], "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:115:49: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:132:49: Context: Write to i@7018 var list20 = [for (int i = 0; oracle("foo"); i++) ...[42]]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:116:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:133:48: Context: Write to i@7018 var set20 = {for (int i = 0; oracle("foo"); i++) ...[42], null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:117:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:134:48: Context: Write to i@7018 var map20 = {for (int i = 0; oracle("foo"); i++) ...{"bar": 42}, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:118:49: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:135:49: Context: Write to i@7018 var list21 = [for (int i = 0; oracle("foo"); i++) ...[dynVar]]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:119:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:136:48: Context: Write to i@7018 var set21 = {for (int i = 0; oracle("foo"); i++) ...[dynVar], null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:120:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:137:48: Context: Write to i@7018 var map21 = {for (int i = 0; oracle("foo"); i++) ...{"bar": dynVar}, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:121:49: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:138:49: Context: Write to i@7018 var list22 = [for (int i = 0; oracle("foo"); i++) ...[[42]]]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:122:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:139:48: Context: Write to i@7018 var set22 = {for (int i = 0; oracle("foo"); i++) ...[[42]], null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:123:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:140:48: Context: Write to i@7018 var map22 = {for (int i = 0; oracle("foo"); i++) ...{"bar": [42]}, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:124:49: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:141:49: Context: Write to i@7018 var list30 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42]]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:125:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:142:48: Context: Write to i@7018 var set30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42], null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:126:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:143:48: Context: Write to i@7018 var map30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": 42}, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:127:49: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:144:49: Context: Write to i@7018 var list31 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar]]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:128:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:145:48: Context: Write to i@7018 var set31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar], null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:129:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:146:48: Context: Write to i@7018 var map31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": dynVar}, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:130:49: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:147:49: Context: Write to i@7018 var list33 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]]]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:131:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:148:48: Context: Write to i@7018 var set33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]], null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:132:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:149:48: Context: Write to i@7018 var map33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": [42]}, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:133:61: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:150:61: Context: Write to i@7018 List<List<int>> list40 = [for (int i = 0; oracle("foo"); i++) ...[[]]]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:134:59: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:151:59: Context: Write to i@7018 Set<List<int>> set40 = {for (int i = 0; oracle("foo"); i++) ...[[]], null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:135:67: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:152:67: Context: Write to i@7018 Map<String, List<int>> map40 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:136:61: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:153:61: Context: Write to i@7018 List<List<int>> list41 = [for (int i = 0; oracle("foo"); i++) ...{[]}]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:137:59: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:154:59: Context: Write to i@7018 Set<List<int>> set41 = {for (int i = 0; oracle("foo"); i++) ...{[]}, null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:138:61: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:155:61: Context: Write to i@7018 List<List<int>> list42 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:139:59: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:156:59: Context: Write to i@7018 Set<List<int>> set42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:140:67: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:157:67: Context: Write to i@7018 Map<String, List<int>> map42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:141:55: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:158:55: Context: Write to i@7018 List<int> list50 = [for (int i = 0; oracle("foo"); i++) ...[]]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:142:53: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:159:53: Context: Write to i@7018 Set<int> set50 = {for (int i = 0; oracle("foo"); i++) ...[], null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:143:61: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:160:61: Context: Write to i@7018 Map<String, int> map50 = {for (int i = 0; oracle("foo"); i++) ...{}, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:144:55: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:161:55: Context: Write to i@7018 List<int> list51 = [for (int i = 0; oracle("foo"); i++) ...{}]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:145:53: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:162:53: Context: Write to i@7018 Set<int> set51 = {for (int i = 0; oracle("foo"); i++) ...{}, null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:146:55: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:163:55: Context: Write to i@7018 List<int> list52 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[]]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:147:53: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:164:53: Context: Write to i@7018 Set<int> set52 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[], null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:148:61: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:165:61: Context: Write to i@7018 List<List<int>> list60 = [for (int i = 0; oracle("foo"); i++) ...[[]]]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:149:59: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:166:59: Context: Write to i@7018 Set<List<int>> set60 = {for (int i = 0; oracle("foo"); i++) ...[[]], null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:150:67: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:167:67: Context: Write to i@7018 Map<String, List<int>> map60 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:151:61: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:168:61: Context: Write to i@7018 List<List<int>> list61 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:152:59: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:169:59: Context: Write to i@7018 Set<List<int>> set61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:153:67: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:170:67: Context: Write to i@7018 Map<String, List<int>> map61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:154:61: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:171:61: Context: Write to i@7018 List<List<int>> list70 = [for (int i = 0; oracle("foo"); i++) []]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:155:59: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:172:59: Context: Write to i@7018 Set<List<int>> set70 = {for (int i = 0; oracle("foo"); i++) [], null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:156:67: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:173:67: Context: Write to i@7018 Map<String, List<int>> map70 = {for (int i = 0; oracle("foo"); i++) "bar": [], "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:157:61: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:174:61: Context: Write to i@7018 List<List<int>> list71 = [for (int i = 0; oracle("foo"); i++) if (oracle()) []]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:158:59: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:175:59: Context: Write to i@7018 Set<List<int>> set71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) [], null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:159:67: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:176:67: Context: Write to i@7018 Map<String, List<int>> map71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": [], "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:160:49: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:177:49: Context: Write to i@7018 var list80 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:161:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:178:48: Context: Write to i@7018 var set80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:162:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:179:48: Context: Write to i@7018 var map80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:163:49: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:180:49: Context: Write to i@7018 var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:164:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:181:48: Context: Write to i@7018 var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:165:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:182:48: Context: Write to i@7018 var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:166:49: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:183:49: Context: Write to i@7018 var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:167:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:184:48: Context: Write to i@7018 var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:168:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:185:48: Context: Write to i@7018 var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:169:49: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:186:49: Context: Write to i@7018 var list83 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...listDouble]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:170:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:187:48: Context: Write to i@7018 var set83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else 3.14, null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:171:48: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:188:48: Context: Write to i@7018 var map83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else "bar": 3.14, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:172:55: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:189:55: Context: Write to i@7018 List<int> list90 = [for (int i = 0; oracle("foo"); i++) dynVar]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:173:53: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:190:53: Context: Write to i@7018 Set<int> set90 = {for (int i = 0; oracle("foo"); i++) dynVar, null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:174:61: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:191:61: Context: Write to i@7018 Map<String, int> map90 = {for (int i = 0; oracle("foo"); i++) "bar": dynVar, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:175:55: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:192:55: Context: Write to i@7018 List<int> list91 = [for (int i = 0; oracle("foo"); i++) ...dynVar]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:176:53: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:193:53: Context: Write to i@7018 Set<int> set91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:177:61: Context: Write to i@6094 +pkg/front_end/testcases/control_flow_collection_inference.dart:194:61: Context: Write to i@7018 Map<String, int> map91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:178:40: Context: Write to index@5992 +pkg/front_end/testcases/control_flow_collection_inference.dart:195:40: Context: Write to index@6916 List<int> list100 = <int>[for (index = 0; oracle("foo"); index++) 42]; ^ -pkg/front_end/testcases/control_flow_collection_inference.dart:178:65: Context: Write to index@5992 +pkg/front_end/testcases/control_flow_collection_inference.dart:195:65: Context: Write to index@6916 List<int> list100 = <int>[for (index = 0; oracle("foo"); index++) 42]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:179:38: Context: Write to index@5992 +pkg/front_end/testcases/control_flow_collection_inference.dart:196:38: Context: Write to index@6916 Set<int> set100 = <int>{for (index = 0; oracle("foo"); index++) 42}; ^ -pkg/front_end/testcases/control_flow_collection_inference.dart:179:63: Context: Write to index@5992 +pkg/front_end/testcases/control_flow_collection_inference.dart:196:63: Context: Write to index@6916 Set<int> set100 = <int>{for (index = 0; oracle("foo"); index++) 42}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:180:54: Context: Write to index@5992 +pkg/front_end/testcases/control_flow_collection_inference.dart:197:54: Context: Write to index@6916 Map<String, int> map100 = <String, int>{for (index = 0; oracle("foo"); index++) "bar": 42}; ^ -pkg/front_end/testcases/control_flow_collection_inference.dart:180:79: Context: Write to index@5992 +pkg/front_end/testcases/control_flow_collection_inference.dart:197:79: Context: Write to index@6916 Map<String, int> map100 = <String, int>{for (index = 0; oracle("foo"); index++) "bar": 42}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:190:41: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:204:48: Context: Write to i@7018 + List<int> list130 = [for (var i = 1; i < 2; i++) i]; + ^^ +pkg/front_end/testcases/control_flow_collection_inference.dart:205:46: Context: Write to i@7018 + Set<int> set130 = {for (var i = 1; i < 2; i++) i}; + ^^ +pkg/front_end/testcases/control_flow_collection_inference.dart:206:51: Context: Write to i@7018 + Map<int, int> map130 = {for (var i = 1; i < 2; i++) i: i}; + ^^ +pkg/front_end/testcases/control_flow_collection_inference.dart:210:41: Context: Write to i@13789 <int>[for (int i = 0; oracle("foo"); i++) "bar"]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:191:41: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:211:41: Context: Write to i@13789 <int>{for (int i = 0; oracle("foo"); i++) "bar", null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:192:46: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:212:46: Context: Write to i@13789 <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:193:41: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:213:41: Context: Write to i@13789 <int>[for (int i = 0; oracle("foo"); i++) ...["bar"]]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:194:41: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:214:41: Context: Write to i@13789 <int>{for (int i = 0; oracle("foo"); i++) ...["bar"], null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:195:46: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:215:46: Context: Write to i@13789 <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:196:41: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:216:41: Context: Write to i@13789 <int>[for (int i = 0; oracle("foo"); i++) ...map]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:197:41: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:217:41: Context: Write to i@13789 <int>{for (int i = 0; oracle("foo"); i++) ...map, null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:198:46: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:218:46: Context: Write to i@13789 <int, int>{for (int i = 0; oracle("foo"); i++) ...list, 42: null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:199:44: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:219:44: Context: Write to i@13789 <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:200:44: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:220:44: Context: Write to i@13789 <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:201:52: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:221:52: Context: Write to i@13789 <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:202:41: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:222:41: Context: Write to i@13789 <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:203:41: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:223:41: Context: Write to i@13789 <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:204:49: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:224:49: Context: Write to i@13789 <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:205:41: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:225:41: Context: Write to i@13789 <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map]; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:206:41: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:226:41: Context: Write to i@13789 <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null}; ^^ -pkg/front_end/testcases/control_flow_collection_inference.dart:207:49: Context: Write to i@12696 +pkg/front_end/testcases/control_flow_collection_inference.dart:227:49: Context: Write to i@13789 <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null}; ^^ +pkg/front_end/testcases/control_flow_collection_inference.dart:267:29: Context: Possible promotion of a@16609 + List<int> list10 = [if (a is B) a.foo]; + ^^ +pkg/front_end/testcases/control_flow_collection_inference.dart:268:27: Context: Possible promotion of a@16609 + Set<int> set10 = {if (a is B) a.foo}; + ^^ +pkg/front_end/testcases/control_flow_collection_inference.dart:269:32: Context: Possible promotion of a@16609 + Map<int, int> map10 = {if (a is B) a.foo: a.foo}; + ^^
diff --git a/pkg/front_end/testcases/duplicated_declarations.dart.legacy.expect b/pkg/front_end/testcases/duplicated_declarations.dart.legacy.expect index f1e837f..86ec30f 100644 --- a/pkg/front_end/testcases/duplicated_declarations.dart.legacy.expect +++ b/pkg/front_end/testcases/duplicated_declarations.dart.legacy.expect
@@ -2,12 +2,12 @@ // // Problems in library: // -// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must preceed part directives. +// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must precede part directives. // Try moving the import directives before the part directives. // import 'duplicated_declarations_lib.dart' as Typedef; // ^^^^^^ // -// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must preceed part directives. +// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must precede part directives. // Try moving the import directives before the part directives. // import 'duplicated_declarations_lib.dart' as Typedef; // ^^^^^^
diff --git a/pkg/front_end/testcases/duplicated_declarations.dart.legacy.transformed.expect b/pkg/front_end/testcases/duplicated_declarations.dart.legacy.transformed.expect index f1e837f..86ec30f 100644 --- a/pkg/front_end/testcases/duplicated_declarations.dart.legacy.transformed.expect +++ b/pkg/front_end/testcases/duplicated_declarations.dart.legacy.transformed.expect
@@ -2,12 +2,12 @@ // // Problems in library: // -// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must preceed part directives. +// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must precede part directives. // Try moving the import directives before the part directives. // import 'duplicated_declarations_lib.dart' as Typedef; // ^^^^^^ // -// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must preceed part directives. +// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must precede part directives. // Try moving the import directives before the part directives. // import 'duplicated_declarations_lib.dart' as Typedef; // ^^^^^^
diff --git a/pkg/front_end/testcases/duplicated_declarations.dart.outline.expect b/pkg/front_end/testcases/duplicated_declarations.dart.outline.expect index 63f345e..1933ac0 100644 --- a/pkg/front_end/testcases/duplicated_declarations.dart.outline.expect +++ b/pkg/front_end/testcases/duplicated_declarations.dart.outline.expect
@@ -2,12 +2,12 @@ // // Problems in library: // -// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must preceed part directives. +// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must precede part directives. // Try moving the import directives before the part directives. // import 'duplicated_declarations_lib.dart' as Typedef; // ^^^^^^ // -// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must preceed part directives. +// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must precede part directives. // Try moving the import directives before the part directives. // import 'duplicated_declarations_lib.dart' as Typedef; // ^^^^^^
diff --git a/pkg/front_end/testcases/duplicated_declarations.dart.strong.expect b/pkg/front_end/testcases/duplicated_declarations.dart.strong.expect index a51c4ba..6e8d2d8 100644 --- a/pkg/front_end/testcases/duplicated_declarations.dart.strong.expect +++ b/pkg/front_end/testcases/duplicated_declarations.dart.strong.expect
@@ -2,12 +2,12 @@ // // Problems in library: // -// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must preceed part directives. +// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must precede part directives. // Try moving the import directives before the part directives. // import 'duplicated_declarations_lib.dart' as Typedef; // ^^^^^^ // -// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must preceed part directives. +// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must precede part directives. // Try moving the import directives before the part directives. // import 'duplicated_declarations_lib.dart' as Typedef; // ^^^^^^
diff --git a/pkg/front_end/testcases/legacy.status b/pkg/front_end/testcases/legacy.status index 2489f9f..7fadc91 100644 --- a/pkg/front_end/testcases/legacy.status +++ b/pkg/front_end/testcases/legacy.status
@@ -113,6 +113,7 @@ regress/issue_35259: RuntimeError # Expected regress/issue_35260: RuntimeError # Expected regress/issue_35266: RuntimeError # Expected +regress/issue_36400: RuntimeError reject_generic_function_types_in_bounds: RuntimeError # Expected runtime_checks/implicit_downcast_constructor_initializer: RuntimeError # Test exercises strong mode semantics runtime_checks/implicit_downcast_do: RuntimeError # Test exercises strong mode semantics
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31155.dart.legacy.expect index 8130bfc..35b1ddf 100644 --- a/pkg/front_end/testcases/regress/issue_31155.dart.legacy.expect +++ b/pkg/front_end/testcases/regress/issue_31155.dart.legacy.expect
@@ -6,7 +6,7 @@ // var f = Map<A, B> {}; // ^ // -// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceeded by the keyword 'operator'. +// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceded by the keyword 'operator'. // Try adding the keyword 'operator'. // var f = Map<A, B> {}; // ^
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31155.dart.legacy.transformed.expect index 8130bfc..35b1ddf 100644 --- a/pkg/front_end/testcases/regress/issue_31155.dart.legacy.transformed.expect +++ b/pkg/front_end/testcases/regress/issue_31155.dart.legacy.transformed.expect
@@ -6,7 +6,7 @@ // var f = Map<A, B> {}; // ^ // -// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceeded by the keyword 'operator'. +// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceded by the keyword 'operator'. // Try adding the keyword 'operator'. // var f = Map<A, B> {}; // ^
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.outline.expect b/pkg/front_end/testcases/regress/issue_31155.dart.outline.expect index 31866e5..368d30d 100644 --- a/pkg/front_end/testcases/regress/issue_31155.dart.outline.expect +++ b/pkg/front_end/testcases/regress/issue_31155.dart.outline.expect
@@ -6,7 +6,7 @@ // var f = Map<A, B> {}; // ^ // -// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceeded by the keyword 'operator'. +// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceded by the keyword 'operator'. // Try adding the keyword 'operator'. // var f = Map<A, B> {}; // ^
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31155.dart.strong.expect index f9e661a..e6f0d60 100644 --- a/pkg/front_end/testcases/regress/issue_31155.dart.strong.expect +++ b/pkg/front_end/testcases/regress/issue_31155.dart.strong.expect
@@ -6,7 +6,7 @@ // var f = Map<A, B> {}; // ^ // -// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceeded by the keyword 'operator'. +// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceded by the keyword 'operator'. // Try adding the keyword 'operator'. // var f = Map<A, B> {}; // ^
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31155.dart.strong.transformed.expect index f9e661a..e6f0d60 100644 --- a/pkg/front_end/testcases/regress/issue_31155.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/regress/issue_31155.dart.strong.transformed.expect
@@ -6,7 +6,7 @@ // var f = Map<A, B> {}; // ^ // -// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceeded by the keyword 'operator'. +// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceded by the keyword 'operator'. // Try adding the keyword 'operator'. // var f = Map<A, B> {}; // ^
diff --git a/pkg/front_end/testcases/regress/issue_36400.dart b/pkg/front_end/testcases/regress/issue_36400.dart new file mode 100644 index 0000000..33c29d6 --- /dev/null +++ b/pkg/front_end/testcases/regress/issue_36400.dart
@@ -0,0 +1,10 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +class Test { + Test factory Test() { + return null; + } +} +
diff --git a/pkg/front_end/testcases/regress/issue_36400.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_36400.dart.hierarchy.expect new file mode 100644 index 0000000..6dc337c --- /dev/null +++ b/pkg/front_end/testcases/regress/issue_36400.dart.hierarchy.expect
@@ -0,0 +1,36 @@ +Object: + superclasses: + interfaces: + classMembers: + Object._haveSameRuntimeType + Object.toString + Object.runtimeType + Object._toString + Object._simpleInstanceOf + Object._hashCodeRnd + Object._instanceOf + Object.noSuchMethod + Object._objectHashCode + Object._identityHashCode + Object.hashCode + Object._simpleInstanceOfFalse + Object._simpleInstanceOfTrue + Object.== + classSetters: + +Test: + superclasses: + Object + interfaces: + classMembers: + Object.toString + Object.runtimeType + Object._simpleInstanceOf + Object._instanceOf + Object.noSuchMethod + Object._identityHashCode + Object.hashCode + Object._simpleInstanceOfFalse + Object._simpleInstanceOfTrue + Object.== + classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_36400.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_36400.dart.legacy.expect new file mode 100644 index 0000000..e63b720 --- /dev/null +++ b/pkg/front_end/testcases/regress/issue_36400.dart.legacy.expect
@@ -0,0 +1,17 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/regress/issue_36400.dart:6:3: Error: Factory constructors cannot have a return type. +// Try removing the type appearing before 'factory'. +// Test factory Test() { +// ^^^^ +// +import self as self; +import "dart:core" as core; + +class Test extends core::Object { + static factory •() → self::Test { + return null; + } +}
diff --git a/pkg/front_end/testcases/regress/issue_36400.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_36400.dart.legacy.transformed.expect new file mode 100644 index 0000000..e63b720 --- /dev/null +++ b/pkg/front_end/testcases/regress/issue_36400.dart.legacy.transformed.expect
@@ -0,0 +1,17 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/regress/issue_36400.dart:6:3: Error: Factory constructors cannot have a return type. +// Try removing the type appearing before 'factory'. +// Test factory Test() { +// ^^^^ +// +import self as self; +import "dart:core" as core; + +class Test extends core::Object { + static factory •() → self::Test { + return null; + } +}
diff --git a/pkg/front_end/testcases/regress/issue_36400.dart.outline.expect b/pkg/front_end/testcases/regress/issue_36400.dart.outline.expect new file mode 100644 index 0000000..2f39e53 --- /dev/null +++ b/pkg/front_end/testcases/regress/issue_36400.dart.outline.expect
@@ -0,0 +1,16 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/regress/issue_36400.dart:6:3: Error: Factory constructors cannot have a return type. +// Try removing the type appearing before 'factory'. +// Test factory Test() { +// ^^^^ +// +import self as self; +import "dart:core" as core; + +class Test extends core::Object { + static factory •() → self::Test + ; +}
diff --git a/pkg/front_end/testcases/regress/issue_36400.dart.strong.expect b/pkg/front_end/testcases/regress/issue_36400.dart.strong.expect new file mode 100644 index 0000000..e63b720 --- /dev/null +++ b/pkg/front_end/testcases/regress/issue_36400.dart.strong.expect
@@ -0,0 +1,17 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/regress/issue_36400.dart:6:3: Error: Factory constructors cannot have a return type. +// Try removing the type appearing before 'factory'. +// Test factory Test() { +// ^^^^ +// +import self as self; +import "dart:core" as core; + +class Test extends core::Object { + static factory •() → self::Test { + return null; + } +}
diff --git a/pkg/front_end/testcases/regress/issue_36400.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_36400.dart.strong.transformed.expect new file mode 100644 index 0000000..e63b720 --- /dev/null +++ b/pkg/front_end/testcases/regress/issue_36400.dart.strong.transformed.expect
@@ -0,0 +1,17 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/regress/issue_36400.dart:6:3: Error: Factory constructors cannot have a return type. +// Try removing the type appearing before 'factory'. +// Test factory Test() { +// ^^^^ +// +import self as self; +import "dart:core" as core; + +class Test extends core::Object { + static factory •() → self::Test { + return null; + } +}
diff --git a/pkg/front_end/testcases/spread_collection_inference.dart.strong.expect b/pkg/front_end/testcases/spread_collection_inference.dart.strong.expect index 7599faa..27a3664 100644 --- a/pkg/front_end/testcases/spread_collection_inference.dart.strong.expect +++ b/pkg/front_end/testcases/spread_collection_inference.dart.strong.expect
@@ -69,20 +69,10 @@ // spread]; // ^ // -// pkg/front_end/testcases/spread_collection_inference.dart:112:5: Error: A value of type 'int' can't be assigned to a variable of type 'String'. -// Try changing the type of the left hand side, or casting the right hand side to 'String'. -// spread]; -// ^ -// // pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'. // Set<String> set60 = <String>{... spread}; // ^ // -// pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: A value of type 'int' can't be assigned to a variable of type 'String'. -// Try changing the type of the left hand side, or casting the right hand side to 'String'. -// Set<String> set60 = <String>{... spread}; -// ^ -// // pkg/front_end/testcases/spread_collection_inference.dart:117:2: Error: Can't assign spread entry keys of type 'String' to map entry keys of type 'int'. // mapSpread}; // ^ @@ -310,18 +300,12 @@ core::Map<dynamic, dynamic> map50 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:109:2: Error: Unexpected type 'int Function()' of a map spread entry. Expected 'dynamic' or a Map. notSpreadFunction}; ^": null}; - core::List<core::String> lhs60 = <core::String>[let final<BottomType> #t64 = invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:112:5: Error: A value of type 'int' can't be assigned to a variable of type 'String'. -Try changing the type of the left hand side, or casting the right hand side to 'String'. + core::List<core::String> lhs60 = <core::String>[invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:112:5: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'. spread]; - ^" in invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:112:5: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'. - spread]; - ^" as{TypeError} core::String]; - core::Set<core::String> set60 = let final core::Set<core::String> #t65 = col::LinkedHashSet::•<core::String>() in let final dynamic #t66 = #t65.{core::Set::add}(let final<BottomType> #t67 = invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: A value of type 'int' can't be assigned to a variable of type 'String'. -Try changing the type of the left hand side, or casting the right hand side to 'String'. + ^"]; + core::Set<core::String> set60 = let final core::Set<core::String> #t64 = col::LinkedHashSet::•<core::String>() in let final dynamic #t65 = #t64.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'. Set<String> set60 = <String>{... spread}; - ^" in invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'. - Set<String> set60 = <String>{... spread}; - ^" as{TypeError} core::String) in #t65; + ^") in #t64; core::Map<core::int, core::int> map60 = <core::int, core::int>{invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:117:2: Error: Can't assign spread entry keys of type 'String' to map entry keys of type 'int'. mapSpread}; ^": null}; @@ -330,91 +314,91 @@ ^"}; core::List<core::int> lhs70 = <core::int>[invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:122:31: Error: Can't spread a value with static type Null. List<int> lhs70 = <int>[... null]; - ^" as{TypeError} core::int]; - core::Set<core::int> set70 = let final core::Set<core::int> #t68 = col::LinkedHashSet::•<core::int>() in let final dynamic #t69 = #t68.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:124:30: Error: Can't spread a value with static type Null. + ^"]; + core::Set<core::int> set70 = let final core::Set<core::int> #t66 = col::LinkedHashSet::•<core::int>() in let final dynamic #t67 = #t66.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:124:30: Error: Can't spread a value with static type Null. Set<int> set70 = <int>{... null}; - ^" as{TypeError} core::int) in #t68; + ^") in #t66; core::Set<dynamic> set71ambiguous = block { - final core::Set<dynamic> #t70 = col::LinkedHashSet::•<dynamic>(); - #t70.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:127:10: Error: Expected ',' before this. + final core::Set<dynamic> #t68 = col::LinkedHashSet::•<dynamic>(); + #t68.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:127:10: Error: Expected ',' before this. {... null, ... /*@typeArgs=dynamic*/ ^"); - for (final dynamic #t71 in <dynamic>[]) { - final dynamic #t72 = #t71 as{TypeError} dynamic; - #t70.{core::Set::add}(#t72); + for (final dynamic #t69 in <dynamic>[]) { + final dynamic #t70 = #t69 as{TypeError} dynamic; + #t68.{core::Set::add}(#t70); } - } =>#t70; + } =>#t68; core::Map<core::String, core::int> map70 = <core::String, core::int>{invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:131:5: Error: Can't spread a value with static type Null. null}; ^": null}; core::List<core::int> lhs80 = block { - final core::List<core::int> #t73 = <core::int>[]; - final dynamic #t74 = null; - if(!#t74.{core::Object::==}(null)) - for (final core::int #t75 in #t74) - #t73.{core::List::add}(#t75); - } =>#t73; + final core::List<core::int> #t71 = <core::int>[]; + final dynamic #t72 = null; + if(!#t72.{core::Object::==}(null)) + for (final core::int #t73 in #t72) + #t71.{core::List::add}(#t73); + } =>#t71; core::Set<core::int> set80 = block { - final core::Set<core::int> #t76 = col::LinkedHashSet::•<core::int>(); - final dynamic #t77 = null; - if(!#t77.{core::Object::==}(null)) - for (final core::int #t78 in #t77) - #t76.{core::Set::add}(#t78); - } =>#t76; + final core::Set<core::int> #t74 = col::LinkedHashSet::•<core::int>(); + final dynamic #t75 = null; + if(!#t75.{core::Object::==}(null)) + for (final core::int #t76 in #t75) + #t74.{core::Set::add}(#t76); + } =>#t74; core::Set<dynamic> set81ambiguous = block { - final core::Set<dynamic> #t79 = col::LinkedHashSet::•<dynamic>(); - final dynamic #t80 = null; - if(!#t80.{core::Object::==}(null)) - for (final dynamic #t81 in #t80) { - final dynamic #t82 = #t81 as{TypeError} dynamic; - #t79.{core::Set::add}(#t82); + final core::Set<dynamic> #t77 = col::LinkedHashSet::•<dynamic>(); + final dynamic #t78 = null; + if(!#t78.{core::Object::==}(null)) + for (final dynamic #t79 in #t78) { + final dynamic #t80 = #t79 as{TypeError} dynamic; + #t77.{core::Set::add}(#t80); } - for (final dynamic #t83 in <dynamic>[]) { - final dynamic #t84 = #t83 as{TypeError} dynamic; - #t79.{core::Set::add}(#t84); + for (final dynamic #t81 in <dynamic>[]) { + final dynamic #t82 = #t81 as{TypeError} dynamic; + #t77.{core::Set::add}(#t82); } - } =>#t79; + } =>#t77; core::Map<core::String, core::int> map80 = block { - final core::Map<core::String, core::int> #t85 = <core::String, core::int>{}; - final core::Map<dynamic, dynamic> #t86 = null; - if(!#t86.{core::Object::==}(null)) - for (final core::MapEntry<core::String, core::int> #t87 in #t86.{core::Map::entries}) - #t85.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value}); - } =>#t85; + final core::Map<core::String, core::int> #t83 = <core::String, core::int>{}; + final core::Map<dynamic, dynamic> #t84 = null; + if(!#t84.{core::Object::==}(null)) + for (final core::MapEntry<core::String, core::int> #t85 in #t84.{core::Map::entries}) + #t83.{core::Map::[]=}(#t85.{core::MapEntry::key}, #t85.{core::MapEntry::value}); + } =>#t83; core::Map<core::String, core::int> map90 = block { - final core::Map<core::String, core::int> #t88 = <core::String, core::int>{}; - for (final core::MapEntry<core::String, core::int> #t89 in self::bar<core::String, core::int>().{core::Map::entries}) - #t88.{core::Map::[]=}(#t89.{core::MapEntry::key}, #t89.{core::MapEntry::value}); - } =>#t88; + final core::Map<core::String, core::int> #t86 = <core::String, core::int>{}; + for (final core::MapEntry<core::String, core::int> #t87 in self::bar<core::String, core::int>().{core::Map::entries}) + #t86.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value}); + } =>#t86; core::List<core::int> list100 = block { - final core::List<core::int> #t90 = <core::int>[]; - for (final dynamic #t91 in listNum) { - final core::int #t92 = #t91 as{TypeError} core::int; - #t90.{core::List::add}(#t92); + final core::List<core::int> #t88 = <core::int>[]; + for (final dynamic #t89 in listNum) { + final core::int #t90 = #t89 as{TypeError} core::int; + #t88.{core::List::add}(#t90); } - } =>#t90; + } =>#t88; core::Map<core::num, core::int> map100 = block { - final core::Map<core::num, core::int> #t93 = <core::num, core::int>{}; - for (final core::MapEntry<dynamic, dynamic> #t94 in mapIntNum.{core::Map::entries}) { - final core::num #t95 = #t94.{core::MapEntry::key} as{TypeError} core::num; - final core::int #t96 = #t94.{core::MapEntry::value} as{TypeError} core::int; - #t93.{core::Map::[]=}(#t95, #t96); + final core::Map<core::num, core::int> #t91 = <core::num, core::int>{}; + for (final core::MapEntry<dynamic, dynamic> #t92 in mapIntNum.{core::Map::entries}) { + final core::num #t93 = #t92.{core::MapEntry::key} as{TypeError} core::num; + final core::int #t94 = #t92.{core::MapEntry::value} as{TypeError} core::int; + #t91.{core::Map::[]=}(#t93, #t94); } - } =>#t93; + } =>#t91; core::List<core::int> list110 = block { - final core::List<core::int> #t97 = <core::int>[]; - for (final dynamic #t98 in dynVar as{TypeError} core::Iterable<dynamic>) { - final core::int #t99 = #t98 as{TypeError} core::int; - #t97.{core::List::add}(#t99); + final core::List<core::int> #t95 = <core::int>[]; + for (final dynamic #t96 in dynVar as{TypeError} core::Iterable<dynamic>) { + final core::int #t97 = #t96 as{TypeError} core::int; + #t95.{core::List::add}(#t97); } - } =>#t97; + } =>#t95; core::Map<core::num, core::int> map110 = block { - final core::Map<core::num, core::int> #t100 = <core::num, core::int>{}; - for (final core::MapEntry<dynamic, dynamic> #t101 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) { - final core::num #t102 = #t101.{core::MapEntry::key} as{TypeError} core::num; - final core::int #t103 = #t101.{core::MapEntry::value} as{TypeError} core::int; - #t100.{core::Map::[]=}(#t102, #t103); + final core::Map<core::num, core::int> #t98 = <core::num, core::int>{}; + for (final core::MapEntry<dynamic, dynamic> #t99 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) { + final core::num #t100 = #t99.{core::MapEntry::key} as{TypeError} core::num; + final core::int #t101 = #t99.{core::MapEntry::value} as{TypeError} core::int; + #t98.{core::Map::[]=}(#t100, #t101); } - } =>#t100; + } =>#t98; } static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/spread_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/spread_collection_inference.dart.strong.transformed.expect index 3262225..838f328 100644 --- a/pkg/front_end/testcases/spread_collection_inference.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/spread_collection_inference.dart.strong.transformed.expect
@@ -69,20 +69,10 @@ // spread]; // ^ // -// pkg/front_end/testcases/spread_collection_inference.dart:112:5: Error: A value of type 'int' can't be assigned to a variable of type 'String'. -// Try changing the type of the left hand side, or casting the right hand side to 'String'. -// spread]; -// ^ -// // pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'. // Set<String> set60 = <String>{... spread}; // ^ // -// pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: A value of type 'int' can't be assigned to a variable of type 'String'. -// Try changing the type of the left hand side, or casting the right hand side to 'String'. -// Set<String> set60 = <String>{... spread}; -// ^ -// // pkg/front_end/testcases/spread_collection_inference.dart:117:2: Error: Can't assign spread entry keys of type 'String' to map entry keys of type 'int'. // mapSpread}; // ^ @@ -310,18 +300,12 @@ core::Map<dynamic, dynamic> map50 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:109:2: Error: Unexpected type 'int Function()' of a map spread entry. Expected 'dynamic' or a Map. notSpreadFunction}; ^": null}; - core::List<core::String> lhs60 = <core::String>[let final<BottomType> #t64 = invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:112:5: Error: A value of type 'int' can't be assigned to a variable of type 'String'. -Try changing the type of the left hand side, or casting the right hand side to 'String'. + core::List<core::String> lhs60 = <core::String>[invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:112:5: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'. spread]; - ^" in invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:112:5: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'. - spread]; - ^" as{TypeError} core::String]; - core::Set<core::String> set60 = let final core::Set<core::String> #t65 = col::LinkedHashSet::•<core::String>() in let final core::bool #t66 = #t65.{core::Set::add}(let final<BottomType> #t67 = invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: A value of type 'int' can't be assigned to a variable of type 'String'. -Try changing the type of the left hand side, or casting the right hand side to 'String'. + ^"]; + core::Set<core::String> set60 = let final core::Set<core::String> #t64 = col::LinkedHashSet::•<core::String>() in let final core::bool #t65 = #t64.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'. Set<String> set60 = <String>{... spread}; - ^" in invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'. - Set<String> set60 = <String>{... spread}; - ^" as{TypeError} core::String) in #t65; + ^") in #t64; core::Map<core::int, core::int> map60 = <core::int, core::int>{invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:117:2: Error: Can't assign spread entry keys of type 'String' to map entry keys of type 'int'. mapSpread}; ^": null}; @@ -330,91 +314,91 @@ ^"}; core::List<core::int> lhs70 = <core::int>[invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:122:31: Error: Can't spread a value with static type Null. List<int> lhs70 = <int>[... null]; - ^" as{TypeError} core::int]; - core::Set<core::int> set70 = let final core::Set<core::int> #t68 = col::LinkedHashSet::•<core::int>() in let final core::bool #t69 = #t68.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:124:30: Error: Can't spread a value with static type Null. + ^"]; + core::Set<core::int> set70 = let final core::Set<core::int> #t66 = col::LinkedHashSet::•<core::int>() in let final core::bool #t67 = #t66.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:124:30: Error: Can't spread a value with static type Null. Set<int> set70 = <int>{... null}; - ^" as{TypeError} core::int) in #t68; + ^") in #t66; core::Set<dynamic> set71ambiguous = block { - final core::Set<dynamic> #t70 = col::LinkedHashSet::•<dynamic>(); - #t70.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:127:10: Error: Expected ',' before this. + final core::Set<dynamic> #t68 = col::LinkedHashSet::•<dynamic>(); + #t68.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:127:10: Error: Expected ',' before this. {... null, ... /*@typeArgs=dynamic*/ ^"); - for (final dynamic #t71 in <dynamic>[]) { - final dynamic #t72 = #t71 as{TypeError} dynamic; - #t70.{core::Set::add}(#t72); + for (final dynamic #t69 in <dynamic>[]) { + final dynamic #t70 = #t69 as{TypeError} dynamic; + #t68.{core::Set::add}(#t70); } - } =>#t70; + } =>#t68; core::Map<core::String, core::int> map70 = <core::String, core::int>{invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:131:5: Error: Can't spread a value with static type Null. null}; ^": null}; core::List<core::int> lhs80 = block { - final core::List<core::int> #t73 = <core::int>[]; - final dynamic #t74 = null; - if(!#t74.{core::Object::==}(null)) - for (final core::int #t75 in #t74) - #t73.{core::List::add}(#t75); - } =>#t73; + final core::List<core::int> #t71 = <core::int>[]; + final dynamic #t72 = null; + if(!#t72.{core::Object::==}(null)) + for (final core::int #t73 in #t72) + #t71.{core::List::add}(#t73); + } =>#t71; core::Set<core::int> set80 = block { - final core::Set<core::int> #t76 = col::LinkedHashSet::•<core::int>(); - final dynamic #t77 = null; - if(!#t77.{core::Object::==}(null)) - for (final core::int #t78 in #t77) - #t76.{core::Set::add}(#t78); - } =>#t76; + final core::Set<core::int> #t74 = col::LinkedHashSet::•<core::int>(); + final dynamic #t75 = null; + if(!#t75.{core::Object::==}(null)) + for (final core::int #t76 in #t75) + #t74.{core::Set::add}(#t76); + } =>#t74; core::Set<dynamic> set81ambiguous = block { - final core::Set<dynamic> #t79 = col::LinkedHashSet::•<dynamic>(); - final dynamic #t80 = null; - if(!#t80.{core::Object::==}(null)) - for (final dynamic #t81 in #t80) { - final dynamic #t82 = #t81 as{TypeError} dynamic; - #t79.{core::Set::add}(#t82); + final core::Set<dynamic> #t77 = col::LinkedHashSet::•<dynamic>(); + final dynamic #t78 = null; + if(!#t78.{core::Object::==}(null)) + for (final dynamic #t79 in #t78) { + final dynamic #t80 = #t79 as{TypeError} dynamic; + #t77.{core::Set::add}(#t80); } - for (final dynamic #t83 in <dynamic>[]) { - final dynamic #t84 = #t83 as{TypeError} dynamic; - #t79.{core::Set::add}(#t84); + for (final dynamic #t81 in <dynamic>[]) { + final dynamic #t82 = #t81 as{TypeError} dynamic; + #t77.{core::Set::add}(#t82); } - } =>#t79; + } =>#t77; core::Map<core::String, core::int> map80 = block { - final core::Map<core::String, core::int> #t85 = <core::String, core::int>{}; - final core::Map<dynamic, dynamic> #t86 = null; - if(!#t86.{core::Object::==}(null)) - for (final core::MapEntry<core::String, core::int> #t87 in #t86.{core::Map::entries}) - #t85.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value}); - } =>#t85; + final core::Map<core::String, core::int> #t83 = <core::String, core::int>{}; + final core::Map<dynamic, dynamic> #t84 = null; + if(!#t84.{core::Object::==}(null)) + for (final core::MapEntry<core::String, core::int> #t85 in #t84.{core::Map::entries}) + #t83.{core::Map::[]=}(#t85.{core::MapEntry::key}, #t85.{core::MapEntry::value}); + } =>#t83; core::Map<core::String, core::int> map90 = block { - final core::Map<core::String, core::int> #t88 = <core::String, core::int>{}; - for (final core::MapEntry<core::String, core::int> #t89 in self::bar<core::String, core::int>().{core::Map::entries}) - #t88.{core::Map::[]=}(#t89.{core::MapEntry::key}, #t89.{core::MapEntry::value}); - } =>#t88; + final core::Map<core::String, core::int> #t86 = <core::String, core::int>{}; + for (final core::MapEntry<core::String, core::int> #t87 in self::bar<core::String, core::int>().{core::Map::entries}) + #t86.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value}); + } =>#t86; core::List<core::int> list100 = block { - final core::List<core::int> #t90 = <core::int>[]; - for (final dynamic #t91 in listNum) { - final core::int #t92 = #t91 as{TypeError} core::int; - #t90.{core::List::add}(#t92); + final core::List<core::int> #t88 = <core::int>[]; + for (final dynamic #t89 in listNum) { + final core::int #t90 = #t89 as{TypeError} core::int; + #t88.{core::List::add}(#t90); } - } =>#t90; + } =>#t88; core::Map<core::num, core::int> map100 = block { - final core::Map<core::num, core::int> #t93 = <core::num, core::int>{}; - for (final core::MapEntry<dynamic, dynamic> #t94 in mapIntNum.{core::Map::entries}) { - final core::num #t95 = #t94.{core::MapEntry::key} as{TypeError} core::num; - final core::int #t96 = #t94.{core::MapEntry::value} as{TypeError} core::int; - #t93.{core::Map::[]=}(#t95, #t96); + final core::Map<core::num, core::int> #t91 = <core::num, core::int>{}; + for (final core::MapEntry<dynamic, dynamic> #t92 in mapIntNum.{core::Map::entries}) { + final core::num #t93 = #t92.{core::MapEntry::key} as{TypeError} core::num; + final core::int #t94 = #t92.{core::MapEntry::value} as{TypeError} core::int; + #t91.{core::Map::[]=}(#t93, #t94); } - } =>#t93; + } =>#t91; core::List<core::int> list110 = block { - final core::List<core::int> #t97 = <core::int>[]; - for (final dynamic #t98 in dynVar as{TypeError} core::Iterable<dynamic>) { - final core::int #t99 = #t98 as{TypeError} core::int; - #t97.{core::List::add}(#t99); + final core::List<core::int> #t95 = <core::int>[]; + for (final dynamic #t96 in dynVar as{TypeError} core::Iterable<dynamic>) { + final core::int #t97 = #t96 as{TypeError} core::int; + #t95.{core::List::add}(#t97); } - } =>#t97; + } =>#t95; core::Map<core::num, core::int> map110 = block { - final core::Map<core::num, core::int> #t100 = <core::num, core::int>{}; - for (final core::MapEntry<dynamic, dynamic> #t101 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) { - final core::num #t102 = #t101.{core::MapEntry::key} as{TypeError} core::num; - final core::int #t103 = #t101.{core::MapEntry::value} as{TypeError} core::int; - #t100.{core::Map::[]=}(#t102, #t103); + final core::Map<core::num, core::int> #t98 = <core::num, core::int>{}; + for (final core::MapEntry<dynamic, dynamic> #t99 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) { + final core::num #t100 = #t99.{core::MapEntry::key} as{TypeError} core::num; + final core::int #t101 = #t99.{core::MapEntry::value} as{TypeError} core::int; + #t98.{core::Map::[]=}(#t100, #t101); } - } =>#t100; + } =>#t98; } static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status index d6443fb..7b802de 100644 --- a/pkg/front_end/testcases/strong.status +++ b/pkg/front_end/testcases/strong.status
@@ -141,6 +141,7 @@ regress/issue_35259: RuntimeError # Expected regress/issue_35260: RuntimeError # Expected regress/issue_35266: RuntimeError # Expected +regress/issue_36400: RuntimeError reject_generic_function_types_in_bounds: RuntimeError # Expected runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast: RuntimeError runtime_checks_new/mixin_forwarding_stub_field: TypeCheckError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status index 8e6529f..9da7144 100644 --- a/pkg/front_end/testcases/text_serialization.status +++ b/pkg/front_end/testcases/text_serialization.status
@@ -919,6 +919,7 @@ regress/issue_35260: TextSerializationFailure # Was: RuntimeError # Expected regress/issue_35266: TextSerializationFailure # Was: RuntimeError # Expected regress/issue_35900: TextSerializationFailure +regress/issue_36400: TextSerializationFailure reject_generic_function_types_in_bounds: TextSerializationFailure # Was: RuntimeError # Expected return_with_unknown_type_in_context: TextSerializationFailure # Was: Pass runtime_checks/call_kinds: TextSerializationFailure # Was: Pass
diff --git a/pkg/kernel/bin/transform.dart b/pkg/kernel/bin/transform.dart index d0019c3..f384400 100755 --- a/pkg/kernel/bin/transform.dart +++ b/pkg/kernel/bin/transform.dart
@@ -102,7 +102,8 @@ case 'constants': final VmConstantsBackend backend = new VmConstantsBackend(coreTypes); component = constants.transformComponent( - component, backend, defines, const constants.SimpleErrorReporter()); + component, backend, defines, const constants.SimpleErrorReporter(), + enableAsserts: true); break; case 'methodcall': component =
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md index 91d9ae1..76c12be 100644 --- a/pkg/kernel/binary.md +++ b/pkg/kernel/binary.md
@@ -139,7 +139,7 @@ type ComponentFile { UInt32 magic = 0x90ABCDEF; - UInt32 formatVersion = 22; + UInt32 formatVersion = 23; List<String> problemsAsJson; // Described in problems.md. Library[] libraries; UriSource sourceMap; @@ -720,6 +720,15 @@ List<Expression> maps; } +type InstanceCreation extends Expression { + Byte tag = 114; + FileOffset fileOffset; + CanonicalNameReference class; + List<DartType> typeArguments; + List<[FieldReference, Expression]> fieldValues; + List<AssertStatement> asserts; +} + type IsExpression extends Expression { Byte tag = 37; FileOffset fileOffset;
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart index 8e41e89..140a9e4 100644 --- a/pkg/kernel/lib/ast.dart +++ b/pkg/kernel/lib/ast.dart
@@ -2211,6 +2211,9 @@ while (type is TypeParameterType) { type = (type as TypeParameterType).parameter.bound; } + if (type == types.nullType) { + return superclass.bottomType; + } if (type is InterfaceType) { var upcastType = types.getTypeAsInstanceOf(type, superclass); if (upcastType != null) return upcastType; @@ -3314,6 +3317,56 @@ } } +/// Create an instance directly from the field values. +/// +/// This expression arises from const constructor calls when one or more field +/// initializing expressions, field initializers or assert initializers contain +/// unevaluated expressions. They only ever occur within unevaluated constants +/// in constant expressions. +class InstanceCreation extends Expression { + final Reference classReference; + final List<DartType> typeArguments; + final Map<Reference, Expression> fieldValues; + final List<AssertStatement> asserts; + + InstanceCreation( + this.classReference, this.typeArguments, this.fieldValues, this.asserts); + + Class get classNode => classReference.asClass; + + DartType getStaticType(TypeEnvironment types) { + return typeArguments.isEmpty + ? classNode.rawType + : new InterfaceType(classNode, typeArguments); + } + + accept(ExpressionVisitor v) => v.visitInstanceCreation(this); + accept1(ExpressionVisitor1 v, arg) => v.visitInstanceCreation(this, arg); + + visitChildren(Visitor v) { + classReference.asClass.acceptReference(v); + visitList(typeArguments, v); + for (final Reference reference in fieldValues.keys) { + reference.asField.acceptReference(v); + } + for (final Expression value in fieldValues.values) { + value.accept(v); + } + visitList(asserts, v); + } + + transformChildren(Transformer v) { + fieldValues.forEach((Reference fieldRef, Expression value) { + Expression transformed = value.accept(v); + if (transformed != null && !identical(value, transformed)) { + fieldValues[fieldRef] = transformed; + transformed.parent = this; + } + }); + transformList(asserts, v, this); + } +} + /// Expression of form `x is T`. class IsExpression extends Expression { Expression operand; @@ -3443,7 +3496,7 @@ class NullLiteral extends BasicLiteral { Object get value => null; - DartType getStaticType(TypeEnvironment types) => const BottomType(); + DartType getStaticType(TypeEnvironment types) => types.nullType; accept(ExpressionVisitor v) => v.visitNullLiteral(this); accept1(ExpressionVisitor1 v, arg) => v.visitNullLiteral(this, arg);
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart index 6306cef..ad088c0 100644 --- a/pkg/kernel/lib/binary/ast_from_binary.dart +++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -1534,6 +1534,26 @@ return new MapConcatenation(readExpressionList(), keyType: keyType, valueType: valueType) ..fileOffset = offset; + case Tag.InstanceCreation: + int offset = readOffset(); + Reference classReference = readClassReference(); + List<DartType> typeArguments = readDartTypeList(); + int fieldValueCount = readUInt(); + Map<Reference, Expression> fieldValues = <Reference, Expression>{}; + for (int i = 0; i < fieldValueCount; i++) { + final Reference fieldRef = + readCanonicalNameReference().getReference(); + final Expression value = readExpression(); + fieldValues[fieldRef] = value; + } + int assertCount = readUInt(); + List<AssertStatement> asserts = new List<AssertStatement>(assertCount); + for (int i = 0; i < assertCount; i++) { + asserts[i] = readStatement(); + } + return new InstanceCreation( + classReference, typeArguments, fieldValues, asserts) + ..fileOffset = offset; case Tag.IsExpression: int offset = readOffset(); return new IsExpression(readExpression(), readDartType())
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart index a0619f6..2b9baba 100644 --- a/pkg/kernel/lib/binary/ast_to_binary.dart +++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -1503,6 +1503,20 @@ } @override + void visitInstanceCreation(InstanceCreation node) { + writeByte(Tag.InstanceCreation); + writeOffset(node.fileOffset); + writeNonNullReference(node.classReference); + writeNodeList(node.typeArguments); + writeUInt30(node.fieldValues.length); + node.fieldValues.forEach((Reference fieldRef, Expression value) { + writeNonNullReference(fieldRef); + writeNode(value); + }); + writeNodeList(node.asserts); + } + + @override void visitIsExpression(IsExpression node) { writeByte(Tag.IsExpression); writeOffset(node.fileOffset);
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart index 9650fa7..42200e1 100644 --- a/pkg/kernel/lib/binary/tag.dart +++ b/pkg/kernel/lib/binary/tag.dart
@@ -53,6 +53,7 @@ static const int ListConcatenation = 111; static const int SetConcatenation = 112; static const int MapConcatenation = 113; + static const int InstanceCreation = 114; static const int IsExpression = 37; static const int AsExpression = 38; static const int StringLiteral = 39; @@ -129,6 +130,7 @@ /// 111 is occupied by [ListConcatenation] (expression). /// 112 is occupied by [SetConcatenation] (expression). /// 113 is occupied by [MapConcatenation] (expression). + /// 114 is occupied by [InstanceCreation] (expression). static const int SpecializedTagHighBit = 0x80; // 10000000 static const int SpecializedTagMask = 0xF8; // 11111000 @@ -145,7 +147,7 @@ /// Internal version of kernel binary format. /// Bump it when making incompatible changes in kernel binaries. /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md. - static const int BinaryFormatVersion = 22; + static const int BinaryFormatVersion = 23; } abstract class ConstantTag {
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart index 4105a43..fd3bb4d 100644 --- a/pkg/kernel/lib/clone.dart +++ b/pkg/kernel/lib/clone.dart
@@ -205,6 +205,18 @@ keyType: visitType(node.keyType), valueType: visitType(node.valueType)); } + visitInstanceCreation(InstanceCreation node) { + final Map<Reference, Expression> fieldValues = <Reference, Expression>{}; + node.fieldValues.forEach((Reference fieldRef, Expression value) { + fieldValues[fieldRef] = clone(value); + }); + return new InstanceCreation( + node.classReference, + node.typeArguments.map(visitType).toList(), + fieldValues, + node.asserts.map(clone).toList()); + } + visitIsExpression(IsExpression node) { return new IsExpression(clone(node.operand), visitType(node.type)); }
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart index 8d957f4..5862b83 100644 --- a/pkg/kernel/lib/text/ast_to_text.dart +++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -1302,6 +1302,39 @@ } } + visitInstanceCreation(InstanceCreation node) { + write('${node.classNode}'); + if (node.typeArguments.isNotEmpty) { + writeSymbol('<'); + writeList(node.typeArguments, writeType); + writeSymbol('>'); + } + write(' {'); + bool first = true; + node.fieldValues.forEach((Reference fieldRef, Expression value) { + if (!first) { + writeComma(); + } + write('${fieldRef.asField.name}: '); + writeExpression(value); + first = false; + }); + for (AssertStatement assert_ in node.asserts) { + if (!first) { + writeComma(); + } + write('assert('); + writeExpression(assert_.condition); + if (assert_.message != null) { + writeComma(); + writeExpression(assert_.message); + } + write(')'); + } + + write('}'); + } + visitIsExpression(IsExpression node) { writeExpression(node.operand, Precedence.BITWISE_OR); writeSpaced('is'); @@ -2014,10 +2047,10 @@ node.fieldValues.forEach((Reference fieldRef, Constant constant) { final String name = syntheticNames.nameConstant(constant); if (!first) { - first = false; sb.write(', '); } sb.write('${fieldRef.asField.name}: $name'); + first = false; }); sb.write('}'); endLine(sb.toString());
diff --git a/pkg/kernel/lib/text/text_serialization_verifier.dart b/pkg/kernel/lib/text/text_serialization_verifier.dart index b9f2662..3fed367 100644 --- a/pkg/kernel/lib/text/text_serialization_verifier.dart +++ b/pkg/kernel/lib/text/text_serialization_verifier.dart
@@ -390,6 +390,12 @@ } @override + void visitInstanceCreation(InstanceCreation node) { + storeLastSeenUriAndOffset(node); + node.visitChildren(this); + } + + @override void visitSymbolConstant(SymbolConstant node) { storeLastSeenUriAndOffset(node); node.visitChildren(this);
diff --git a/pkg/kernel/lib/transformations/async.dart b/pkg/kernel/lib/transformations/async.dart index dbdca9b..3ea9fe2 100644 --- a/pkg/kernel/lib/transformations/async.dart +++ b/pkg/kernel/lib/transformations/async.dart
@@ -90,13 +90,11 @@ /// surrounding context. Expression rewrite(Expression expression, List<Statement> outer) { assert(statements.isEmpty); - assert(nameIndex == 0); var saved = seenAwait; seenAwait = false; Expression result = expression.accept(this); outer.addAll(statements.reversed); statements.clear(); - nameIndex = 0; seenAwait = seenAwait || saved; return result; }
diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart index 7f04bce..f81ec66 100644 --- a/pkg/kernel/lib/type_checker.dart +++ b/pkg/kernel/lib/type_checker.dart
@@ -713,6 +713,18 @@ } @override + DartType visitInstanceCreation(InstanceCreation node) { + Substitution substitution = Substitution.fromPairs( + node.classNode.typeParameters, node.typeArguments); + node.fieldValues.forEach((Reference fieldRef, Expression value) { + DartType fieldType = substitution.substituteType(fieldRef.asField.type); + DartType valueType = visitExpression(value); + checkAssignable(node, fieldType, valueType); + }); + return new InterfaceType(node.classNode, node.typeArguments); + } + + @override DartType visitStringLiteral(StringLiteral node) { return environment.stringType; }
diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart index 388f3cf..b1a9938 100644 --- a/pkg/kernel/lib/visitor.dart +++ b/pkg/kernel/lib/visitor.dart
@@ -41,6 +41,7 @@ R visitListConcatenation(ListConcatenation node) => defaultExpression(node); R visitSetConcatenation(SetConcatenation node) => defaultExpression(node); R visitMapConcatenation(MapConcatenation node) => defaultExpression(node); + R visitInstanceCreation(InstanceCreation node) => defaultExpression(node); R visitIsExpression(IsExpression node) => defaultExpression(node); R visitAsExpression(AsExpression node) => defaultExpression(node); R visitSymbolLiteral(SymbolLiteral node) => defaultExpression(node); @@ -167,6 +168,7 @@ R visitListConcatenation(ListConcatenation node) => defaultExpression(node); R visitSetConcatenation(SetConcatenation node) => defaultExpression(node); R visitMapConcatenation(MapConcatenation node) => defaultExpression(node); + R visitInstanceCreation(InstanceCreation node) => defaultExpression(node); R visitIsExpression(IsExpression node) => defaultExpression(node); R visitAsExpression(AsExpression node) => defaultExpression(node); R visitSymbolLiteral(SymbolLiteral node) => defaultExpression(node); @@ -510,6 +512,8 @@ defaultExpression(node, arg); R visitMapConcatenation(MapConcatenation node, T arg) => defaultExpression(node, arg); + R visitInstanceCreation(InstanceCreation node, T arg) => + defaultExpression(node, arg); R visitIsExpression(IsExpression node, T arg) => defaultExpression(node, arg); R visitAsExpression(AsExpression node, T arg) => defaultExpression(node, arg); R visitSymbolLiteral(SymbolLiteral node, T arg) =>
diff --git a/pkg/vm/bin/compare_sizes.dart b/pkg/vm/bin/compare_sizes.dart index 691566e..6c41417 100644 --- a/pkg/vm/bin/compare_sizes.dart +++ b/pkg/vm/bin/compare_sizes.dart
@@ -157,6 +157,7 @@ } return sb.toString() + '\n' + sb.toString(); } + return null; // Make analyzer happy. } } @@ -209,6 +210,7 @@ final diff = width - value.length; return ' ' * (diff ~/ 2) + value + (' ' * (diff - diff ~/ 2)); } + return null; // Make analyzer happy. } int get length => value.length;
diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart index a8d8cb0..0686cd6 100644 --- a/pkg/vm/lib/bytecode/assembler.dart +++ b/pkg/vm/lib/bytecode/assembler.dart
@@ -423,4 +423,9 @@ void emitEntryOptional(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kEntryOptional, ra, rb, rc)); } + + void emitAllocateClosure(int rd) { + emitSourcePosition(); + emitWord(_encodeD(Opcode.kAllocateClosure, rd)); + } }
diff --git a/pkg/vm/lib/bytecode/constant_pool.dart b/pkg/vm/lib/bytecode/constant_pool.dart index 18b1ac1..3e204ae 100644 --- a/pkg/vm/lib/bytecode/constant_pool.dart +++ b/pkg/vm/lib/bytecode/constant_pool.dart
@@ -4,8 +4,6 @@ library vm.bytecode.constant_pool; -import 'dart:typed_data'; - import 'package:kernel/ast.dart' hide MapEntry; import 'dbc.dart' show constantPoolIndexLimit, BytecodeLimitExceededException; @@ -33,39 +31,6 @@ Byte tag; } -type ConstantNull extends ConstantPoolEntry { - Byte tag = 1; -} - -type ConstantString extends ConstantPoolEntry { - Byte tag = 2; - PackedString value; -} - -type ConstantInt extends ConstantPoolEntry { - Byte tag = 3; - UInt32 low; - UInt32 high; -} - -type ConstantDouble extends ConstantPoolEntry { - Byte tag = 4; - UInt32 low; - UInt32 high; -} - -type ConstantBool extends ConstantPoolEntry { - Byte tag = 5; - Byte flag; -} - -type ConstantArgDesc extends ConstantPoolEntry { - Byte tag = 6; - UInt numArguments; - UInt numTypeArgs; - List<PackedString> names; -} - enum InvocationKind { method, // x.foo(...) or foo(...) getter, // x.foo @@ -80,12 +45,6 @@ ConstantIndex argDesc; } -type ConstantStaticICData extends ConstantPoolEntry { - Byte tag = 8; - PackedObject target; - ConstantIndex argDesc; -} - type ConstantStaticField extends ConstantPoolEntry { Byte tag = 9; PackedObject field; @@ -107,40 +66,11 @@ PackedObject class; } -type ConstantTearOff extends ConstantPoolEntry { - Byte tag = 13; - PackedObject target; -} - type ConstantType extends ConstantPoolEntry { Byte tag = 14; PackedObject type; } -type ConstantTypeArguments extends ConstantPoolEntry { - Byte tag = 15; - List<PackedObject> types; -} - -type ConstantList extends ConstantPoolEntry { - Byte tag = 16; - PackedObject typeArg; - List<ConstantIndex> entries; -} - -type ConstantInstance extends ConstantPoolEntry { - Byte tag = 17; - PackedObject class; - ConstantIndex typeArguments; - List<Pair<PackedObject, ConstantIndex>> fieldValues; -} - -type ConstantTypeArgumentsForInstanceAllocation extends ConstantPoolEntry { - Byte tag = 18; - PackedObject instantiatingClass; - List<PackedObject> types; -} - type ConstantClosureFunction extends ConstantPoolEntry { Byte tag = 19; UInt closureIndex; @@ -159,30 +89,10 @@ Byte tag = 22; } -type ConstantPartialTearOffInstantiation extends ConstantPoolEntry { - Byte tag = 23; - ConstantIndex tearOffConstant; - ConstantIndex typeArguments; -} - type ConstantEmptyTypeArguments extends ConstantPoolEntry { Byte tag = 24; } -type ConstantSymbol extends ConstantPoolEntry { - Byte tag = 25; - PackedObject name; -} - -// Occupies 2 entries in the constant pool. -type ConstantInterfaceCallV1 extends ConstantPoolEntry { - Byte tag = 26; - Byte flags(invocationKindBit0, invocationKindBit1); - // Where invocationKind is index into InvocationKind. - PackedObject targetName; - ConstantIndex argDesc; -} - type ConstantObjectRef extends ConstantPoolEntry { Byte tag = 27; PackedObject object; @@ -206,32 +116,32 @@ enum ConstantTag { kInvalid, - kNull, // TODO(alexmarkov): obsolete, remove - kString, // TODO(alexmarkov): obsolete, remove - kInt, // TODO(alexmarkov): obsolete, remove - kDouble, // TODO(alexmarkov): obsolete, remove - kBool, // TODO(alexmarkov): obsolete, remove - kArgDesc, // TODO(alexmarkov): obsolete, remove + kUnused1, + kUnused2, + kUnused3, + kUnused4, + kUnused5, + kUnused6, kICData, - kStaticICData, // TODO(alexmarkov): obsolete, remove + kUnused7, kStaticField, kInstanceField, kClass, kTypeArgumentsField, - kTearOff, // TODO(alexmarkov): obsolete, remove + kUnused8, kType, - kTypeArguments, // TODO(alexmarkov): obsolete, remove - kList, // TODO(alexmarkov): obsolete, remove - kInstance, // TODO(alexmarkov): obsolete, remove - kTypeArgumentsForInstanceAllocation, // TODO(alexmarkov): obsolete, remove + kUnused9, + kUnused10, + kUnused11, + kUnused12, kClosureFunction, kEndClosureFunctionScope, kNativeEntry, kSubtypeTestCache, - kPartialTearOffInstantiation, // TODO(alexmarkov): obsolete, remove + kUnused13, kEmptyTypeArguments, - kSymbol, // TODO(alexmarkov): obsolete, remove - kInterfaceCallV1, // TODO(alexmarkov): obsolete, remove + kUnused14, + kUnused15, kObjectRef, kDirectCall, kInterfaceCall, @@ -261,22 +171,8 @@ switch (tag) { case ConstantTag.kInvalid: break; - case ConstantTag.kNull: - return new ConstantNull.read(reader); - case ConstantTag.kString: - return new ConstantString.read(reader); - case ConstantTag.kInt: - return new ConstantInt.read(reader); - case ConstantTag.kDouble: - return new ConstantDouble.read(reader); - case ConstantTag.kBool: - return new ConstantBool.read(reader); case ConstantTag.kICData: return new ConstantICData.read(reader); - case ConstantTag.kStaticICData: - return new ConstantStaticICData.read(reader); - case ConstantTag.kArgDesc: - return new ConstantArgDesc.read(reader); case ConstantTag.kStaticField: return new ConstantStaticField.read(reader); case ConstantTag.kInstanceField: @@ -285,18 +181,8 @@ return new ConstantClass.read(reader); case ConstantTag.kTypeArgumentsField: return new ConstantTypeArgumentsField.read(reader); - case ConstantTag.kTearOff: - return new ConstantTearOff.read(reader); case ConstantTag.kType: return new ConstantType.read(reader); - case ConstantTag.kTypeArguments: - return new ConstantTypeArguments.read(reader); - case ConstantTag.kList: - return new ConstantList.read(reader); - case ConstantTag.kInstance: - return new ConstantInstance.read(reader); - case ConstantTag.kTypeArgumentsForInstanceAllocation: - return new ConstantTypeArgumentsForInstanceAllocation.read(reader); case ConstantTag.kClosureFunction: return new ConstantClosureFunction.read(reader); case ConstantTag.kEndClosureFunctionScope: @@ -305,225 +191,36 @@ return new ConstantNativeEntry.read(reader); case ConstantTag.kSubtypeTestCache: return new ConstantSubtypeTestCache.read(reader); - case ConstantTag.kPartialTearOffInstantiation: - return new ConstantPartialTearOffInstantiation.read(reader); case ConstantTag.kEmptyTypeArguments: return new ConstantEmptyTypeArguments.read(reader); - case ConstantTag.kSymbol: - return new ConstantSymbol.read(reader); - case ConstantTag.kInterfaceCallV1: - return new ConstantInterfaceCallV1.read(reader); case ConstantTag.kObjectRef: return new ConstantObjectRef.read(reader); case ConstantTag.kDirectCall: return new ConstantDirectCall.read(reader); case ConstantTag.kInterfaceCall: return new ConstantInterfaceCall.read(reader); + // Make analyzer happy. + case ConstantTag.kUnused1: + case ConstantTag.kUnused2: + case ConstantTag.kUnused3: + case ConstantTag.kUnused4: + case ConstantTag.kUnused5: + case ConstantTag.kUnused6: + case ConstantTag.kUnused7: + case ConstantTag.kUnused8: + case ConstantTag.kUnused9: + case ConstantTag.kUnused10: + case ConstantTag.kUnused11: + case ConstantTag.kUnused12: + case ConstantTag.kUnused13: + case ConstantTag.kUnused14: + case ConstantTag.kUnused15: + break; } throw 'Unexpected constant tag $tag'; } } -class ConstantNull extends ConstantPoolEntry { - const ConstantNull(); - - @override - ConstantTag get tag => ConstantTag.kNull; - - @override - void writeValue(BufferedWriter writer) {} - - ConstantNull.read(BufferedReader reader); - - @override - String toString() => 'Null'; - - @override - int get hashCode => 1961; - - @override - bool operator ==(other) => other is ConstantNull; -} - -class ConstantString extends ConstantPoolEntry { - final String value; - - ConstantString(this.value); - ConstantString.fromLiteral(StringLiteral literal) : this(literal.value); - - @override - ConstantTag get tag => ConstantTag.kString; - - @override - void writeValue(BufferedWriter writer) { - writer.writePackedStringReference(value); - } - - ConstantString.read(BufferedReader reader) - : value = reader.readPackedStringReference(); - - @override - String toString() => 'String \'$value\''; - - @override - int get hashCode => value.hashCode; - - @override - bool operator ==(other) => - other is ConstantString && this.value == other.value; -} - -class ConstantInt extends ConstantPoolEntry { - final int value; - - ConstantInt(this.value); - - @override - ConstantTag get tag => ConstantTag.kInt; - - @override - void writeValue(BufferedWriter writer) { - // TODO(alexmarkov): more efficient encoding - writer.writeUInt32(value & 0xffffffff); - writer.writeUInt32((value >> 32) & 0xffffffff); - } - - ConstantInt.read(BufferedReader reader) - : value = reader.readUInt32() | (reader.readUInt32() << 32); - - @override - String toString() => 'Int $value'; - - @override - int get hashCode => value; - - @override - bool operator ==(other) => other is ConstantInt && this.value == other.value; -} - -class ConstantDouble extends ConstantPoolEntry { - final double value; - - ConstantDouble(this.value); - - @override - ConstantTag get tag => ConstantTag.kDouble; - - static int doubleToIntBits(double value) { - final buf = new ByteData(8); - buf.setFloat64(0, value, Endian.host); - return buf.getInt64(0, Endian.host); - } - - static double intBitsToDouble(int bits) { - final buf = new ByteData(8); - buf.setInt64(0, bits, Endian.host); - return buf.getFloat64(0, Endian.host); - } - - @override - void writeValue(BufferedWriter writer) { - // TODO(alexmarkov): more efficient encoding - int bits = doubleToIntBits(value); - writer.writeUInt32(bits & 0xffffffff); - writer.writeUInt32((bits >> 32) & 0xffffffff); - } - - ConstantDouble.read(BufferedReader reader) - : value = - intBitsToDouble(reader.readUInt32() | (reader.readUInt32() << 32)); - - @override - String toString() => 'Double $value'; - - @override - int get hashCode => value.hashCode; - - @override - bool operator ==(other) => - other is ConstantDouble && value.compareTo(other.value) == 0; -} - -class ConstantBool extends ConstantPoolEntry { - final bool value; - - ConstantBool(this.value); - ConstantBool.fromLiteral(BoolLiteral literal) : this(literal.value); - - @override - ConstantTag get tag => ConstantTag.kBool; - - @override - void writeValue(BufferedWriter writer) { - writer.writeByte(value ? 1 : 0); - } - - ConstantBool.read(BufferedReader reader) : value = reader.readByte() != 0; - - @override - String toString() => 'Bool $value'; - - @override - int get hashCode => value.hashCode; - - @override - bool operator ==(other) => other is ConstantBool && this.value == other.value; -} - -class ConstantArgDesc extends ConstantPoolEntry { - final int numArguments; - final int numTypeArgs; - final List<String> argNames; - - ConstantArgDesc(this.numArguments, this.numTypeArgs, this.argNames); - - ConstantArgDesc.fromArguments( - Arguments args, bool hasReceiver, bool isFactory) - : this( - args.positional.length + - args.named.length + - (hasReceiver ? 1 : 0) + - // VM expects that type arguments vector passed to a factory - // constructor is counted in numArguments, and not counted in - // numTypeArgs. - // TODO(alexmarkov): Clean this up. - (isFactory ? 1 : 0), - isFactory ? 0 : args.types.length, - new List<String>.from(args.named.map((ne) => ne.name))); - - @override - ConstantTag get tag => ConstantTag.kArgDesc; - - @override - void writeValue(BufferedWriter writer) { - writer.writePackedUInt30(numArguments); - writer.writePackedUInt30(numTypeArgs); - writer.writePackedUInt30(argNames.length); - argNames.forEach(writer.writePackedStringReference); - } - - ConstantArgDesc.read(BufferedReader reader) - : numArguments = reader.readPackedUInt30(), - numTypeArgs = reader.readPackedUInt30(), - argNames = new List<String>.generate(reader.readPackedUInt30(), - (_) => reader.readPackedStringReference()); - - @override - String toString() => - 'ArgDesc num-args $numArguments, num-type-args $numTypeArgs, names $argNames'; - - @override - int get hashCode => _combineHashes( - _combineHashes(numArguments, numTypeArgs), listHashCode(argNames)); - - @override - bool operator ==(other) => - other is ConstantArgDesc && - this.numArguments == other.numArguments && - this.numTypeArgs == other.numTypeArgs && - listEquals(this.argNames, other.argNames); -} - enum InvocationKind { method, getter, setter } String _invocationKindToString(InvocationKind kind) { @@ -587,40 +284,6 @@ bool operator ==(other) => identical(this, other); } -class ConstantStaticICData extends ConstantPoolEntry { - final ObjectHandle target; - final int argDescConstantIndex; - - ConstantStaticICData(this.target, this.argDescConstantIndex); - - @override - ConstantTag get tag => ConstantTag.kStaticICData; - - @override - void writeValue(BufferedWriter writer) { - writer.writePackedObject(target); - writer.writePackedUInt30(argDescConstantIndex); - } - - ConstantStaticICData.read(BufferedReader reader) - : target = reader.readPackedObject(), - argDescConstantIndex = reader.readPackedUInt30(); - - @override - String toString() => 'StaticICData ' - 'target \'$target\', arg-desc CP#$argDescConstantIndex'; - - // ConstantStaticICData entries are created per call site and should not be - // merged, so ConstantStaticICData class uses identity [hashCode] and - // [operator ==]. - - @override - int get hashCode => identityHashCode(this); - - @override - bool operator ==(other) => identical(this, other); -} - class ConstantStaticField extends ConstantPoolEntry { final ObjectHandle field; @@ -732,33 +395,6 @@ this.classHandle == other.classHandle; } -class ConstantTearOff extends ConstantPoolEntry { - final ObjectHandle procedure; - - ConstantTearOff(this.procedure); - - @override - ConstantTag get tag => ConstantTag.kTearOff; - - @override - void writeValue(BufferedWriter writer) { - writer.writePackedObject(procedure); - } - - ConstantTearOff.read(BufferedReader reader) - : procedure = reader.readPackedObject(); - - @override - String toString() => 'TearOff $procedure'; - - @override - int get hashCode => procedure.hashCode; - - @override - bool operator ==(other) => - other is ConstantTearOff && this.procedure == other.procedure; -} - class ConstantType extends ConstantPoolEntry { final ObjectHandle type; @@ -784,158 +420,6 @@ bool operator ==(other) => other is ConstantType && this.type == other.type; } -class ConstantTypeArguments extends ConstantPoolEntry { - final List<ObjectHandle> typeArgs; - - ConstantTypeArguments(this.typeArgs); - - @override - ConstantTag get tag => ConstantTag.kTypeArguments; - - @override - void writeValue(BufferedWriter writer) { - writer.writePackedList(typeArgs); - } - - ConstantTypeArguments.read(BufferedReader reader) - : typeArgs = reader.readPackedList(); - - @override - String toString() => 'TypeArgs $typeArgs'; - - @override - int get hashCode => listHashCode(typeArgs); - - @override - bool operator ==(other) => - other is ConstantTypeArguments && - listEquals(this.typeArgs, other.typeArgs); -} - -class ConstantList extends ConstantPoolEntry { - final ObjectHandle typeArg; - final List<int> entries; - - ConstantList(this.typeArg, this.entries); - - @override - ConstantTag get tag => ConstantTag.kList; - - @override - void writeValue(BufferedWriter writer) { - writer.writePackedObject(typeArg); - writer.writePackedUInt30(entries.length); - entries.forEach(writer.writePackedUInt30); - } - - ConstantList.read(BufferedReader reader) - : typeArg = reader.readPackedObject(), - entries = new List<int>.generate( - reader.readPackedUInt30(), (_) => reader.readPackedUInt30()); - - @override - String toString() => 'List type-arg $typeArg, entries CP# $entries'; - - @override - int get hashCode => typeArg.hashCode ^ listHashCode(entries); - - @override - bool operator ==(other) => - other is ConstantList && - this.typeArg == other.typeArg && - listEquals(this.entries, other.entries); -} - -class ConstantInstance extends ConstantPoolEntry { - final ObjectHandle classHandle; - final int _typeArgumentsConstantIndex; - final Map<ObjectHandle, int> _fieldValues; - - ConstantInstance( - this.classHandle, this._typeArgumentsConstantIndex, this._fieldValues); - - @override - ConstantTag get tag => ConstantTag.kInstance; - - @override - void writeValue(BufferedWriter writer) { - writer.writePackedObject(classHandle); - writer.writePackedUInt30(_typeArgumentsConstantIndex); - writer.writePackedUInt30(_fieldValues.length); - _fieldValues.forEach((ObjectHandle field, int valueIndex) { - writer.writePackedObject(field); - writer.writePackedUInt30(valueIndex); - }); - } - - ConstantInstance.read(BufferedReader reader) - : classHandle = reader.readPackedObject(), - _typeArgumentsConstantIndex = reader.readPackedUInt30(), - _fieldValues = new Map<ObjectHandle, int>() { - final fieldValuesLen = reader.readPackedUInt30(); - for (int i = 0; i < fieldValuesLen; i++) { - final field = reader.readPackedObject(); - final valueIndex = reader.readPackedUInt30(); - _fieldValues[field] = valueIndex; - } - } - - @override - String toString() { - final values = _fieldValues.map<String, String>( - (ObjectHandle field, int valueIndex) => - new MapEntry(field.toString(), 'CP#$valueIndex')); - return 'Instance $classHandle type-args CP#$_typeArgumentsConstantIndex $values'; - } - - @override - int get hashCode => _combineHashes( - _combineHashes(classHandle.hashCode, _typeArgumentsConstantIndex), - mapHashCode(_fieldValues)); - - @override - bool operator ==(other) => - other is ConstantInstance && - this.classHandle == other.classHandle && - this._typeArgumentsConstantIndex == other._typeArgumentsConstantIndex && - mapEquals(this._fieldValues, other._fieldValues); -} - -class ConstantTypeArgumentsForInstanceAllocation extends ConstantPoolEntry { - final ObjectHandle instantiatingClass; - final List<ObjectHandle> typeArgs; - - ConstantTypeArgumentsForInstanceAllocation( - this.instantiatingClass, this.typeArgs); - - @override - ConstantTag get tag => ConstantTag.kTypeArgumentsForInstanceAllocation; - - @override - void writeValue(BufferedWriter writer) { - writer.writePackedObject(instantiatingClass); - writer.writePackedList(typeArgs); - } - - ConstantTypeArgumentsForInstanceAllocation.read(BufferedReader reader) - : instantiatingClass = reader.readPackedObject(), - typeArgs = reader.readPackedList(); - - @override - String toString() => - 'TypeArgumentsForInstanceAllocation $instantiatingClass $typeArgs'; - - @override - int get hashCode => - _combineHashes(instantiatingClass.hashCode, listHashCode(typeArgs)); - - @override - bool operator ==(other) => - other is ConstantTypeArgumentsForInstanceAllocation && - this.instantiatingClass == other.instantiatingClass && - listEquals(this.typeArgs, other.typeArgs); -} - class ConstantClosureFunction extends ConstantPoolEntry { final int closureIndex; @@ -1037,42 +521,6 @@ bool operator ==(other) => identical(this, other); } -class ConstantPartialTearOffInstantiation extends ConstantPoolEntry { - final int tearOffConstantIndex; - final int typeArgumentsConstantIndex; - - ConstantPartialTearOffInstantiation( - this.tearOffConstantIndex, this.typeArgumentsConstantIndex); - - @override - ConstantTag get tag => ConstantTag.kPartialTearOffInstantiation; - - @override - void writeValue(BufferedWriter writer) { - writer.writePackedUInt30(tearOffConstantIndex); - writer.writePackedUInt30(typeArgumentsConstantIndex); - } - - ConstantPartialTearOffInstantiation.read(BufferedReader reader) - : tearOffConstantIndex = reader.readPackedUInt30(), - typeArgumentsConstantIndex = reader.readPackedUInt30(); - - @override - String toString() { - return 'PartialTearOffInstantiation tear-off CP#$tearOffConstantIndex type-args CP#$typeArgumentsConstantIndex'; - } - - @override - int get hashCode => - _combineHashes(tearOffConstantIndex, typeArgumentsConstantIndex); - - @override - bool operator ==(other) => - other is ConstantPartialTearOffInstantiation && - this.tearOffConstantIndex == other.tearOffConstantIndex && - this.typeArgumentsConstantIndex == other.typeArgumentsConstantIndex; -} - class ConstantEmptyTypeArguments extends ConstantPoolEntry { const ConstantEmptyTypeArguments(); @@ -1094,75 +542,6 @@ bool operator ==(other) => other is ConstantEmptyTypeArguments; } -class ConstantSymbol extends ConstantPoolEntry { - final ObjectHandle name; - - ConstantSymbol(this.name); - - @override - ConstantTag get tag => ConstantTag.kSymbol; - - @override - void writeValue(BufferedWriter writer) { - writer.writePackedObject(name); - } - - ConstantSymbol.read(BufferedReader reader) : name = reader.readPackedObject(); - - @override - String toString() => 'Symbol $name'; - - @override - int get hashCode => name.hashCode; - - @override - bool operator ==(other) => other is ConstantSymbol && this.name == other.name; -} - -class ConstantInterfaceCallV1 extends ConstantPoolEntry { - final InvocationKind invocationKind; - final ObjectHandle targetName; - final int argDescConstantIndex; - - ConstantInterfaceCallV1( - this.invocationKind, this.targetName, this.argDescConstantIndex); - - // Reserve 1 extra slot for arguments descriptor, following target name slot. - int get numReservedEntries => 1; - - @override - ConstantTag get tag => ConstantTag.kInterfaceCallV1; - - @override - void writeValue(BufferedWriter writer) { - writer.writeByte(invocationKind.index); - writer.writePackedObject(targetName); - writer.writePackedUInt30(argDescConstantIndex); - } - - ConstantInterfaceCallV1.read(BufferedReader reader) - : invocationKind = InvocationKind.values[reader.readByte()], - targetName = reader.readPackedObject(), - argDescConstantIndex = reader.readPackedUInt30(); - - @override - String toString() => 'InterfaceCallV1 ' - '${_invocationKindToString(invocationKind)}' - 'target-name $targetName, arg-desc CP#$argDescConstantIndex'; - - @override - int get hashCode => _combineHashes( - _combineHashes(invocationKind.index, targetName.hashCode), - argDescConstantIndex); - - @override - bool operator ==(other) => - other is ConstantInterfaceCallV1 && - this.invocationKind == other.invocationKind && - this.targetName == other.targetName && - this.argDescConstantIndex == other.argDescConstantIndex; -} - class ConstantObjectRef extends ConstantPoolEntry { final ObjectHandle object;
diff --git a/pkg/vm/lib/bytecode/dbc.dart b/pkg/vm/lib/bytecode/dbc.dart index f9b3aa8..8702add 100644 --- a/pkg/vm/lib/bytecode/dbc.dart +++ b/pkg/vm/lib/bytecode/dbc.dart
@@ -10,7 +10,7 @@ /// Before bumping current bytecode version format, make sure that /// all users have switched to a VM which is able to consume new /// version of bytecode. -const int currentBytecodeFormatVersion = 3; +const int currentBytecodeFormatVersion = 4; /// Version of experimental / bleeding edge bytecode format. /// Produced by bytecode generator when --use-future-bytecode-format @@ -123,6 +123,8 @@ kCompareIntLe, kDirectCall, + + kAllocateClosure, } enum Encoding { @@ -300,6 +302,8 @@ Encoding.k0, const [Operand.none, Operand.none, Operand.none]), Opcode.kDirectCall: const Format( Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]), + Opcode.kAllocateClosure: const Format( + Encoding.kD, const [Operand.lit, Operand.none, Operand.none]), }; // Should match constant in runtime/vm/stack_frame_dbc.h.
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart index 6770f3a..0e54ba3 100644 --- a/pkg/vm/lib/bytecode/gen_bytecode.dart +++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -1745,10 +1745,7 @@ void _genAllocateClosureInstance( TreeNode node, int closureFunctionIndex, FunctionNode function) { - // TODO(alexmarkov): Consider adding a bytecode to allocate closure. - - assert(closureClass.typeParameters.isEmpty); - asm.emitAllocate(cp.addClass(closureClass)); + asm.emitAllocateClosure(closureFunctionIndex); final int temp = locals.tempIndexInFrame(node); asm.emitStoreLocal(temp); @@ -2151,19 +2148,22 @@ _genTypeArguments([node.typeArgument]); - _genDupTOS(locals.tempIndexInFrame(node)); + if (node.expressions.isEmpty) { + asm.emitPushConstant( + cp.addObjectRef(new ListConstant(const DynamicType(), const []))); + } else { + _genDupTOS(locals.tempIndexInFrame(node)); + _genPushInt(node.expressions.length); + asm.emitCreateArrayTOS(); + final int temp = locals.tempIndexInFrame(node); + asm.emitStoreLocal(temp); - // TODO(alexmarkov): gen more efficient code for empty array - _genPushInt(node.expressions.length); - asm.emitCreateArrayTOS(); - final int temp = locals.tempIndexInFrame(node); - asm.emitStoreLocal(temp); - - for (int i = 0; i < node.expressions.length; i++) { - asm.emitPush(temp); - _genPushInt(i); - _generateNode(node.expressions[i]); - asm.emitStoreIndexedTOS(); + for (int i = 0; i < node.expressions.length; i++) { + asm.emitPush(temp); + _genPushInt(i); + _generateNode(node.expressions[i]); + asm.emitStoreIndexedTOS(); + } } // List._fromLiteral is a factory constructor. @@ -2702,6 +2702,14 @@ } @override + visitBlockExpression(BlockExpression node) { + _enterScope(node); + _generateNodeList(node.body.statements); + _generateNode(node.value); + _leaveScope(); + } + + @override visitBreakStatement(BreakStatement node) { final targetLabel = labeledStatements[node.target] ?? (throw 'Target label ${node.target} was not registered for break $node');
diff --git a/pkg/vm/lib/bytecode/local_vars.dart b/pkg/vm/lib/bytecode/local_vars.dart index d365fd2..5d3862d 100644 --- a/pkg/vm/lib/bytecode/local_vars.dart +++ b/pkg/vm/lib/bytecode/local_vars.dart
@@ -598,6 +598,16 @@ } @override + visitBlockExpression(BlockExpression node) { + // Not using _visitWithScope as Block inside BlockExpression does not have + // a scope. + _enterScope(node); + visitList(node.body.statements, this); + node.value.accept(this); + _leaveScope(); + } + + @override visitAssertBlock(AssertBlock node) { _visitWithScope(node); } @@ -1037,6 +1047,15 @@ } @override + visitBlockExpression(BlockExpression node) { + // Not using _visit as Block inside BlockExpression does not have a scope. + _enterScope(node); + visitList(node.body.statements, this); + node.value.accept(this); + _leaveScope(); + } + + @override visitAssertBlock(AssertBlock node) { _visit(node, scope: true); }
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart index 28d0cd0..dfc4b67 100644 --- a/pkg/vm/lib/kernel_front_end.dart +++ b/pkg/vm/lib/kernel_front_end.dart
@@ -57,6 +57,8 @@ show transformComponent; import 'transformations/no_dynamic_invocations_annotator.dart' as no_dynamic_invocations_annotator show transformComponent; +import 'transformations/protobuf_aware_treeshaker/transformer.dart' + as protobuf_tree_shaker; import 'transformations/type_flow/transformer.dart' as globalTypeFlow show transformComponent; import 'transformations/obfuscation_prohibitions_annotator.dart' @@ -93,6 +95,9 @@ help: 'Enable global type flow analysis and related transformations in AOT mode.', defaultsTo: true); + args.addFlag('protobuf-tree-shaker', + help: 'Enable protobuf tree shaker transformation in AOT mode.', + defaultsTo: false); args.addMultiOption('define', abbr: 'D', help: 'The values for the environment constants (e.g. -Dkey=value).'); @@ -118,6 +123,8 @@ help: 'Generate bytecode in the bleeding edge format', defaultsTo: false); args.addMultiOption('enable-experiment', help: 'Comma separated list of experimental features to enable.'); + args.addFlag('help', + abbr: 'h', negatable: false, help: 'Print this help message.'); } /// Create ArgParser and populate it with options consumed by [runCompiler]. @@ -136,6 +143,11 @@ Future<int> runCompiler(ArgResults options, String usage) async { final String platformKernel = options['platform']; + if (options['help']) { + print(usage); + return successExitCode; + } + if ((options.rest.length != 1) || (platformKernel == null)) { print(usage); return badUsageExitCode; @@ -159,6 +171,7 @@ final bool useFutureBytecodeFormat = options['use-future-bytecode-format']; final bool enableAsserts = options['enable-asserts']; final bool enableConstantEvaluation = options['enable-constant-evaluation']; + final bool useProtobufTreeShaker = options['protobuf-tree-shaker']; final bool splitOutputByPackages = options['split-output-by-packages']; final bool showBytecodeSizeStat = options['show-bytecode-size-stat']; final List<String> experimentalFlags = options['enable-experiment']; @@ -217,7 +230,8 @@ dropAST: dropAST && !splitOutputByPackages, useFutureBytecodeFormat: useFutureBytecodeFormat, enableAsserts: enableAsserts, - enableConstantEvaluation: enableConstantEvaluation); + enableConstantEvaluation: enableConstantEvaluation, + useProtobufTreeShaker: useProtobufTreeShaker); errorPrinter.printCompilationMessages(); @@ -276,30 +290,36 @@ bool dropAST: false, bool useFutureBytecodeFormat: false, bool enableAsserts: false, - bool enableConstantEvaluation: true}) async { + bool enableConstantEvaluation: true, + bool useProtobufTreeShaker: false}) async { // Replace error handler to detect if there are compilation errors. final errorDetector = new ErrorDetector(previousErrorHandler: options.onDiagnostic); options.onDiagnostic = errorDetector; - final component = await kernelForProgram(source, options); - - // If we don't default back to the current VM we'll add environment defines - // for the core libraries. - if (component != null && environmentDefines != null) { - if (environmentDefines['dart.vm.product'] == 'true') { - environmentDefines['dart.developer.causal_async_stacks'] = 'false'; - } - environmentDefines['dart.isVM'] = 'true'; - for (final library in component.libraries) { - if (library.importUri.scheme == 'dart') { - final path = library.importUri.path; - if (!path.startsWith('_')) { - environmentDefines['dart.library.${path}'] = 'true'; - } + // TODO(alexmarkov): move this logic into VmTarget and call from front-end + // in order to have the same defines when compiling platform. + assert(environmentDefines != null); + if (environmentDefines['dart.vm.product'] == 'true') { + environmentDefines['dart.developer.causal_async_stacks'] = 'false'; + } + environmentDefines['dart.isVM'] = 'true'; + // TODO(dartbug.com/36460): Derive dart.library.* definitions from platform. + for (String library in options.target.extraRequiredLibraries) { + Uri libraryUri = Uri.parse(library); + if (libraryUri.scheme == 'dart') { + final path = libraryUri.path; + if (!path.startsWith('_')) { + environmentDefines['dart.library.${path}'] = 'true'; } } } + // dart:core is not mentioned in Target.extraRequiredLibraries. + environmentDefines['dart.library.core'] = 'true'; + + options.environmentDefines = environmentDefines; + + final component = await kernelForProgram(source, options); // Run global transformations only if component is correct. if (aot && component != null) { @@ -311,6 +331,7 @@ environmentDefines, enableAsserts, enableConstantEvaluation, + useProtobufTreeShaker, errorDetector); } @@ -342,6 +363,7 @@ Map<String, String> environmentDefines, bool enableAsserts, bool enableConstantEvaluation, + bool useProtobufTreeShaker, ErrorDetector errorDetector) async { if (errorDetector.hasCompilationErrors) return; @@ -371,6 +393,18 @@ no_dynamic_invocations_annotator.transformComponent(component); } + if (useProtobufTreeShaker) { + if (!useGlobalTypeFlowAnalysis) { + throw 'Protobuf tree shaker requires type flow analysis (--tfa)'; + } + + protobuf_tree_shaker.removeUnusedProtoReferences( + component, coreTypes, null); + + globalTypeFlow.transformComponent( + compilerOptions.target, coreTypes, component); + } + // TODO(35069): avoid recomputing CSA by reading it from the platform files. void ignoreAmbiguousSupertypes(cls, a, b) {} final hierarchy = new ClassHierarchy(component,
diff --git a/pkg/vm/lib/target/flutter_runner.dart b/pkg/vm/lib/target/flutter_runner.dart index 3ffde3c..9266f3a 100644 --- a/pkg/vm/lib/target/flutter_runner.dart +++ b/pkg/vm/lib/target/flutter_runner.dart
@@ -43,6 +43,5 @@ 'dart:fuchsia', 'dart:vmservice_io', 'dart:ui', - 'dart:mozart.internal', ]; }
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart index ba4e06d..bcbf5fa 100644 --- a/pkg/vm/lib/transformations/ffi.dart +++ b/pkg/vm/lib/transformations/ffi.dart
@@ -89,6 +89,7 @@ final Library ffiLibrary; final Class nativeFunctionClass; final Class pointerClass; + final Class structClass; final Procedure castMethod; final Procedure loadMethod; final Procedure storeMethod; @@ -110,6 +111,7 @@ ffiLibrary = index.getLibrary('dart:ffi'), nativeFunctionClass = index.getClass('dart:ffi', 'NativeFunction'), pointerClass = index.getClass('dart:ffi', 'Pointer'), + structClass = index.getClass('dart:ffi', 'Struct'), castMethod = index.getMember('dart:ffi', 'Pointer', 'cast'), loadMethod = index.getMember('dart:ffi', 'Pointer', 'load'), storeMethod = index.getMember('dart:ffi', 'Pointer', 'store'),
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart index 32ff1f4..ad38a18 100644 --- a/pkg/vm/lib/transformations/ffi_definitions.dart +++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -360,6 +360,8 @@ } bool _hasAnnotation(Class node) { + // Pre constant 2018 update. + // TODO(dacoharkes): Remove pre constant 2018 after constants change landed. for (Expression e in node.annotations) { if (e is StaticGet) { if (e.target == structField) { @@ -367,7 +369,12 @@ } } } - return false; + Iterable<Class> postConstant2018 = node.annotations + .whereType<ConstantExpression>() + .map((expr) => expr.constant) + .whereType<InstanceConstant>() + .map((constant) => constant.classNode); + return postConstant2018.contains(structClass); } void _preventTreeShaking(Class node) { @@ -386,11 +393,20 @@ } Iterable<NativeType> _getAnnotations(Field node) { - return node.annotations + Iterable<NativeType> preConstant2018 = node.annotations .whereType<ConstructorInvocation>() .map((expr) => expr.target.parent) .map((klass) => _getFieldType(klass)) .where((type) => type != null); + Iterable<NativeType> postConstant2018 = node.annotations + .whereType<ConstantExpression>() + .map((expr) => expr.constant) + .whereType<InstanceConstant>() + .map((constant) => constant.classNode) + .map((klass) => _getFieldType(klass)) + .where((type) => type != null); + // TODO(dacoharkes): Remove preConstant2018 after constants change landed. + return postConstant2018.followedBy(preConstant2018); } }
diff --git a/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart b/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart index 9034c55..1aa352e 100644 --- a/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart +++ b/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart
@@ -43,7 +43,7 @@ void _treeshakeProtos(Target target, Component component, CoreTypes coreTypes, TransformationInfo info) { globalTypeFlow.transformComponent(target, coreTypes, component); - final collector = _removeUnusedProtoReferences(component, coreTypes, info); + final collector = removeUnusedProtoReferences(component, coreTypes, info); if (collector == null) { return; } @@ -59,7 +59,7 @@ component.metadata.clear(); } -InfoCollector _removeUnusedProtoReferences( +InfoCollector removeUnusedProtoReferences( Component component, CoreTypes coreTypes, TransformationInfo info) { final protobufUri = Uri.parse('package:protobuf/protobuf.dart'); final protobufLibs =
diff --git a/pkg/vm/lib/transformations/type_flow/types.dart b/pkg/vm/lib/transformations/type_flow/types.dart index 9904fa7..9c52e34 100644 --- a/pkg/vm/lib/transformations/type_flow/types.dart +++ b/pkg/vm/lib/transformations/type_flow/types.dart
@@ -118,6 +118,17 @@ return new Type.nullableAny(); } else if (dartType == const BottomType()) { return new Type.nullable(new Type.empty()); + } else if ( + // Recognize Null type and use a more precise representation which + // doesn't need type specialization. + // TODO(alexmarkov): figure out where exactly approximation happens if + // Null is represented as Nullable(Cone(Null)) instead of + // Nullable(Empty). + dartType is InterfaceType && + dartType.classNode.name == 'Null' && + dartType.classNode.enclosingLibrary.importUri.scheme == 'dart' && + dartType.classNode.enclosingLibrary.importUri.path == 'core') { + return new Type.nullable(new Type.empty()); } return new Type.nullable(new ConeType(dartType)); }
diff --git a/pkg/vm/test/frontend_server_test.dart b/pkg/vm/test/frontend_server_test.dart index 3ff0a6c..5310517 100644 --- a/pkg/vm/test/frontend_server_test.dart +++ b/pkg/vm/test/frontend_server_test.dart
@@ -538,8 +538,8 @@ mainFile .writeAsStringSync("import 'lib.dart'; main() => print(foo);\n"); inputStreamController.add('recompile ${mainFile.path} abc\n' - '${mainFile.uri}\n' - 'abc\n' + '${mainFile.uri}\n' + 'abc\n' .codeUnits); count += 1; } else if (count == 1) { @@ -597,8 +597,8 @@ inputStreamController.add('accept\n'.codeUnits); mainFile.writeAsStringSync("main() => print('foo');\n"); inputStreamController.add('recompile ${mainFile.path} abc\n' - '${mainFile.uri}\n' - 'abc\n' + '${mainFile.uri}\n' + 'abc\n' .codeUnits); count += 1; } else if (count == 1) { @@ -687,8 +687,8 @@ file.writeAsStringSync("import 'lib.dart'; main() => foo();\n"); inputStreamController.add('recompile ${file.path} abc\n' - '${file.path}\n' - 'abc\n' + '${file.path}\n' + 'abc\n' .codeUnits); count += 1; @@ -757,8 +757,8 @@ var file2 = new File('${tempDir.path}/bar.dart')..createSync(); file2.writeAsStringSync("main() {}\n"); inputStreamController.add('recompile ${file2.path} abc\n' - '${file2.path}\n' - 'abc\n' + '${file2.path}\n' + 'abc\n' .codeUnits); } else { expect(count, 1); @@ -853,8 +853,8 @@ inputStreamController.add('reset\n'.codeUnits); inputStreamController.add('recompile ${fileB.path} abc\n' - '${fileB.path}\n' - 'abc\n' + '${fileB.path}\n' + 'abc\n' .codeUnits); break; case 1: @@ -925,8 +925,8 @@ var file2 = new File('${tempDir.path}/bar.dart')..createSync(); file2.writeAsStringSync("main() { baz(); }\n"); inputStreamController.add('recompile ${file2.uri} abc\n' - '${file2.uri}\n' - 'abc\n' + '${file2.uri}\n' + 'abc\n' .codeUnits); break; case 1: @@ -938,8 +938,8 @@ var file2 = new File('${tempDir.path}/bar.dart')..createSync(); file2.writeAsStringSync("main() { }\n"); inputStreamController.add('recompile ${file2.uri} abc\n' - '${file2.uri}\n' - 'abc\n' + '${file2.uri}\n' + 'abc\n' .codeUnits); break; case 2: @@ -1132,7 +1132,7 @@ inputStreamController.add('accept\n'.codeUnits); inputStreamController.add('reset\n'.codeUnits); inputStreamController.add('recompile ${dart2js.path} x$count\n' - 'x$count\n' + 'x$count\n' .codeUnits); } else if (count == 1) { // Restart. Expect full kernel file. @@ -1157,7 +1157,7 @@ // Reload with no changes inputStreamController.add('accept\n'.codeUnits); inputStreamController.add('recompile ${dart2js.path} x$count\n' - 'x$count\n' + 'x$count\n' .codeUnits); } else if (count == 2) { // Partial file. Expect to be empty. @@ -1174,8 +1174,8 @@ // Reload with 1 change inputStreamController.add('accept\n'.codeUnits); inputStreamController.add('recompile ${dart2js.path} x$count\n' - '${dart2jsOtherFile.uri}\n' - 'x$count\n' + '${dart2jsOtherFile.uri}\n' + 'x$count\n' .codeUnits); } else if (count == 3) { // Partial file. Expect to not be empty.
diff --git a/pkg/vm/test/incremental_compiler_test.dart b/pkg/vm/test/incremental_compiler_test.dart index a280c93..2b714ec 100644 --- a/pkg/vm/test/incremental_compiler_test.dart +++ b/pkg/vm/test/incremental_compiler_test.dart
@@ -408,6 +408,7 @@ vm = await Process.start(Platform.resolvedExecutable, <String>[ "--pause-isolates-on-exit", "--enable-vm-service:0", + "--disable-service-auth-codes", list.path ]); @@ -469,6 +470,7 @@ '--trace_reload_verbose', '--enable-vm-service=0', // Note: use 0 to avoid port collisions. '--pause_isolates_on_start', + '--disable-service-auth-codes', outputFile.path ]; final vm = await Process.start(Platform.resolvedExecutable, vmArgs);
diff --git a/pkg/vm/testcases/bytecode/async.dart.expect b/pkg/vm/testcases/bytecode/async.dart.expect index 3a89af2..cce2837 100644 --- a/pkg/vm/testcases/bytecode/async.dart.expect +++ b/pkg/vm/testcases/bytecode/async.dart.expect
@@ -15,20 +15,20 @@ Bytecode { Entry 3 CheckStack 0 - Allocate CP#20 + AllocateClosure CP#0 StoreLocal r2 Push r2 PushNull - StoreFieldTOS CP#21 + StoreFieldTOS CP#20 Push r2 PushNull - StoreFieldTOS CP#23 + StoreFieldTOS CP#22 Push r2 - PushConstant CP#25 - StoreFieldTOS CP#26 + PushConstant CP#24 + StoreFieldTOS CP#25 Push r2 PushConstant CP#0 - StoreFieldTOS CP#28 + StoreFieldTOS CP#27 Push r2 Push r0 StoreFieldTOS CP#1 @@ -55,27 +55,26 @@ [17] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names [] [18] = Reserved [19] = EndClosureFunctionScope - [20] = Class dart:core::_Closure - [21] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [22] = Reserved - [23] = InstanceField dart:core::_Closure::_function_type_arguments (field) - [24] = Reserved - [25] = EmptyTypeArguments - [26] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) - [27] = Reserved - [28] = InstanceField dart:core::_Closure::_function (field) - [29] = Reserved - [30] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names [] - [31] = Reserved - [32] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] - [33] = Reserved - [34] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] - [35] = Reserved - [36] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] - [37] = ICData dynamic target-name 'start', arg-desc CP#36 - [38] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names [] - [39] = Reserved - [40] = EndClosureFunctionScope + [20] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [21] = Reserved + [22] = InstanceField dart:core::_Closure::_function_type_arguments (field) + [23] = Reserved + [24] = EmptyTypeArguments + [25] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) + [26] = Reserved + [27] = InstanceField dart:core::_Closure::_function (field) + [28] = Reserved + [29] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names [] + [30] = Reserved + [31] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] + [32] = Reserved + [33] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] + [34] = Reserved + [35] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] + [36] = ICData dynamic target-name 'start', arg-desc CP#35 + [37] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names [] + [38] = Reserved + [39] = EndClosureFunctionScope } Closure #lib::asyncInFieldInitializer (field)::'<anonymous closure>' (dart:async::Future < dart:core::int > x) -> dart:async::Future < dart:core::Null > ClosureCode { @@ -126,47 +125,47 @@ PushNull StoreContextVar 0, 7 Push r0 - Allocate CP#20 + AllocateClosure CP#10 StoreLocal r2 Push r2 PushNull - StoreFieldTOS CP#21 + StoreFieldTOS CP#20 Push r2 PushNull - StoreFieldTOS CP#23 + StoreFieldTOS CP#22 Push r2 - PushConstant CP#25 - StoreFieldTOS CP#26 + PushConstant CP#24 + StoreFieldTOS CP#25 Push r2 PushConstant CP#10 - StoreFieldTOS CP#28 + StoreFieldTOS CP#27 Push r2 Push r0 StoreFieldTOS CP#1 StoreContextVar 0, 8 Push r0 LoadContextVar 0, 8 - DirectCall 1, CP#30 + DirectCall 1, CP#29 PopLocal r3 Push r0 Push r0 LoadContextVar 0, 8 - DirectCall 1, CP#32 + DirectCall 1, CP#31 StoreContextVar 0, 3 Push r0 Push r0 LoadContextVar 0, 8 - DirectCall 1, CP#34 + DirectCall 1, CP#33 StoreContextVar 0, 4 Push r0 LoadContextVar 0, 1 Push r0 LoadContextVar 0, 8 - DynamicCall 2, CP#37 + DynamicCall 2, CP#36 Drop1 Push r0 LoadContextVar 0, 1 - InterfaceCall 1, CP#38 + InterfaceCall 1, CP#37 ReturnTOS } @@ -294,41 +293,41 @@ Push r0 PushNull StoreContextVar 0, 3 - Allocate CP#14 + AllocateClosure CP#4 StoreLocal r2 Push r2 PushNull - StoreFieldTOS CP#15 + StoreFieldTOS CP#14 Push r2 PushNull - StoreFieldTOS CP#17 + StoreFieldTOS CP#16 Push r2 - PushConstant CP#19 - StoreFieldTOS CP#20 + PushConstant CP#18 + StoreFieldTOS CP#19 Push r2 PushConstant CP#4 - StoreFieldTOS CP#22 + StoreFieldTOS CP#21 Push r2 Push r0 StoreFieldTOS CP#6 PopLocal r6 Push r6 - DirectCall 1, CP#24 + DirectCall 1, CP#23 PopLocal r3 Push r6 - DirectCall 1, CP#26 + DirectCall 1, CP#25 PopLocal r4 Push r6 - DirectCall 1, CP#28 + DirectCall 1, CP#27 PopLocal r5 Push r0 LoadContextVar 0, 0 Push r6 - DynamicCall 2, CP#31 + DynamicCall 2, CP#30 Drop1 Push r0 LoadContextVar 0, 0 - InterfaceCall 1, CP#32 + InterfaceCall 1, CP#31 ReturnTOS } ConstantPool { @@ -346,26 +345,25 @@ [11] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names [] [12] = Reserved [13] = EndClosureFunctionScope - [14] = Class dart:core::_Closure - [15] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [16] = Reserved - [17] = InstanceField dart:core::_Closure::_function_type_arguments (field) - [18] = Reserved - [19] = EmptyTypeArguments - [20] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) - [21] = Reserved - [22] = InstanceField dart:core::_Closure::_function (field) - [23] = Reserved - [24] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names [] - [25] = Reserved - [26] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] - [27] = Reserved - [28] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] - [29] = Reserved - [30] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] - [31] = ICData dynamic target-name 'start', arg-desc CP#30 - [32] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names [] - [33] = Reserved + [14] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [15] = Reserved + [16] = InstanceField dart:core::_Closure::_function_type_arguments (field) + [17] = Reserved + [18] = EmptyTypeArguments + [19] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) + [20] = Reserved + [21] = InstanceField dart:core::_Closure::_function (field) + [22] = Reserved + [23] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names [] + [24] = Reserved + [25] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] + [26] = Reserved + [27] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] + [28] = Reserved + [29] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] + [30] = ICData dynamic target-name 'start', arg-desc CP#29 + [31] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names [] + [32] = Reserved } Closure #lib::foo::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic ClosureCode { @@ -475,47 +473,47 @@ PushNull StoreContextVar 0, 9 Push r0 - Allocate CP#18 + AllocateClosure CP#4 StoreLocal r2 Push r2 PushNull - StoreFieldTOS CP#19 + StoreFieldTOS CP#18 Push r2 PushNull - StoreFieldTOS CP#21 + StoreFieldTOS CP#20 Push r2 - PushConstant CP#23 - StoreFieldTOS CP#24 + PushConstant CP#22 + StoreFieldTOS CP#23 Push r2 PushConstant CP#4 - StoreFieldTOS CP#26 + StoreFieldTOS CP#25 Push r2 Push r0 StoreFieldTOS CP#6 StoreContextVar 0, 10 Push r0 LoadContextVar 0, 10 - DirectCall 1, CP#28 + DirectCall 1, CP#27 PopLocal r3 Push r0 Push r0 LoadContextVar 0, 10 - DirectCall 1, CP#30 + DirectCall 1, CP#29 StoreContextVar 0, 4 Push r0 Push r0 LoadContextVar 0, 10 - DirectCall 1, CP#32 + DirectCall 1, CP#31 StoreContextVar 0, 5 Push r0 LoadContextVar 0, 2 Push r0 LoadContextVar 0, 10 - DynamicCall 2, CP#35 + DynamicCall 2, CP#34 Drop1 Push r0 LoadContextVar 0, 2 - InterfaceCall 1, CP#36 + InterfaceCall 1, CP#35 ReturnTOS } ConstantPool { @@ -537,26 +535,25 @@ [15] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names [] [16] = Reserved [17] = EndClosureFunctionScope - [18] = Class dart:core::_Closure - [19] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [20] = Reserved - [21] = InstanceField dart:core::_Closure::_function_type_arguments (field) - [22] = Reserved - [23] = EmptyTypeArguments - [24] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) - [25] = Reserved - [26] = InstanceField dart:core::_Closure::_function (field) - [27] = Reserved - [28] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names [] - [29] = Reserved - [30] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] - [31] = Reserved - [32] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] - [33] = Reserved - [34] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] - [35] = ICData dynamic target-name 'start', arg-desc CP#34 - [36] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names [] - [37] = Reserved + [18] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [19] = Reserved + [20] = InstanceField dart:core::_Closure::_function_type_arguments (field) + [21] = Reserved + [22] = EmptyTypeArguments + [23] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) + [24] = Reserved + [25] = InstanceField dart:core::_Closure::_function (field) + [26] = Reserved + [27] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names [] + [28] = Reserved + [29] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] + [30] = Reserved + [31] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] + [32] = Reserved + [33] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] + [34] = ICData dynamic target-name 'start', arg-desc CP#33 + [35] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names [] + [36] = Reserved } Closure #lib::simpleAsyncAwait::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic ClosureCode { @@ -733,47 +730,47 @@ PushNull StoreContextVar 0, 9 Push r0 - Allocate CP#26 + AllocateClosure CP#4 StoreLocal r2 Push r2 PushNull - StoreFieldTOS CP#27 + StoreFieldTOS CP#26 Push r2 PushNull - StoreFieldTOS CP#29 + StoreFieldTOS CP#28 Push r2 - PushConstant CP#31 - StoreFieldTOS CP#32 + PushConstant CP#30 + StoreFieldTOS CP#31 Push r2 PushConstant CP#4 - StoreFieldTOS CP#34 + StoreFieldTOS CP#33 Push r2 Push r0 StoreFieldTOS CP#6 StoreContextVar 0, 10 Push r0 LoadContextVar 0, 10 - DirectCall 1, CP#36 + DirectCall 1, CP#35 PopLocal r3 Push r0 Push r0 LoadContextVar 0, 10 - DirectCall 1, CP#38 + DirectCall 1, CP#37 StoreContextVar 0, 3 Push r0 Push r0 LoadContextVar 0, 10 - DirectCall 1, CP#40 + DirectCall 1, CP#39 StoreContextVar 0, 4 Push r0 LoadContextVar 0, 1 Push r0 LoadContextVar 0, 10 - DynamicCall 2, CP#43 + DynamicCall 2, CP#42 Drop1 Push r0 LoadContextVar 0, 1 - InterfaceCall 1, CP#44 + InterfaceCall 1, CP#43 ReturnTOS } ConstantPool { @@ -803,26 +800,25 @@ [23] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names [] [24] = Reserved [25] = EndClosureFunctionScope - [26] = Class dart:core::_Closure - [27] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [28] = Reserved - [29] = InstanceField dart:core::_Closure::_function_type_arguments (field) - [30] = Reserved - [31] = EmptyTypeArguments - [32] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) - [33] = Reserved - [34] = InstanceField dart:core::_Closure::_function (field) - [35] = Reserved - [36] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names [] - [37] = Reserved - [38] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] - [39] = Reserved - [40] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] - [41] = Reserved - [42] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] - [43] = ICData dynamic target-name 'start', arg-desc CP#42 - [44] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names [] - [45] = Reserved + [26] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [27] = Reserved + [28] = InstanceField dart:core::_Closure::_function_type_arguments (field) + [29] = Reserved + [30] = EmptyTypeArguments + [31] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) + [32] = Reserved + [33] = InstanceField dart:core::_Closure::_function (field) + [34] = Reserved + [35] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names [] + [36] = Reserved + [37] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] + [38] = Reserved + [39] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] + [40] = Reserved + [41] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] + [42] = ICData dynamic target-name 'start', arg-desc CP#41 + [43] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names [] + [44] = Reserved } Closure #lib::loops::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic ClosureCode { @@ -1074,7 +1070,7 @@ Bytecode { Entry 4 CheckStack 0 - AllocateContext 0, 16 + AllocateContext 0, 18 PopLocal r0 Push r0 Push FP[-7] @@ -1130,47 +1126,53 @@ PushNull StoreContextVar 0, 14 Push r0 - Allocate CP#24 + PushNull + StoreContextVar 0, 15 + Push r0 + PushNull + StoreContextVar 0, 16 + Push r0 + AllocateClosure CP#4 StoreLocal r2 Push r2 PushNull - StoreFieldTOS CP#25 + StoreFieldTOS CP#24 Push r2 PushNull - StoreFieldTOS CP#27 + StoreFieldTOS CP#26 Push r2 - PushConstant CP#29 - StoreFieldTOS CP#30 + PushConstant CP#28 + StoreFieldTOS CP#29 Push r2 PushConstant CP#4 - StoreFieldTOS CP#32 + StoreFieldTOS CP#31 Push r2 Push r0 StoreFieldTOS CP#6 - StoreContextVar 0, 15 + StoreContextVar 0, 17 Push r0 - LoadContextVar 0, 15 - DirectCall 1, CP#34 + LoadContextVar 0, 17 + DirectCall 1, CP#33 PopLocal r3 Push r0 Push r0 - LoadContextVar 0, 15 - DirectCall 1, CP#36 + LoadContextVar 0, 17 + DirectCall 1, CP#35 StoreContextVar 0, 5 Push r0 Push r0 - LoadContextVar 0, 15 - DirectCall 1, CP#38 + LoadContextVar 0, 17 + DirectCall 1, CP#37 StoreContextVar 0, 6 Push r0 LoadContextVar 0, 3 Push r0 - LoadContextVar 0, 15 - DynamicCall 2, CP#41 + LoadContextVar 0, 17 + DynamicCall 2, CP#40 Drop1 Push r0 LoadContextVar 0, 3 - InterfaceCall 1, CP#42 + InterfaceCall 1, CP#41 ReturnTOS } ConstantPool { @@ -1198,26 +1200,25 @@ [21] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names [] [22] = Reserved [23] = EndClosureFunctionScope - [24] = Class dart:core::_Closure - [25] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [26] = Reserved - [27] = InstanceField dart:core::_Closure::_function_type_arguments (field) - [28] = Reserved - [29] = EmptyTypeArguments - [30] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) - [31] = Reserved - [32] = InstanceField dart:core::_Closure::_function (field) - [33] = Reserved - [34] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names [] - [35] = Reserved - [36] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] - [37] = Reserved - [38] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] - [39] = Reserved - [40] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] - [41] = ICData dynamic target-name 'start', arg-desc CP#40 - [42] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names [] - [43] = Reserved + [24] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [25] = Reserved + [26] = InstanceField dart:core::_Closure::_function_type_arguments (field) + [27] = Reserved + [28] = EmptyTypeArguments + [29] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) + [30] = Reserved + [31] = InstanceField dart:core::_Closure::_function (field) + [32] = Reserved + [33] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names [] + [34] = Reserved + [35] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] + [36] = Reserved + [37] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] + [38] = Reserved + [39] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] + [40] = ICData dynamic target-name 'start', arg-desc CP#39 + [41] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names [] + [42] = Reserved } Closure #lib::tryCatchRethrow::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic ClosureCode { @@ -1282,7 +1283,7 @@ LoadContextVar 0, 6 Push r4 LoadContextParent - LoadContextVar 0, 15 + LoadContextVar 0, 17 DirectCall 4, CP#8 PopLocal r13 PushNull @@ -1339,7 +1340,7 @@ LoadContextParent Push r4 LoadContextVar 1, 0 - StoreContextVar 0, 14 + StoreContextVar 0, 15 Push r4 LoadContextParent PushInt 2 @@ -1359,7 +1360,7 @@ LoadContextVar 0, 6 Push r4 LoadContextParent - LoadContextVar 0, 15 + LoadContextVar 0, 17 DirectCall 4, CP#8 PopLocal r13 PushNull @@ -1374,7 +1375,7 @@ Push r4 Push r4 LoadContextParent - LoadContextVar 0, 14 + LoadContextVar 0, 15 Push r1 InterfaceCall 2, CP#10 StoreContextVar 1, 0 @@ -1413,7 +1414,7 @@ LoadContextParent Push r4 LoadContextVar 1, 0 - StoreContextVar 0, 14 + StoreContextVar 0, 16 Push r4 LoadContextParent PushInt 3 @@ -1433,7 +1434,7 @@ LoadContextVar 0, 6 Push r4 LoadContextParent - LoadContextVar 0, 15 + LoadContextVar 0, 17 DirectCall 4, CP#8 PopLocal r12 PushNull @@ -1448,7 +1449,7 @@ Push r4 Push r4 LoadContextParent - LoadContextVar 0, 14 + LoadContextVar 0, 16 Push r1 InterfaceCall 2, CP#10 StoreContextVar 1, 0 @@ -1475,7 +1476,7 @@ LoadContextParent Push r4 LoadContextVar 1, 0 - StoreContextVar 0, 14 + StoreContextVar 0, 16 Push r4 LoadContextParent PushInt 4 @@ -1495,7 +1496,7 @@ LoadContextVar 0, 6 Push r4 LoadContextParent - LoadContextVar 0, 15 + LoadContextVar 0, 17 DirectCall 4, CP#8 PopLocal r12 PushNull @@ -1510,7 +1511,7 @@ Push r4 Push r4 LoadContextParent - LoadContextVar 0, 14 + LoadContextVar 0, 16 Push r1 InterfaceCall 2, CP#10 StoreContextVar 1, 0 @@ -1537,7 +1538,7 @@ LoadContextParent Push r4 LoadContextVar 1, 0 - StoreContextVar 0, 14 + StoreContextVar 0, 16 Push r4 LoadContextParent PushInt 5 @@ -1557,7 +1558,7 @@ LoadContextVar 0, 6 Push r4 LoadContextParent - LoadContextVar 0, 15 + LoadContextVar 0, 17 DirectCall 4, CP#8 PopLocal r12 PushNull @@ -1572,7 +1573,7 @@ Push r4 Push r4 LoadContextParent - LoadContextVar 0, 14 + LoadContextVar 0, 16 Push r1 InterfaceCall 2, CP#10 StoreContextVar 1, 0 @@ -1656,20 +1657,20 @@ Push r0 PushInt 3 StoreContextVar 0, 1 - Allocate CP#20 + AllocateClosure CP#0 StoreLocal r3 Push r3 PushNull - StoreFieldTOS CP#21 + StoreFieldTOS CP#20 Push r3 PushNull - StoreFieldTOS CP#23 + StoreFieldTOS CP#22 Push r3 - PushConstant CP#25 - StoreFieldTOS CP#26 + PushConstant CP#24 + StoreFieldTOS CP#25 Push r3 PushConstant CP#0 - StoreFieldTOS CP#28 + StoreFieldTOS CP#27 Push r3 Push r0 StoreFieldTOS CP#1 @@ -1698,27 +1699,26 @@ [17] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names [] [18] = Reserved [19] = EndClosureFunctionScope - [20] = Class dart:core::_Closure - [21] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [22] = Reserved - [23] = InstanceField dart:core::_Closure::_function_type_arguments (field) - [24] = Reserved - [25] = EmptyTypeArguments - [26] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) - [27] = Reserved - [28] = InstanceField dart:core::_Closure::_function (field) - [29] = Reserved - [30] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names [] - [31] = Reserved - [32] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] - [33] = Reserved - [34] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] - [35] = Reserved - [36] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] - [37] = ICData dynamic target-name 'start', arg-desc CP#36 - [38] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names [] - [39] = Reserved - [40] = EndClosureFunctionScope + [20] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [21] = Reserved + [22] = InstanceField dart:core::_Closure::_function_type_arguments (field) + [23] = Reserved + [24] = EmptyTypeArguments + [25] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) + [26] = Reserved + [27] = InstanceField dart:core::_Closure::_function (field) + [28] = Reserved + [29] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names [] + [30] = Reserved + [31] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] + [32] = Reserved + [33] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] + [34] = Reserved + [35] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] + [36] = ICData dynamic target-name 'start', arg-desc CP#35 + [37] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names [] + [38] = Reserved + [39] = EndClosureFunctionScope } Closure #lib::closure::'nested' () -> dart:async::Future < dart:core::int > ClosureCode { @@ -1766,47 +1766,47 @@ PushNull StoreContextVar 1, 7 Push r0 - Allocate CP#20 + AllocateClosure CP#7 StoreLocal r2 Push r2 PushNull - StoreFieldTOS CP#21 + StoreFieldTOS CP#20 Push r2 PushNull - StoreFieldTOS CP#23 + StoreFieldTOS CP#22 Push r2 - PushConstant CP#25 - StoreFieldTOS CP#26 + PushConstant CP#24 + StoreFieldTOS CP#25 Push r2 PushConstant CP#7 - StoreFieldTOS CP#28 + StoreFieldTOS CP#27 Push r2 Push r0 StoreFieldTOS CP#1 StoreContextVar 1, 8 Push r0 LoadContextVar 1, 8 - DirectCall 1, CP#30 + DirectCall 1, CP#29 PopLocal r3 Push r0 Push r0 LoadContextVar 1, 8 - DirectCall 1, CP#32 + DirectCall 1, CP#31 StoreContextVar 1, 2 Push r0 Push r0 LoadContextVar 1, 8 - DirectCall 1, CP#34 + DirectCall 1, CP#33 StoreContextVar 1, 3 Push r0 LoadContextVar 1, 0 Push r0 LoadContextVar 1, 8 - DynamicCall 2, CP#37 + DynamicCall 2, CP#36 Drop1 Push r0 LoadContextVar 1, 0 - InterfaceCall 1, CP#38 + InterfaceCall 1, CP#37 ReturnTOS } @@ -2013,47 +2013,47 @@ PushNull StoreContextVar 0, 7 Push r0 - Allocate CP#20 + AllocateClosure CP#4 StoreLocal r2 Push r2 PushNull - StoreFieldTOS CP#21 + StoreFieldTOS CP#20 Push r2 PushNull - StoreFieldTOS CP#23 + StoreFieldTOS CP#22 Push r2 - PushConstant CP#25 - StoreFieldTOS CP#26 + PushConstant CP#24 + StoreFieldTOS CP#25 Push r2 PushConstant CP#4 - StoreFieldTOS CP#28 + StoreFieldTOS CP#27 Push r2 Push r0 StoreFieldTOS CP#6 StoreContextVar 0, 8 Push r0 LoadContextVar 0, 8 - DirectCall 1, CP#30 + DirectCall 1, CP#29 PopLocal r3 Push r0 Push r0 LoadContextVar 0, 8 - DirectCall 1, CP#32 + DirectCall 1, CP#31 StoreContextVar 0, 3 Push r0 Push r0 LoadContextVar 0, 8 - DirectCall 1, CP#34 + DirectCall 1, CP#33 StoreContextVar 0, 4 Push r0 LoadContextVar 0, 1 Push r0 LoadContextVar 0, 8 - DynamicCall 2, CP#37 + DynamicCall 2, CP#36 Drop1 Push r0 LoadContextVar 0, 1 - InterfaceCall 1, CP#38 + InterfaceCall 1, CP#37 ReturnTOS } ConstantPool { @@ -2077,26 +2077,25 @@ [17] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names [] [18] = Reserved [19] = EndClosureFunctionScope - [20] = Class dart:core::_Closure - [21] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [22] = Reserved - [23] = InstanceField dart:core::_Closure::_function_type_arguments (field) - [24] = Reserved - [25] = EmptyTypeArguments - [26] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) - [27] = Reserved - [28] = InstanceField dart:core::_Closure::_function (field) - [29] = Reserved - [30] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names [] - [31] = Reserved - [32] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] - [33] = Reserved - [34] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] - [35] = Reserved - [36] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] - [37] = ICData dynamic target-name 'start', arg-desc CP#36 - [38] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names [] - [39] = Reserved + [20] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [21] = Reserved + [22] = InstanceField dart:core::_Closure::_function_type_arguments (field) + [23] = Reserved + [24] = EmptyTypeArguments + [25] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) + [26] = Reserved + [27] = InstanceField dart:core::_Closure::_function (field) + [28] = Reserved + [29] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names [] + [30] = Reserved + [31] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] + [32] = Reserved + [33] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names [] + [34] = Reserved + [35] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] + [36] = ICData dynamic target-name 'start', arg-desc CP#35 + [37] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names [] + [38] = Reserved } Closure #lib::testAssert::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic ClosureCode { @@ -2367,6 +2366,8 @@ dynamic :exception0; dynamic :stack_trace0; dynamic :async_temporary_0; + dynamic :async_temporary_1; + dynamic :async_temporary_2; function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding try { #L5: @@ -2383,16 +2384,16 @@ :return_value = 42; break #L5; } - :async_temporary_0 = x; + :async_temporary_1 = x; [yield] let dynamic #t6 = dart.async::_awaitHelper(b, :async_op_then, :async_op_error, :async_op) in null; - x = :async_temporary_0.{dart.core::num::+}(:result); + x = :async_temporary_1.{dart.core::num::+}(:result); rethrow; } finally { dart.core::print("fin"); - :async_temporary_0 = x; + :async_temporary_2 = x; [yield] let dynamic #t7 = dart.async::_awaitHelper(c, :async_op_then, :async_op_error, :async_op) in null; - x = :async_temporary_0.{dart.core::num::+}(:result); + x = :async_temporary_2.{dart.core::num::+}(:result); :return_value = x; break #L5; }
diff --git a/pkg/vm/testcases/bytecode/closures.dart.expect b/pkg/vm/testcases/bytecode/closures.dart.expect index 50124d6..c168ee6 100644 --- a/pkg/vm/testcases/bytecode/closures.dart.expect +++ b/pkg/vm/testcases/bytecode/closures.dart.expect
@@ -24,27 +24,27 @@ Push r0 PushInt 5 StoreContextVar 0, 0 - Allocate CP#7 + AllocateClosure CP#0 StoreLocal r3 Push r3 PushNull - StoreFieldTOS CP#8 + StoreFieldTOS CP#7 Push r3 PushNull - StoreFieldTOS CP#10 + StoreFieldTOS CP#9 Push r3 - PushConstant CP#12 - StoreFieldTOS CP#13 + PushConstant CP#11 + StoreFieldTOS CP#12 Push r3 PushConstant CP#0 - StoreFieldTOS CP#15 + StoreFieldTOS CP#14 Push r3 Push r0 StoreFieldTOS CP#1 PopLocal r2 Push r2 PushInt 3 - DynamicCall 2, CP#18 + DynamicCall 2, CP#17 Drop1 Push r0 LoadContextVar 0, 0 @@ -58,18 +58,17 @@ [4] = ObjectRef 'y' [5] = SubtypeTestCache [6] = EndClosureFunctionScope - [7] = Class dart:core::_Closure - [8] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [9] = Reserved - [10] = InstanceField dart:core::_Closure::_function_type_arguments (field) - [11] = Reserved - [12] = EmptyTypeArguments - [13] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) - [14] = Reserved - [15] = InstanceField dart:core::_Closure::_function (field) - [16] = Reserved - [17] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] - [18] = ICData dynamic target-name 'call', arg-desc CP#17 + [7] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [8] = Reserved + [9] = InstanceField dart:core::_Closure::_function_type_arguments (field) + [10] = Reserved + [11] = EmptyTypeArguments + [12] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) + [13] = Reserved + [14] = InstanceField dart:core::_Closure::_function (field) + [15] = Reserved + [16] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] + [17] = ICData dynamic target-name 'call', arg-desc CP#16 } Closure #lib::simpleClosure::'<anonymous closure>' (dart:core::int y) -> dart:core::Null ClosureCode { @@ -246,11 +245,11 @@ Bytecode { Entry 7 CheckStack 0 - Allocate CP#14 + AllocateClosure CP#0 StoreLocal r3 Push r3 PushNull - StoreFieldTOS CP#15 + StoreFieldTOS CP#14 Push r3 PushNull StoreFieldTOS CP#6 @@ -259,33 +258,33 @@ StoreFieldTOS CP#3 Push r3 PushConstant CP#0 - StoreFieldTOS CP#17 + StoreFieldTOS CP#16 Push r3 Push r0 StoreFieldTOS CP#1 PopLocal r2 Push r2 StoreLocal r3 - PushConstant CP#19 + PushConstant CP#18 StoreLocal r6 - DirectCall 2, CP#20 + DirectCall 2, CP#19 Drop1 - Allocate CP#14 + Allocate CP#21 StoreLocal r5 Push r6 StoreFieldTOS CP#3 Push r5 Push r3 - LoadFieldTOS CP#15 - StoreFieldTOS CP#15 + LoadFieldTOS CP#14 + StoreFieldTOS CP#14 Push r5 Push r3 LoadFieldTOS CP#6 StoreFieldTOS CP#6 Push r5 Push r3 - LoadFieldTOS CP#17 - StoreFieldTOS CP#17 + LoadFieldTOS CP#16 + StoreFieldTOS CP#16 Push r5 Push r3 LoadFieldTOS CP#1 @@ -310,14 +309,14 @@ [11] = ObjectRef 't' [12] = SubtypeTestCache [13] = EndClosureFunctionScope - [14] = Class dart:core::_Closure - [15] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [16] = Reserved - [17] = InstanceField dart:core::_Closure::_function (field) - [18] = Reserved - [19] = ObjectRef < dart:core::int > - [20] = DirectCall 'dart:_internal::_boundsCheckForPartialInstantiation', ArgDesc num-args 2, num-type-args 0, names [] - [21] = Reserved + [14] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [15] = Reserved + [16] = InstanceField dart:core::_Closure::_function (field) + [17] = Reserved + [18] = ObjectRef < dart:core::int > + [19] = DirectCall 'dart:_internal::_boundsCheckForPartialInstantiation', ArgDesc num-args 2, num-type-args 0, names [] + [20] = Reserved + [21] = Class dart:core::_Closure } Closure #lib::testPartialInstantiation::'foo' <dart:core::Object T> (#lib::testPartialInstantiation::Closure/0::TypeParam/0 t) -> void ClosureCode { @@ -672,12 +671,12 @@ Push r1 Push FP[-5] StoreContextVar 0, 0 - Allocate CP#30 + AllocateClosure CP#0 StoreLocal r4 Push r4 Push FP[-5] LoadTypeArgumentsField CP#14 - StoreFieldTOS CP#31 + StoreFieldTOS CP#30 Push r4 Push r0 StoreFieldTOS CP#6 @@ -686,18 +685,18 @@ StoreFieldTOS CP#3 Push r4 PushConstant CP#0 - StoreFieldTOS CP#33 + StoreFieldTOS CP#32 Push r4 Push r1 StoreFieldTOS CP#1 PopLocal r3 - PushConstant CP#44 + PushConstant CP#43 Push r3 - DynamicCall 2, CP#45 + DynamicCall 2, CP#44 Drop1 - PushConstant CP#46 + PushConstant CP#45 Push r3 - DynamicCall 2, CP#47 + DynamicCall 2, CP#46 Drop1 PushNull ReturnTOS @@ -733,24 +732,23 @@ [27] = DirectCall '#lib::callWithArgs', ArgDesc num-args 0, num-type-args 8, names [] [28] = Reserved [29] = EndClosureFunctionScope - [30] = Class dart:core::_Closure - [31] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [32] = Reserved - [33] = InstanceField dart:core::_Closure::_function (field) - [34] = Reserved - [35] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] - [36] = ICData dynamic target-name 'call', arg-desc CP#35 - [37] = EndClosureFunctionScope - [38] = ObjectRef < #lib::C7, #lib::C8 > - [39] = ObjectRef ArgDesc num-args 1, num-type-args 2, names [] - [40] = ICData dynamic target-name 'call', arg-desc CP#39 - [41] = ObjectRef < dart:core::List < #lib::C7 >, dart:core::List < #lib::C8 > > - [42] = ICData dynamic target-name 'call', arg-desc CP#39 - [43] = EndClosureFunctionScope - [44] = ObjectRef < #lib::C5, #lib::C6 > - [45] = ICData dynamic target-name 'call', arg-desc CP#39 - [46] = ObjectRef < dart:core::List < #lib::C5 >, dart:core::List < #lib::C6 > > - [47] = ICData dynamic target-name 'call', arg-desc CP#39 + [30] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [31] = Reserved + [32] = InstanceField dart:core::_Closure::_function (field) + [33] = Reserved + [34] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] + [35] = ICData dynamic target-name 'call', arg-desc CP#34 + [36] = EndClosureFunctionScope + [37] = ObjectRef < #lib::C7, #lib::C8 > + [38] = ObjectRef ArgDesc num-args 1, num-type-args 2, names [] + [39] = ICData dynamic target-name 'call', arg-desc CP#38 + [40] = ObjectRef < dart:core::List < #lib::C7 >, dart:core::List < #lib::C8 > > + [41] = ICData dynamic target-name 'call', arg-desc CP#38 + [42] = EndClosureFunctionScope + [43] = ObjectRef < #lib::C5, #lib::C6 > + [44] = ICData dynamic target-name 'call', arg-desc CP#38 + [45] = ObjectRef < dart:core::List < #lib::C5 >, dart:core::List < #lib::C6 > > + [46] = ICData dynamic target-name 'call', arg-desc CP#38 } Closure #lib::A::foo::'nested1' <dart:core::Object T5, dart:core::Object T6> () -> void ClosureCode { @@ -776,13 +774,13 @@ PushInt 4 DirectCall 4, CP#8 PopLocal r0 - Allocate CP#30 + AllocateClosure CP#10 StoreLocal r4 Push r4 Push r1 LoadContextVar 0, 0 LoadTypeArgumentsField CP#14 - StoreFieldTOS CP#31 + StoreFieldTOS CP#30 Push r4 Push r0 StoreFieldTOS CP#6 @@ -791,18 +789,18 @@ StoreFieldTOS CP#3 Push r4 PushConstant CP#10 - StoreFieldTOS CP#33 + StoreFieldTOS CP#32 Push r4 Push r1 StoreFieldTOS CP#1 PopLocal r3 - PushConstant CP#38 + PushConstant CP#37 Push r3 - DynamicCall 2, CP#40 + DynamicCall 2, CP#39 Drop1 - PushConstant CP#41 + PushConstant CP#40 Push r3 - DynamicCall 2, CP#42 + DynamicCall 2, CP#41 Drop1 PushNull ReturnTOS @@ -833,13 +831,13 @@ PushInt 6 DirectCall 4, CP#8 PopLocal r0 - Allocate CP#30 + AllocateClosure CP#11 StoreLocal r4 Push r4 Push r1 LoadContextVar 0, 0 LoadTypeArgumentsField CP#14 - StoreFieldTOS CP#31 + StoreFieldTOS CP#30 Push r4 Push r0 StoreFieldTOS CP#6 @@ -848,13 +846,13 @@ StoreFieldTOS CP#3 Push r4 PushConstant CP#11 - StoreFieldTOS CP#33 + StoreFieldTOS CP#32 Push r4 Push r1 StoreFieldTOS CP#1 PopLocal r3 Push r3 - DynamicCall 1, CP#36 + DynamicCall 1, CP#35 Drop1 PushNull ReturnTOS @@ -1016,66 +1014,66 @@ Push r0 PushInt 3 StoreContextVar 0, 2 - Allocate CP#10 + AllocateClosure CP#0 StoreLocal r4 Push r4 PushNull - StoreFieldTOS CP#11 + StoreFieldTOS CP#10 Push r4 PushNull - StoreFieldTOS CP#13 + StoreFieldTOS CP#12 Push r4 - PushConstant CP#15 - StoreFieldTOS CP#16 + PushConstant CP#14 + StoreFieldTOS CP#15 Push r4 PushConstant CP#0 - StoreFieldTOS CP#18 + StoreFieldTOS CP#17 Push r4 Push r0 StoreFieldTOS CP#1 PopLocal r3 Push r3 PushInt 10 - DynamicCall 2, CP#26 + DynamicCall 2, CP#25 Drop1 Push r3 PushInt 11 - DynamicCall 2, CP#27 + DynamicCall 2, CP#26 Drop1 Push r2 - DirectCall 1, CP#22 + DirectCall 1, CP#21 Drop1 Push r0 LoadContextVar 0, 2 - DirectCall 1, CP#22 + DirectCall 1, CP#21 Drop1 Push r0 LoadContextVar 0, 1 - DirectCall 1, CP#22 + DirectCall 1, CP#21 Drop1 Push r0 PushInt 42 StoreContextVar 0, 3 - Allocate CP#10 + AllocateClosure CP#27 StoreLocal r3 Push r3 PushNull - StoreFieldTOS CP#11 + StoreFieldTOS CP#10 Push r3 PushNull - StoreFieldTOS CP#13 + StoreFieldTOS CP#12 Push r3 - PushConstant CP#15 - StoreFieldTOS CP#16 + PushConstant CP#14 + StoreFieldTOS CP#15 Push r3 - PushConstant CP#28 - StoreFieldTOS CP#18 + PushConstant CP#27 + StoreFieldTOS CP#17 Push r3 Push r0 StoreFieldTOS CP#1 PopLocal r2 Push r2 - DynamicCall 1, CP#32 + DynamicCall 1, CP#31 Drop1 PushNull ReturnTOS @@ -1091,29 +1089,28 @@ [7] = InterfaceCall '#lib::B::get:foo', ArgDesc num-args 1, num-type-args 0, names [] [8] = Reserved [9] = EndClosureFunctionScope - [10] = Class dart:core::_Closure - [11] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [12] = Reserved - [13] = InstanceField dart:core::_Closure::_function_type_arguments (field) - [14] = Reserved - [15] = EmptyTypeArguments - [16] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) - [17] = Reserved - [18] = InstanceField dart:core::_Closure::_function (field) - [19] = Reserved - [20] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] - [21] = ICData dynamic target-name 'call', arg-desc CP#20 - [22] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names [] - [23] = Reserved - [24] = EndClosureFunctionScope - [25] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] - [26] = ICData dynamic target-name 'call', arg-desc CP#25 - [27] = ICData dynamic target-name 'call', arg-desc CP#25 - [28] = ClosureFunction 2 - [29] = InterfaceCall '#lib::B::set:foo', ArgDesc num-args 2, num-type-args 0, names [] - [30] = Reserved - [31] = EndClosureFunctionScope - [32] = ICData dynamic target-name 'call', arg-desc CP#20 + [10] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [11] = Reserved + [12] = InstanceField dart:core::_Closure::_function_type_arguments (field) + [13] = Reserved + [14] = EmptyTypeArguments + [15] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) + [16] = Reserved + [17] = InstanceField dart:core::_Closure::_function (field) + [18] = Reserved + [19] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] + [20] = ICData dynamic target-name 'call', arg-desc CP#19 + [21] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names [] + [22] = Reserved + [23] = EndClosureFunctionScope + [24] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] + [25] = ICData dynamic target-name 'call', arg-desc CP#24 + [26] = ICData dynamic target-name 'call', arg-desc CP#24 + [27] = ClosureFunction 2 + [28] = InterfaceCall '#lib::B::set:foo', ArgDesc num-args 2, num-type-args 0, names [] + [29] = Reserved + [30] = EndClosureFunctionScope + [31] = ICData dynamic target-name 'call', arg-desc CP#19 } Closure #lib::B::topLevel::'<anonymous closure>' (dart:core::int y) -> dart:core::Null ClosureCode { @@ -1154,30 +1151,30 @@ Push r0 PushInt 4 StoreContextVar 1, 1 - Allocate CP#10 + AllocateClosure CP#6 StoreLocal r2 Push r2 PushNull - StoreFieldTOS CP#11 + StoreFieldTOS CP#10 Push r2 PushNull - StoreFieldTOS CP#13 + StoreFieldTOS CP#12 Push r2 - PushConstant CP#15 - StoreFieldTOS CP#16 + PushConstant CP#14 + StoreFieldTOS CP#15 Push r2 PushConstant CP#6 - StoreFieldTOS CP#18 + StoreFieldTOS CP#17 Push r2 Push r0 StoreFieldTOS CP#1 PopLocal r3 Push r3 - DynamicCall 1, CP#21 + DynamicCall 1, CP#20 Drop1 Push r0 LoadContextVar 1, 1 - DirectCall 1, CP#22 + DirectCall 1, CP#21 Drop1 L1: PushNull @@ -1225,7 +1222,7 @@ LoadContextVar 0, 0 Push r0 LoadContextVar 0, 3 - InterfaceCall 2, CP#29 + InterfaceCall 2, CP#28 Drop1 PushNull ReturnTOS @@ -1313,20 +1310,12 @@ PushInt 0 StoreContextVar 0, 0 PushConstant CP#0 - StoreLocal r3 - Push r3 - PushInt 0 - CreateArrayTOS - StoreLocal r3 - DirectCall 2, CP#1 + PushConstant CP#1 + DirectCall 2, CP#2 PopLocal r2 PushConstant CP#0 - StoreLocal r3 - Push r3 - PushInt 0 - CreateArrayTOS - StoreLocal r3 - DirectCall 2, CP#1 + PushConstant CP#1 + DirectCall 2, CP#2 PopLocal r4 AllocateContext 1, 1 StoreLocal r1 @@ -1345,7 +1334,7 @@ CompareIntLt JumpIfFalse L1 Push r2 - Allocate CP#7 + AllocateClosure CP#4 StoreLocal r3 Push r3 PushNull @@ -1357,15 +1346,15 @@ PushConstant CP#12 StoreFieldTOS CP#13 Push r3 - PushConstant CP#3 + PushConstant CP#4 StoreFieldTOS CP#15 Push r3 Push r0 - StoreFieldTOS CP#4 + StoreFieldTOS CP#5 InterfaceCall 2, CP#17 Drop1 Push r4 - Allocate CP#7 + AllocateClosure CP#19 StoreLocal r3 Push r3 PushNull @@ -1381,7 +1370,7 @@ StoreFieldTOS CP#15 Push r3 Push r0 - StoreFieldTOS CP#4 + StoreFieldTOS CP#5 InterfaceCall 2, CP#17 Drop1 Push r0 @@ -1409,13 +1398,13 @@ } ConstantPool { [0] = ObjectRef < dart:core::Function > - [1] = DirectCall 'dart:core::List::_fromLiteral (constructor)', ArgDesc num-args 2, num-type-args 0, names [] - [2] = Reserved - [3] = ClosureFunction 0 - [4] = InstanceField dart:core::_Closure::_context (field) - [5] = Reserved - [6] = EndClosureFunctionScope - [7] = Class dart:core::_Closure + [1] = ObjectRef const <dynamic> [] + [2] = DirectCall 'dart:core::List::_fromLiteral (constructor)', ArgDesc num-args 2, num-type-args 0, names [] + [3] = Reserved + [4] = ClosureFunction 0 + [5] = InstanceField dart:core::_Closure::_context (field) + [6] = Reserved + [7] = EndClosureFunctionScope [8] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) [9] = Reserved [10] = InstanceField dart:core::_Closure::_function_type_arguments (field) @@ -1438,7 +1427,7 @@ EntryFixed 1, 2 CheckStack 0 Push FP[-5] - LoadFieldTOS CP#4 + LoadFieldTOS CP#5 PopLocal r0 Push r0 LoadContextVar 1, 0 @@ -1455,7 +1444,7 @@ EntryFixed 2, 3 CheckStack 0 Push FP[-6] - LoadFieldTOS CP#4 + LoadFieldTOS CP#5 PopLocal r0 Push FP[-5] PushConstant CP#20 @@ -1499,30 +1488,30 @@ Push r2 InterfaceCall 1, CP#4 StoreContextVar 0, 0 - Allocate CP#10 + AllocateClosure CP#6 StoreLocal r4 Push r4 PushNull - StoreFieldTOS CP#11 + StoreFieldTOS CP#10 Push r4 PushNull - StoreFieldTOS CP#13 + StoreFieldTOS CP#12 Push r4 - PushConstant CP#15 - StoreFieldTOS CP#16 + PushConstant CP#14 + StoreFieldTOS CP#15 Push r4 PushConstant CP#6 - StoreFieldTOS CP#18 + StoreFieldTOS CP#17 Push r4 Push r0 StoreFieldTOS CP#7 PopLocal r3 Push r3 - DynamicCall 1, CP#21 + DynamicCall 1, CP#20 Drop1 Push r0 LoadContextVar 0, 0 - DirectCall 1, CP#22 + DirectCall 1, CP#21 Drop1 Push r0 LoadContextParent @@ -1543,20 +1532,19 @@ [7] = InstanceField dart:core::_Closure::_context (field) [8] = Reserved [9] = EndClosureFunctionScope - [10] = Class dart:core::_Closure - [11] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [12] = Reserved - [13] = InstanceField dart:core::_Closure::_function_type_arguments (field) - [14] = Reserved - [15] = EmptyTypeArguments - [16] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) - [17] = Reserved - [18] = InstanceField dart:core::_Closure::_function (field) - [19] = Reserved - [20] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] - [21] = ICData dynamic target-name 'call', arg-desc CP#20 - [22] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names [] - [23] = Reserved + [10] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [11] = Reserved + [12] = InstanceField dart:core::_Closure::_function_type_arguments (field) + [13] = Reserved + [14] = EmptyTypeArguments + [15] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) + [16] = Reserved + [17] = InstanceField dart:core::_Closure::_function (field) + [18] = Reserved + [19] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] + [20] = ICData dynamic target-name 'call', arg-desc CP#19 + [21] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names [] + [22] = Reserved } Closure #lib::C::testForInLoop::'<anonymous closure>' () -> dart:core::Null ClosureCode { @@ -1650,21 +1638,21 @@ PushConstant CP#2 AssertAssignable 0, CP#3 Drop1 - Allocate CP#8 + AllocateClosure CP#4 StoreLocal r2 Push r2 Push FP[-6] LoadTypeArgumentsField CP#1 - StoreFieldTOS CP#9 + StoreFieldTOS CP#8 Push r2 PushNull - StoreFieldTOS CP#11 + StoreFieldTOS CP#10 Push r2 - PushConstant CP#13 - StoreFieldTOS CP#14 + PushConstant CP#12 + StoreFieldTOS CP#13 Push r2 PushConstant CP#4 - StoreFieldTOS CP#16 + StoreFieldTOS CP#15 Push r2 Push r0 StoreFieldTOS CP#5 @@ -1680,16 +1668,15 @@ [5] = InstanceField dart:core::_Closure::_context (field) [6] = Reserved [7] = EndClosureFunctionScope - [8] = Class dart:core::_Closure - [9] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [10] = Reserved - [11] = InstanceField dart:core::_Closure::_function_type_arguments (field) - [12] = Reserved - [13] = EmptyTypeArguments - [14] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) - [15] = Reserved - [16] = InstanceField dart:core::_Closure::_function (field) - [17] = Reserved + [8] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [9] = Reserved + [10] = InstanceField dart:core::_Closure::_function_type_arguments (field) + [11] = Reserved + [12] = EmptyTypeArguments + [13] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) + [14] = Reserved + [15] = InstanceField dart:core::_Closure::_function (field) + [16] = Reserved } Closure #lib::D::foo::'<anonymous closure>' () -> #lib::D::TypeParam/0 ClosureCode { @@ -1718,21 +1705,21 @@ Push r0 Push FP[-5] StoreContextVar 0, 0 - Allocate CP#5 + AllocateClosure CP#0 StoreLocal r2 Push r2 Push FP[-5] - LoadTypeArgumentsField CP#6 - StoreFieldTOS CP#7 + LoadTypeArgumentsField CP#5 + StoreFieldTOS CP#6 Push r2 PushNull - StoreFieldTOS CP#9 + StoreFieldTOS CP#8 Push r2 - PushConstant CP#11 - StoreFieldTOS CP#12 + PushConstant CP#10 + StoreFieldTOS CP#11 Push r2 PushConstant CP#0 - StoreFieldTOS CP#14 + StoreFieldTOS CP#13 Push r2 Push r0 StoreFieldTOS CP#1 @@ -1744,20 +1731,19 @@ [2] = Reserved [3] = ClosureFunction 1 [4] = EndClosureFunctionScope - [5] = Class dart:core::_Closure - [6] = TypeArgumentsField #lib::D - [7] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [8] = Reserved - [9] = InstanceField dart:core::_Closure::_function_type_arguments (field) - [10] = Reserved - [11] = EmptyTypeArguments - [12] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) - [13] = Reserved - [14] = InstanceField dart:core::_Closure::_function (field) - [15] = Reserved - [16] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] - [17] = ICData dynamic target-name 'call', arg-desc CP#16 - [18] = EndClosureFunctionScope + [5] = TypeArgumentsField #lib::D + [6] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [7] = Reserved + [8] = InstanceField dart:core::_Closure::_function_type_arguments (field) + [9] = Reserved + [10] = EmptyTypeArguments + [11] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) + [12] = Reserved + [13] = InstanceField dart:core::_Closure::_function (field) + [14] = Reserved + [15] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] + [16] = ICData dynamic target-name 'call', arg-desc CP#15 + [17] = EndClosureFunctionScope } Closure #lib::D::bar::'<anonymous closure>' () -> dart:core::Null ClosureCode { @@ -1766,28 +1752,28 @@ Push FP[-5] LoadFieldTOS CP#1 PopLocal r0 - Allocate CP#5 + AllocateClosure CP#3 StoreLocal r3 Push r3 Push r0 LoadContextVar 0, 0 - LoadTypeArgumentsField CP#6 - StoreFieldTOS CP#7 + LoadTypeArgumentsField CP#5 + StoreFieldTOS CP#6 Push r3 PushNull - StoreFieldTOS CP#9 + StoreFieldTOS CP#8 Push r3 - PushConstant CP#11 - StoreFieldTOS CP#12 + PushConstant CP#10 + StoreFieldTOS CP#11 Push r3 PushConstant CP#3 - StoreFieldTOS CP#14 + StoreFieldTOS CP#13 Push r3 Push r0 StoreFieldTOS CP#1 PopLocal r2 Push r2 - DynamicCall 1, CP#17 + DynamicCall 1, CP#16 Drop1 PushNull ReturnTOS
diff --git a/pkg/vm/testcases/bytecode/try_blocks.dart.expect b/pkg/vm/testcases/bytecode/try_blocks.dart.expect index 2cdcf6d..126eae9 100644 --- a/pkg/vm/testcases/bytecode/try_blocks.dart.expect +++ b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
@@ -222,26 +222,26 @@ Push r0 PushInt 2 StoreContextVar 0, 1 - Allocate CP#8 + AllocateClosure CP#0 StoreLocal r5 Push r5 PushNull - StoreFieldTOS CP#9 + StoreFieldTOS CP#8 Push r5 PushNull - StoreFieldTOS CP#11 + StoreFieldTOS CP#10 Push r5 - PushConstant CP#13 - StoreFieldTOS CP#14 + PushConstant CP#12 + StoreFieldTOS CP#13 Push r5 PushConstant CP#0 - StoreFieldTOS CP#16 + StoreFieldTOS CP#15 Push r5 Push r0 StoreFieldTOS CP#1 PopLocal r4 Push r4 - DynamicCall 1, CP#19 + DynamicCall 1, CP#18 Drop1 Push r0 LoadContextVar 0, 1 @@ -266,7 +266,7 @@ StoreLocal r5 Push r5 PushInt 0 - PushConstant CP#20 + PushConstant CP#19 StoreIndexedTOS Push r5 PushInt 1 @@ -274,30 +274,30 @@ StoreIndexedTOS Push r5 PushInt 2 - PushConstant CP#21 + PushConstant CP#20 StoreIndexedTOS Push r5 PushInt 3 Push r0 LoadContextVar 0, 2 StoreIndexedTOS - DirectCall 1, CP#22 + DirectCall 1, CP#21 DirectCall 1, CP#4 Drop1 - Allocate CP#8 + AllocateClosure CP#23 StoreLocal r5 Push r5 PushNull - StoreFieldTOS CP#9 + StoreFieldTOS CP#8 Push r5 PushNull - StoreFieldTOS CP#11 + StoreFieldTOS CP#10 Push r5 - PushConstant CP#13 - StoreFieldTOS CP#14 + PushConstant CP#12 + StoreFieldTOS CP#13 Push r5 - PushConstant CP#24 - StoreFieldTOS CP#16 + PushConstant CP#23 + StoreFieldTOS CP#15 Push r5 Push r0 StoreFieldTOS CP#1 @@ -323,30 +323,29 @@ [5] = Reserved [6] = Type dynamic [7] = EndClosureFunctionScope - [8] = Class dart:core::_Closure - [9] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [10] = Reserved - [11] = InstanceField dart:core::_Closure::_function_type_arguments (field) - [12] = Reserved - [13] = EmptyTypeArguments - [14] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) - [15] = Reserved - [16] = InstanceField dart:core::_Closure::_function (field) - [17] = Reserved - [18] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] - [19] = ICData dynamic target-name 'call', arg-desc CP#18 - [20] = ObjectRef 'caught ' - [21] = ObjectRef ' ' - [22] = DirectCall 'dart:core::_StringBase::_interpolate', ArgDesc num-args 1, num-type-args 0, names [] - [23] = Reserved - [24] = ClosureFunction 1 - [25] = ObjectRef 'danger bar' - [26] = Type dart:core::Error - [27] = InterfaceCall 'dart:core::Object::_simpleInstanceOf', ArgDesc num-args 2, num-type-args 0, names [] - [28] = Reserved - [29] = ObjectRef 'error ' - [30] = ObjectRef ', captured stack trace: ' - [31] = EndClosureFunctionScope + [8] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [9] = Reserved + [10] = InstanceField dart:core::_Closure::_function_type_arguments (field) + [11] = Reserved + [12] = EmptyTypeArguments + [13] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) + [14] = Reserved + [15] = InstanceField dart:core::_Closure::_function (field) + [16] = Reserved + [17] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] + [18] = ICData dynamic target-name 'call', arg-desc CP#17 + [19] = ObjectRef 'caught ' + [20] = ObjectRef ' ' + [21] = DirectCall 'dart:core::_StringBase::_interpolate', ArgDesc num-args 1, num-type-args 0, names [] + [22] = Reserved + [23] = ClosureFunction 1 + [24] = ObjectRef 'danger bar' + [25] = Type dart:core::Error + [26] = InterfaceCall 'dart:core::Object::_simpleInstanceOf', ArgDesc num-args 2, num-type-args 0, names [] + [27] = Reserved + [28] = ObjectRef 'error ' + [29] = ObjectRef ', captured stack trace: ' + [30] = EndClosureFunctionScope } Closure #lib::testTryCatch3::'foo' () -> void ClosureCode { @@ -395,7 +394,7 @@ Push r0 PopLocal r2 Try #0 start: - PushConstant CP#25 + PushConstant CP#24 DirectCall 1, CP#4 Drop1 Jump L1 @@ -407,8 +406,8 @@ MoveSpecial exception, r2 MoveSpecial stackTrace, r3 Push r2 - PushConstant CP#26 - InterfaceCall 2, CP#27 + PushConstant CP#25 + InterfaceCall 2, CP#26 JumpIfFalse L2 Push r2 PopLocal r4 @@ -418,7 +417,7 @@ StoreLocal r5 Push r5 PushInt 0 - PushConstant CP#29 + PushConstant CP#28 StoreIndexedTOS Push r5 PushInt 1 @@ -426,14 +425,14 @@ StoreIndexedTOS Push r5 PushInt 2 - PushConstant CP#30 + PushConstant CP#29 StoreIndexedTOS Push r5 PushInt 3 Push r0 LoadContextVar 0, 2 StoreIndexedTOS - DirectCall 1, CP#22 + DirectCall 1, CP#21 DirectCall 1, CP#4 Drop1 Jump L1 @@ -637,26 +636,26 @@ PushConstant CP#5 DirectCall 1, CP#3 Drop1 - Allocate CP#10 + AllocateClosure CP#6 StoreLocal r8 Push r8 PushNull - StoreFieldTOS CP#11 + StoreFieldTOS CP#10 Push r8 PushNull - StoreFieldTOS CP#13 + StoreFieldTOS CP#12 Push r8 - PushConstant CP#15 - StoreFieldTOS CP#16 + PushConstant CP#14 + StoreFieldTOS CP#15 Push r8 PushConstant CP#6 - StoreFieldTOS CP#18 + StoreFieldTOS CP#17 Push r8 Push r0 StoreFieldTOS CP#7 PopLocal r7 Push r7 - DynamicCall 1, CP#21 + DynamicCall 1, CP#20 Drop1 Jump L4 Try #1 end: @@ -666,7 +665,7 @@ PopLocal r0 MoveSpecial exception, r5 MoveSpecial stackTrace, r6 - PushConstant CP#23 + PushConstant CP#22 DirectCall 1, CP#3 Drop1 Push r5 @@ -675,7 +674,7 @@ L4: Push r5 PopLocal r0 - PushConstant CP#23 + PushConstant CP#22 DirectCall 1, CP#3 Drop1 Jump L5 @@ -686,7 +685,7 @@ PopLocal r0 MoveSpecial exception, r3 MoveSpecial stackTrace, r4 - PushConstant CP#25 + PushConstant CP#24 DirectCall 1, CP#3 Drop1 Push r3 @@ -695,12 +694,12 @@ L5: Push r3 PopLocal r0 - PushConstant CP#25 + PushConstant CP#24 DirectCall 1, CP#3 Drop1 Jump L2 L2: - PushConstant CP#26 + PushConstant CP#25 DirectCall 1, CP#3 Drop1 Jump L3 @@ -709,8 +708,8 @@ ReturnTOS } ExceptionsTable { - try-index 0, outer -1, start 21, end 71, handler 71, needs-stack-trace, types [CP#22] - try-index 1, outer 0, start 29, end 54, handler 54, needs-stack-trace, types [CP#22] + try-index 0, outer -1, start 21, end 71, handler 71, needs-stack-trace, types [CP#21] + try-index 1, outer 0, start 29, end 54, handler 54, needs-stack-trace, types [CP#21] } ConstantPool { [0] = InterfaceCall 'dart:core::Object::==', ArgDesc num-args 2, num-type-args 0, names [] @@ -723,23 +722,22 @@ [7] = InstanceField dart:core::_Closure::_context (field) [8] = Reserved [9] = EndClosureFunctionScope - [10] = Class dart:core::_Closure - [11] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [12] = Reserved - [13] = InstanceField dart:core::_Closure::_function_type_arguments (field) - [14] = Reserved - [15] = EmptyTypeArguments - [16] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) - [17] = Reserved - [18] = InstanceField dart:core::_Closure::_function (field) - [19] = Reserved - [20] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] - [21] = ICData dynamic target-name 'call', arg-desc CP#20 - [22] = Type dynamic - [23] = ObjectRef 'finally 1' - [24] = ObjectRef 'after try 1' - [25] = ObjectRef 'finally 2' - [26] = ObjectRef 'case 2' + [10] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [11] = Reserved + [12] = InstanceField dart:core::_Closure::_function_type_arguments (field) + [13] = Reserved + [14] = EmptyTypeArguments + [15] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) + [16] = Reserved + [17] = InstanceField dart:core::_Closure::_function (field) + [18] = Reserved + [19] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] + [20] = ICData dynamic target-name 'call', arg-desc CP#19 + [21] = Type dynamic + [22] = ObjectRef 'finally 1' + [23] = ObjectRef 'after try 1' + [24] = ObjectRef 'finally 2' + [25] = ObjectRef 'case 2' } Closure #lib::testTryFinally2::'foo' () -> void ClosureCode { @@ -780,20 +778,20 @@ Push r0 PopLocal r3 Try #0 start: - Allocate CP#9 + AllocateClosure CP#0 StoreLocal r5 Push r5 PushNull - StoreFieldTOS CP#10 + StoreFieldTOS CP#9 Push r5 PushNull - StoreFieldTOS CP#12 + StoreFieldTOS CP#11 Push r5 - PushConstant CP#14 - StoreFieldTOS CP#15 + PushConstant CP#13 + StoreFieldTOS CP#14 Push r5 PushConstant CP#0 - StoreFieldTOS CP#17 + StoreFieldTOS CP#16 Push r5 Push r0 StoreFieldTOS CP#1 @@ -811,7 +809,7 @@ DirectCall 1, CP#3 Drop1 Push r2 - DynamicCall 1, CP#20 + DynamicCall 1, CP#19 Drop1 Push r3 Push r4 @@ -824,7 +822,7 @@ DirectCall 1, CP#3 Drop1 Push r2 - DynamicCall 1, CP#21 + DynamicCall 1, CP#20 Drop1 Push r0 LoadContextParent @@ -845,19 +843,18 @@ [6] = Type dynamic [7] = ObjectRef 'try 2' [8] = EndClosureFunctionScope - [9] = Class dart:core::_Closure - [10] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [11] = Reserved - [12] = InstanceField dart:core::_Closure::_function_type_arguments (field) - [13] = Reserved - [14] = EmptyTypeArguments - [15] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) - [16] = Reserved - [17] = InstanceField dart:core::_Closure::_function (field) - [18] = Reserved - [19] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] - [20] = ICData dynamic target-name 'call', arg-desc CP#19 - [21] = ICData dynamic target-name 'call', arg-desc CP#19 + [9] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [10] = Reserved + [11] = InstanceField dart:core::_Closure::_function_type_arguments (field) + [12] = Reserved + [13] = EmptyTypeArguments + [14] = InstanceField dart:core::_Closure::_delayed_type_arguments (field) + [15] = Reserved + [16] = InstanceField dart:core::_Closure::_function (field) + [17] = Reserved + [18] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] + [19] = ICData dynamic target-name 'call', arg-desc CP#18 + [20] = ICData dynamic target-name 'call', arg-desc CP#18 } Closure #lib::testTryFinally3::'<anonymous closure>' () -> dart:core::int ClosureCode {
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn index 55e9d2e..a13c951 100644 --- a/runtime/bin/BUILD.gn +++ b/runtime/bin/BUILD.gn
@@ -138,6 +138,8 @@ } deps = [ ":generate_abi_version_cc_file" ] + extra_deps + defines = [ "EXCLUDE_CFE_AND_KERNEL_PLATFORM" ] + sources = [ "address_sanitizer.cc", "builtin.cc", @@ -846,37 +848,23 @@ target_type = "static_library" } -executable("process_test") { - sources = [ - "process_test.cc", +dart_executable("dartaotruntime") { + extra_configs = [ "..:dart_precompiled_runtime_config" ] + extra_deps = [ "..:libdart_precompiled_runtime" ] + extra_sources = [ + "builtin.cc", + "snapshot_empty.cc", + "loader.cc", + "loader.h", + "gzip.cc", + "gzip.h", + "observatory_assets_empty.cc", ] } -action("generate_snapshot_test_dat_file") { - snapshot_test_dat_file = "$root_gen_dir/snapshot_test.dat" - snapshot_test_in_dat_file = "../vm/snapshot_test_in.dat" - snapshot_test_dart_file = "../vm/snapshot_test.dart" - inputs = [ - "../tools/create_string_literal.py", - snapshot_test_in_dat_file, - snapshot_test_dart_file, - ] - - outputs = [ - snapshot_test_dat_file, - ] - - script = "../tools/create_string_literal.py" - args = [ - "--output", - rebase_path(snapshot_test_dat_file), - "--input_cc", - rebase_path(snapshot_test_in_dat_file), - "--include", - "INTENTIONALLY_LEFT_BLANK", - "--var_name", - "INTENTIONALLY_LEFT_BLANK_TOO", - rebase_path(snapshot_test_dart_file), +executable("process_test") { + sources = [ + "process_test.cc", ] } @@ -925,6 +913,10 @@ "..:dart_os_config", "..:dart_maybe_product_config", ] + + if (dart_target_arch != "ia32") { + configs += [ "..:dart_precompiler_config" ] + } if (is_fuchsia) { configs -= [ "//build/config:symbol_visibility_hidden" ] } @@ -935,10 +927,9 @@ ":dart_snapshot_cc", ":gen_kernel_bytecode_dill", ":generate_abi_version_cc_file", - ":generate_snapshot_test_dat_file", ":libdart_builtin", ":standalone_dart_io", - "..:libdart_jit", + "..:libdart_nosnapshot_with_precompiler", "//third_party/zlib", ] include_dirs = [
diff --git a/runtime/bin/builtin.cc b/runtime/bin/builtin.cc index a10ee81..a18ca56 100644 --- a/runtime/bin/builtin.cc +++ b/runtime/bin/builtin.cc
@@ -39,8 +39,9 @@ Dart_Handle library = Dart_LookupLibrary(url); ASSERT(!Dart_IsError(library)); // Setup the native resolver for built in library functions. - DART_CHECK_VALID( - Dart_SetNativeResolver(library, NativeLookup, NativeSymbol)); + Dart_Handle result = + Dart_SetNativeResolver(library, NativeLookup, NativeSymbol); + ASSERT(!Dart_IsError(result)); } }
diff --git a/runtime/bin/builtin_gen_snapshot.cc b/runtime/bin/builtin_gen_snapshot.cc index 070e140..d4828a6 100644 --- a/runtime/bin/builtin_gen_snapshot.cc +++ b/runtime/bin/builtin_gen_snapshot.cc
@@ -30,7 +30,9 @@ bool* auto_setup_scope) { const char* function_name = NULL; Dart_Handle result = Dart_StringToCString(name, &function_name); - DART_CHECK_VALID(result); + if (Dart_IsError(result)) { + Dart_PropagateError(result); + } ASSERT(function_name != NULL); ASSERT(auto_setup_scope != NULL); *auto_setup_scope = true;
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc index b91c95b..0c27be9 100644 --- a/runtime/bin/builtin_natives.cc +++ b/runtime/bin/builtin_natives.cc
@@ -47,7 +47,9 @@ bool* auto_setup_scope) { const char* function_name = NULL; Dart_Handle err = Dart_StringToCString(name, &function_name); - DART_CHECK_VALID(err); + if (Dart_IsError(err)) { + Dart_PropagateError(err); + } ASSERT(function_name != NULL); ASSERT(auto_setup_scope != NULL); *auto_setup_scope = true;
diff --git a/runtime/bin/dart_embedder_api_impl.cc b/runtime/bin/dart_embedder_api_impl.cc index 4700774..492aab8 100644 --- a/runtime/bin/dart_embedder_api_impl.cc +++ b/runtime/bin/dart_embedder_api_impl.cc
@@ -88,7 +88,8 @@ Dart_EnterScope(); // Load embedder specific bits and return. if (!bin::VmService::Setup(config.ip, config.port, config.dev_mode, - /*trace_loading=*/false, config.deterministic)) { + config.disable_auth_codes, /*trace_loading=*/false, + config.deterministic)) { *error = strdup(bin::VmService::GetErrorMessage()); return nullptr; }
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc index 0ef24e7..edf14c4 100644 --- a/runtime/bin/dfe.cc +++ b/runtime/bin/dfe.cc
@@ -11,6 +11,7 @@ #include "bin/directory.h" #include "bin/error_exit.h" #include "bin/file.h" +#include "bin/main_options.h" #include "bin/platform.h" #include "bin/utils.h" #include "include/dart_tools_api.h" @@ -68,7 +69,13 @@ frontend_filename_(NULL), application_kernel_buffer_(NULL), application_kernel_buffer_size_(0) { -#if defined(DART_NO_SNAPSHOT) || defined(DART_PRECOMPILER) + // The run_vm_tests binary has the DART_PRECOMPILER set in order to allow unit + // tests to exercise JIT and AOT pipeline. + // + // Only on X64 do we have kernel-service.dart.snapshot available otherwise we + // need to fall back to the built-in one (if we have it). +#if defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM) || defined(DART_NO_SNAPSHOT) || \ + (defined(DART_PRECOMPILER) && defined(TARGET_ARCH_X64)) kernel_service_dill_ = NULL; kernel_service_dill_size_ = 0; platform_strong_dill_ = NULL; @@ -93,7 +100,7 @@ } void DFE::Init() { - Init(AbiVersion::GetCurrent()); + Init(Options::kAbiVersionUnset); } void DFE::Init(int target_abi_version) { @@ -122,7 +129,7 @@ auto dir_prefix = std::unique_ptr<char, void (*)(void*)>( GetDirectoryPrefixFromExeName(), free); - if (target_abi_version != AbiVersion::GetCurrent()) { + if (target_abi_version != Options::kAbiVersionUnset) { kernel_service_dill_ = NULL; kernel_service_dill_size_ = 0; platform_strong_dill_ = NULL;
diff --git a/runtime/bin/entrypoints_verification_test_extension.cc b/runtime/bin/entrypoints_verification_test_extension.cc index 5088e75..1f4eab6 100644 --- a/runtime/bin/entrypoints_verification_test_extension.cc +++ b/runtime/bin/entrypoints_verification_test_extension.cc
@@ -8,7 +8,15 @@ #include "./include/dart_api.h" #include "./include/dart_native_api.h" -#define CHECK(H) DART_CHECK_VALID(H) +#define CHECK(H) \ + do { \ + Dart_Handle __handle__ = H; \ + if (Dart_IsError(__handle__)) { \ + const char* message = Dart_GetError(__handle__); \ + fprintf(stderr, "Check \"" #H "\" failed: %s", message); \ + abort(); \ + } \ + } while (false) #define ASSERT(E) \ if (!(E)) { \
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc index 94a0c35258..935f2ea 100644 --- a/runtime/bin/io_natives.cc +++ b/runtime/bin/io_natives.cc
@@ -194,7 +194,7 @@ bool* auto_setup_scope) { const char* function_name = NULL; Dart_Handle result = Dart_StringToCString(name, &function_name); - DART_CHECK_VALID(result); + ASSERT(!Dart_IsError(result)); ASSERT(function_name != NULL); ASSERT(auto_setup_scope != NULL); *auto_setup_scope = true;
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc index 9117f38..2d09c17 100644 --- a/runtime/bin/main.cc +++ b/runtime/bin/main.cc
@@ -12,6 +12,7 @@ #include "include/dart_embedder_api.h" #include "include/dart_tools_api.h" +#include "bin/abi_version.h" #include "bin/builtin.h" #include "bin/console.h" #include "bin/crashpad.h" @@ -508,10 +509,10 @@ CHECK_RESULT(result); // Load embedder specific bits and return. - if (!VmService::Setup(Options::vm_service_server_ip(), - Options::vm_service_server_port(), - Options::vm_service_dev_mode(), - Options::trace_loading(), Options::deterministic())) { + if (!VmService::Setup( + Options::vm_service_server_ip(), Options::vm_service_server_port(), + Options::vm_service_dev_mode(), Options::vm_service_auth_disabled(), + Options::trace_loading(), Options::deterministic())) { *error = strdup(VmService::GetErrorMessage()); return NULL; } @@ -605,7 +606,8 @@ Dart_Isolate isolate = NULL; #if !defined(DART_PRECOMPILED_RUNTIME) - if (!isolate_run_app_snapshot && (isolate_snapshot_data == NULL)) { + if ((!isolate_run_app_snapshot && (isolate_snapshot_data == NULL)) || + (Options::target_abi_version() != Options::kAbiVersionUnset)) { const uint8_t* platform_kernel_buffer = NULL; intptr_t platform_kernel_buffer_size = 0; dfe.LoadPlatform(&platform_kernel_buffer, &platform_kernel_buffer_size);
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc index a0db7aa..42fa0b5 100644 --- a/runtime/bin/main_options.cc +++ b/runtime/bin/main_options.cc
@@ -120,13 +120,14 @@ // clang-format off void Options::PrintUsage() { Log::PrintErr( - "Usage: dart [<vm-flags>] <dart-script-file> [<dart-options>]\n" + "Usage: dart [<vm-flags>] <dart-script-file> [<script-arguments>]\n" "\n" - "Executes the Dart script passed as <dart-script-file>.\n" + "Executes the Dart script <dart-script-file> with " + "the given list of <script-arguments>.\n" "\n"); if (!Options::verbose_option()) { Log::PrintErr( -"Common options:\n" +"Common VM flags:\n" "--enable-asserts\n" " Enable assert statements.\n" "--help or -h\n" @@ -325,7 +326,7 @@ return true; } -int Options::target_abi_version_ = AbiVersion::GetCurrent(); +int Options::target_abi_version_ = Options::kAbiVersionUnset; bool Options::ProcessAbiVersionOption(const char* arg, CommandLineOptions* vm_options) { const char* value = OptionProcessor::ProcessOption(arg, "--use_abi_version=");
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h index e290696..8513fe3 100644 --- a/runtime/bin/main_options.h +++ b/runtime/bin/main_options.h
@@ -38,6 +38,7 @@ V(version, version_option) \ V(compile_all, compile_all) \ V(disable_service_origin_check, vm_service_dev_mode) \ + V(disable_service_auth_codes, vm_service_auth_disabled) \ V(deterministic, deterministic) \ V(trace_loading, trace_loading) \ V(short_socket_read, short_socket_read) \ @@ -116,6 +117,7 @@ static const char* vm_service_server_ip() { return vm_service_server_ip_; } static int vm_service_server_port() { return vm_service_server_port_; } + static constexpr int kAbiVersionUnset = -1; static int target_abi_version() { return target_abi_version_; } #if !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc index 4eb653e..aa36a87 100644 --- a/runtime/bin/run_vm_tests.cc +++ b/runtime/bin/run_vm_tests.cc
@@ -156,6 +156,14 @@ free(*error); *error = NULL; } + // If a test does not actually require the kernel isolate the main thead can + // start calling Dart::Cleanup() while the kernel isolate is booting up. + // This can cause the isolate to be killed early which will return `nullptr` + // here. + if (isolate == nullptr) { + delete isolate_data; + return NULL; + } } if (isolate == NULL) { delete isolate_data;
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart index dcad9f8..447d334 100644 --- a/runtime/bin/vmservice/server.dart +++ b/runtime/bin/vmservice/server.dart
@@ -147,6 +147,7 @@ final String _ip; final int _port; final bool _originCheckDisabled; + final bool _authCodesDisabled; HttpServer _server; bool get running => _server != null; @@ -157,11 +158,15 @@ } var ip = _server.address.address; var port = _server.port; - var path = useAuthToken ? "$serviceAuthToken/" : "/"; + var path = !_authCodesDisabled ? "$serviceAuthToken/" : "/"; return new Uri(scheme: 'http', host: ip, port: port, path: path); } - Server(this._service, this._ip, this._port, this._originCheckDisabled); + // On Fuchsia, authentication codes are disabled by default. To enable, the authentication token + // would have to be written into the hub alongside the port number. + Server(this._service, this._ip, this._port, this._originCheckDisabled, + bool authCodesDisabled) + : _authCodesDisabled = (authCodesDisabled || Platform.isFuchsia); bool _isAllowedOrigin(String origin) { Uri uri; @@ -214,7 +219,7 @@ /// Checks the [requestUri] for the service auth token and returns the path. /// If the service auth token check fails, returns null. String _checkAuthTokenAndGetPath(Uri requestUri) { - if (!useAuthToken) { + if (_authCodesDisabled) { return requestUri.path == '/' ? ROOT_REDIRECT_PATH : requestUri.path; } final List<String> requestPathSegments = requestUri.pathSegments;
diff --git a/runtime/bin/vmservice/vmservice_io.dart b/runtime/bin/vmservice/vmservice_io.dart index 64d602d..6d7c55f 100644 --- a/runtime/bin/vmservice/vmservice_io.dart +++ b/runtime/bin/vmservice/vmservice_io.dart
@@ -23,6 +23,9 @@ // Should the HTTP server auto start? @pragma("vm:entry-point") bool _autoStart; +// Should the HTTP server require an auth code? +@pragma("vm:entry-point") +bool _authCodesDisabled; // Should the HTTP server run in devmode? @pragma("vm:entry-point") bool _originCheckDisabled; @@ -45,7 +48,8 @@ // Lazily create service. var service = new VMService(); // Lazily create server. - server = new Server(service, _ip, _port, _originCheckDisabled); + server = + new Server(service, _ip, _port, _originCheckDisabled, _authCodesDisabled); } Future cleanupCallback() async {
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc index 04a3e89..683d4b4 100644 --- a/runtime/bin/vmservice_impl.cc +++ b/runtime/bin/vmservice_impl.cc
@@ -113,6 +113,7 @@ bool VmService::Setup(const char* server_ip, intptr_t server_port, bool dev_mode_server, + bool auth_codes_disabled, bool trace_loading, bool deterministic) { Dart_Isolate isolate = Dart_CurrentIsolate(); @@ -169,6 +170,11 @@ SHUTDOWN_ON_ERROR(result); result = Dart_SetField(library, DartUtils::NewString("_originCheckDisabled"), Dart_NewBoolean(dev_mode_server)); + SHUTDOWN_ON_ERROR(result); + + result = Dart_SetField(library, DartUtils::NewString("_authCodesDisabled"), + Dart_NewBoolean(auth_codes_disabled)); + SHUTDOWN_ON_ERROR(result); // Are we running on Windows? #if defined(HOST_OS_WINDOWS)
diff --git a/runtime/bin/vmservice_impl.h b/runtime/bin/vmservice_impl.h index 0a40178..51e9bfc 100644 --- a/runtime/bin/vmservice_impl.h +++ b/runtime/bin/vmservice_impl.h
@@ -17,6 +17,7 @@ static bool Setup(const char* server_ip, intptr_t server_port, bool dev_mode_server, + bool auth_codes_disabled, bool trace_loading, bool deterministic);
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h index 51a1f80..be316ee 100644 --- a/runtime/include/dart_api.h +++ b/runtime/include/dart_api.h
@@ -386,34 +386,10 @@ * * \param An error handle (See Dart_IsError) * - * \return On success, this function does not return. On failure, an - * error handle is returned. + * \return On success, this function does not return. On failure, the + * process is terminated. */ -DART_EXPORT Dart_Handle Dart_PropagateError(Dart_Handle handle); -/* TODO(turnidge): Should this really return an error handle? */ -/* Consider just terminating. */ - -/* Internal routine used for reporting error handles. */ -DART_EXPORT void _Dart_ReportErrorHandle(const char* file, - int line, - const char* handle_string, - const char* error); - -/* TODO(turnidge): Move DART_CHECK_VALID to some sort of dart_utils - * header instead of this header. */ -/** - * Aborts the process if 'handle' is an error handle. - * - * Provided for convenience. - */ -#define DART_CHECK_VALID(handle) \ - { \ - Dart_Handle __handle = handle; \ - if (Dart_IsError((__handle))) { \ - _Dart_ReportErrorHandle(__FILE__, __LINE__, #handle, \ - Dart_GetError(__handle)); \ - } \ - } +DART_EXPORT void Dart_PropagateError(Dart_Handle handle); /** * Converts an object to a string.
diff --git a/runtime/include/dart_embedder_api.h b/runtime/include/dart_embedder_api.h index eda9059..9a91a83 100644 --- a/runtime/include/dart_embedder_api.h +++ b/runtime/include/dart_embedder_api.h
@@ -60,6 +60,7 @@ // TODO(vegorov) document these ones. bool dev_mode; bool deterministic; + bool disable_auth_codes; }; // Create and initialize vm-service isolate. This method should be used
diff --git a/runtime/lib/convert_patch.dart b/runtime/lib/convert_patch.dart index d2cf222..747e1e3 100644 --- a/runtime/lib/convert_patch.dart +++ b/runtime/lib/convert_patch.dart
@@ -1857,8 +1857,7 @@ final to = endIndex; // Special case for _Uint8ArrayView. - final cid = ClassID.getID(units); - if (identical(cid, ClassID.cidUint8ArrayView)) { + if (units is Uint8List) { if (from >= 0 && to >= 0 && to <= units.length) { for (int i = from; i < to; i++) { final unit = units[i];
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc index d0e9f93..916649f 100644 --- a/runtime/lib/mirrors.cc +++ b/runtime/lib/mirrors.cc
@@ -553,15 +553,22 @@ const Library& lib = Library::Handle(zone, Library::MirrorsLibrary()); const Class& cls = Class::Handle( zone, lib.LookupClassAllowPrivate(Symbols::_LocalMethodMirror())); - const Error& error = Error::Handle(zone, cls.EnsureIsFinalized(thread)); + Error& error = Error::Handle(zone); + error ^= cls.EnsureIsFinalized(thread); ASSERT(error.IsNull()); - Field& field = Field::Handle(); - Smi& value = Smi::Handle(); + Field& field = Field::Handle(zone); + Smi& value = Smi::Handle(zone); + String& fname = String::Handle(zone); #define CHECK_KIND_SHIFT(name) \ - field = cls.LookupField(String::Handle(String::New(#name))); \ + fname ^= String::New(#name); \ + field = cls.LookupField(fname); \ ASSERT(!field.IsNull()); \ + if (field.IsUninitialized()) { \ + error ^= field.Initialize(); \ + ASSERT(error.IsNull()); \ + } \ value ^= field.StaticValue(); \ ASSERT(value.Value() == Mirrors::name); MIRRORS_KIND_SHIFT_LIST(CHECK_KIND_SHIFT)
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart index e75284a..10992637 100644 --- a/runtime/lib/string_patch.dart +++ b/runtime/lib/string_patch.dart
@@ -224,8 +224,7 @@ var s = _OneByteString._allocate(len); // Special case for _Uint8ArrayView. - final cid = ClassID.getID(charCodes); - if (identical(cid, ClassID.cidUint8ArrayView)) { + if (charCodes is Uint8List) { if (start >= 0 && len >= 0) { for (int i = 0; i < len; i++) { s._setAt(i, charCodes[start + i]);
diff --git a/runtime/observatory/HACKING.md b/runtime/observatory/HACKING.md index afcab5c..b645f9e 100644 --- a/runtime/observatory/HACKING.md +++ b/runtime/observatory/HACKING.md
@@ -62,8 +62,8 @@ submit your code. The main reviewers for Observatory related CLs are: - - turnidge - - johnmccutchan + - asiva + - bkonyi - rmacnak ## Write a new service test
diff --git a/runtime/observatory/lib/service_io.dart b/runtime/observatory/lib/service_io.dart index 4565d9f..2ecbbf1 100644 --- a/runtime/observatory/lib/service_io.dart +++ b/runtime/observatory/lib/service_io.dart
@@ -52,9 +52,7 @@ } } -/// The [WebSocketVM] communicates with a Dart VM over WebSocket. The Dart VM -/// can be embedded in Chromium or standalone. In the case of Chromium, we -/// make the service requests via the Chrome Remote Debugging Protocol. +/// The [WebSocketVM] communicates with a Dart VM over WebSocket. class WebSocketVM extends CommonWebSocketVM { WebSocketVM(WebSocketVMTarget target) : super(target, new _IOWebSocket()); }
diff --git a/runtime/observatory/lib/src/app/application.dart b/runtime/observatory/lib/src/app/application.dart index 740c6ec..9b7f90c 100644 --- a/runtime/observatory/lib/src/app/application.dart +++ b/runtime/observatory/lib/src/app/application.dart
@@ -277,11 +277,6 @@ events.onConnectionClosed.listen(_addNotification); } - loadCrashDump(Map crashDump) { - _switchVM(new FakeVM(crashDump['result'])); - app.locationManager.go(Uris.vm()); - } - void handleException(e, st) { if (e is ServerRpcException) { if (e.code == ServerRpcException.kFeatureDisabled) return;
diff --git a/runtime/observatory/lib/src/app/page.dart b/runtime/observatory/lib/src/app/page.dart index 9563098..526e182 100644 --- a/runtime/observatory/lib/src/app/page.dart +++ b/runtime/observatory/lib/src/app/page.dart
@@ -890,9 +890,7 @@ void onInstall() { if (element == null) { - element = new VMConnectElement( - ObservatoryApplication.app.targets, - ObservatoryApplication.app.loadCrashDump, + element = new VMConnectElement(ObservatoryApplication.app.targets, ObservatoryApplication.app.notifications, queue: ObservatoryApplication.app.queue); }
diff --git a/runtime/observatory/lib/src/elements/vm_connect.dart b/runtime/observatory/lib/src/elements/vm_connect.dart index d6036df..c8cac11 100644 --- a/runtime/observatory/lib/src/elements/vm_connect.dart +++ b/runtime/observatory/lib/src/elements/vm_connect.dart
@@ -16,8 +16,6 @@ import 'package:observatory/src/elements/view_footer.dart'; import 'package:observatory/src/elements/vm_connect_target.dart'; -typedef void CrashDumpLoadCallback(Map dump); - class VMConnectElement extends HtmlElement implements Renderable { static const tag = const Tag<VMConnectElement>('vm-connect', dependencies: const [ @@ -31,24 +29,21 @@ Stream<RenderedEvent<VMConnectElement>> get onRendered => _r.onRendered; - CrashDumpLoadCallback _loadDump; M.NotificationRepository _notifications; M.TargetRepository _targets; StreamSubscription _targetsSubscription; String _address; - factory VMConnectElement(M.TargetRepository targets, - CrashDumpLoadCallback loadDump, M.NotificationRepository notifications, + factory VMConnectElement( + M.TargetRepository targets, M.NotificationRepository notifications, {String address: '', RenderingQueue queue}) { assert(address != null); - assert(loadDump != null); assert(notifications != null); assert(targets != null); VMConnectElement e = document.createElement(tag.name); e._r = new RenderingScheduler<VMConnectElement>(e, queue: queue); e._address = address; - e._loadDump = loadDump; e._notifications = notifications; e._targets = targets; return e; @@ -124,19 +119,6 @@ ..text = 'Run Standalone with: \'--observe\'', ], new DivElement()..classes = ['flex-item-20-percent'], - new DivElement() - ..classes = ['flex-item-40-percent'] - ..children = <Element>[ - new HeadingElement.h2()..text = 'View crash dump', - new BRElement(), - _createCrushDumpLoader(), - new BRElement(), - new BRElement(), - new PreElement() - ..classes = ['well'] - ..text = 'Request a crash dump with:\n' - '\'curl $host:$port/_getCrashDump > dump.json\'', - ] ], ], new ViewFooterElement(queue: _r.queue) @@ -158,20 +140,6 @@ return textbox; } - FileUploadInputElement _createCrushDumpLoader() { - FileUploadInputElement e = new FileUploadInputElement() - ..id = 'crashDumpFile'; - e.onChange.listen((_) { - var reader = new FileReader(); - reader.readAsText(e.files[0]); - reader.onLoad.listen((_) { - var crashDump = json.decode(reader.result); - _loadDump(crashDump); - }); - }); - return e; - } - void _createAndConnect() { if (_address == null || _address.isEmpty) return; String normalizedNetworkAddress = _normalizeStandaloneAddress(_address);
diff --git a/runtime/observatory/lib/src/repositories/target.dart b/runtime/observatory/lib/src/repositories/target.dart index 245542d..4fb1fb1 100644 --- a/runtime/observatory/lib/src/repositories/target.dart +++ b/runtime/observatory/lib/src/repositories/target.dart
@@ -120,7 +120,7 @@ scheme: 'ws', host: host ?? serverAddress.host, port: int.tryParse(port ?? '') ?? serverAddress.port, - path: '/ws', + path: serverAddress.path.isEmpty ? '/ws' : serverAddress.path + 'ws', ); return wsAddress.toString(); }
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart index cc8f158..7e828a1 100644 --- a/runtime/observatory/lib/src/service/object.dart +++ b/runtime/observatory/lib/src/service/object.dart
@@ -99,12 +99,6 @@ String toString() => 'MalformedResponseRpcException(${message})'; } -class FakeVMRpcException extends RpcException { - FakeVMRpcException(String message) : super(message); - - String toString() => 'FakeVMRpcException(${message})'; -} - /// A [ServiceObject] represents a persistent object within the vm. abstract class ServiceObject implements M.ObjectRef { static int LexicalSortName(ServiceObject o1, ServiceObject o2) { @@ -886,8 +880,6 @@ await listenEventStream(kDebugStream, _dispatchEventToIsolate); await listenEventStream(_kGraphStream, _dispatchEventToIsolate); await listenEventStream(kServiceStream, _updateService); - } on FakeVMRpcException catch (_) { - // ignore FakeVMRpcExceptions here. } on NetworkRpcException catch (_) { // ignore network errors here. } @@ -1011,78 +1003,6 @@ } } -class FakeVM extends VM { - String get displayName => name; - - final Map _responses = {}; - FakeVM(Map responses) { - if (responses == null) { - return; - } - responses.forEach((uri, response) { - // Encode as string. - _responses[_canonicalizeUri(Uri.parse(uri))] = response; - }); - } - - String _canonicalizeUri(Uri uri) { - // We use the uri as the key to the response map. Uri parameters can be - // serialized in any order, this function canonicalizes the uri parameters - // so they are serialized in sorted-by-parameter-name order. - var method = uri.path; - // Create a map sorted on insertion order. - var parameters = new Map(); - // Sort keys. - var sortedKeys = uri.queryParameters.keys.toList(); - sortedKeys.sort(); - // Filter keys to remove any private options. - sortedKeys.removeWhere((k) => k.startsWith('_')); - // Insert parameters in sorted order. - for (var key in sortedKeys) { - parameters[key] = uri.queryParameters[key]; - } - // Return canonical uri. - return new Uri(path: method, queryParameters: parameters).toString(); - } - - /// Force the VM to disconnect. - void disconnect() { - _onDisconnect.complete('Disconnected'); - } - - // Always connected. - Future _onConnect; - Future get onConnect { - if (_onConnect != null) { - return _onConnect; - } - _onConnect = new Future.value(this); - return _onConnect; - } - - bool get isConnected => !isDisconnected; - // Only complete when requested. - Completer<String> _onDisconnect = new Completer<String>(); - Future<String> get onDisconnect => _onDisconnect.future; - bool get isDisconnected => _onDisconnect.isCompleted; - - Future<Map> invokeRpcRaw(String method, Map params) { - if (params.isEmpty) { - params = null; - } - var key = _canonicalizeUri(new Uri(path: method, queryParameters: params)); - var response = _responses[key]; - if (response == null) { - return new Future.error(new FakeVMRpcException( - "Unable to find key '${key}' in cached response set")); - } - return new Future.value(response); - } - - @override - WebSocketVMTarget get target => throw new UnimplementedError(); -} - /// Snapshot in time of tag counters. class TagProfileSnapshot { final double seconds;
diff --git a/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart b/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart index 8727212..1f5d1b6 100644 --- a/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart +++ b/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart
@@ -10,8 +10,6 @@ import 'package:observatory/src/elements/vm_connect.dart'; import '../mocks.dart'; -void load(_) {} - main() { VMConnectElement.tag.ensureRegistration(); @@ -21,14 +19,13 @@ group('instantiation', () { test('default', () { final e = new VMConnectElement( - new TargetRepositoryMock(), load, new NotificationRepositoryMock()); + new TargetRepositoryMock(), new NotificationRepositoryMock()); expect(e, isNotNull, reason: 'element correctly created'); }); }); test('is correctly listening', () async { final targets = new TargetRepositoryMock(); - final e = - new VMConnectElement(targets, load, new NotificationRepositoryMock()); + final e = new VMConnectElement(targets, new NotificationRepositoryMock()); document.body.append(e); await e.onRendered.first; expect(targets.hasListeners, isTrue, reason: 'is listening'); @@ -42,8 +39,7 @@ const TargetMock(name: 't-1'), const TargetMock(name: 't-2'), ]); - final e = - new VMConnectElement(targets, load, new NotificationRepositoryMock()); + final e = new VMConnectElement(targets, new NotificationRepositoryMock()); document.body.append(e); await e.onRendered.first; expect(targets.listInvoked, isTrue, reason: 'should invoke list()'); @@ -57,8 +53,7 @@ test('react to update event', () async { final list = <TargetMock>[const TargetMock(name: 't-1')]; final targets = new TargetRepositoryMock(list: list); - final e = - new VMConnectElement(targets, load, new NotificationRepositoryMock()); + final e = new VMConnectElement(targets, new NotificationRepositoryMock()); document.body.append(e); await e.onRendered.first; expect(e.querySelectorAll(tTag).length, equals(1)); @@ -80,8 +75,7 @@ add: expectAsync1((String val) { expect(val, equals(address)); }, count: 1, reason: 'should be invoked')); - final e = new VMConnectElement( - targets, load, new NotificationRepositoryMock(), + final e = new VMConnectElement(targets, new NotificationRepositoryMock(), address: address); document.body.append(e); await e.onRendered.first; @@ -96,8 +90,7 @@ setCurrent: expectAsync1((M.Target t) { expect(t, equals(list[0])); }, count: 1, reason: 'should be invoked')); - final e = - new VMConnectElement(targets, load, new NotificationRepositoryMock()); + final e = new VMConnectElement(targets, new NotificationRepositoryMock()); document.body.append(e); await e.onRendered.first; (e.querySelector(tTag) as VMConnectTargetElement).connect(); @@ -111,8 +104,7 @@ delete: expectAsync1((M.Target t) { expect(t, equals(list[0])); }, count: 1, reason: 'should be invoked')); - final e = - new VMConnectElement(targets, load, new NotificationRepositoryMock()); + final e = new VMConnectElement(targets, new NotificationRepositoryMock()); document.body.append(e); await e.onRendered.first; (e.querySelector(tTag) as VMConnectTargetElement).delete();
diff --git a/runtime/observatory/tests/service/crash_dump_test.dart b/runtime/observatory/tests/service/crash_dump_test.dart deleted file mode 100644 index 2309c94..0000000 --- a/runtime/observatory/tests/service/crash_dump_test.dart +++ /dev/null
@@ -1,36 +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 crash_dump_test; - -import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; -import 'package:observatory/service_io.dart'; - -import 'test_helper.dart'; - -Future warmup() async { - print('hi'); -} - -var tests = <VMTest>[ - (VM vm) async { - HttpClient client = new HttpClient(); - print('Requesting uri ${serviceHttpAddress}/_getCrashDump'); - var request = - await client.getUrl(Uri.parse('$serviceHttpAddress/_getCrashDump')); - var response = await request.close(); - print('Received response'); - Completer completer = new Completer<String>(); - StringBuffer sb = new StringBuffer(); - response.transform(utf8.decoder).listen((chunk) { - sb.write(chunk); - }, onDone: () => completer.complete(sb.toString())); - var responseString = await completer.future; - json.decode(responseString); - } -]; - -main(args) async => runVMTests(args, tests, testeeBefore: warmup);
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status index 086e741a..7012181 100644 --- a/runtime/observatory/tests/service/service_kernel.status +++ b/runtime/observatory/tests/service/service_kernel.status
@@ -50,6 +50,9 @@ regress_34841_test: RuntimeError # http://dartbug.com/34841 unused_changes_in_last_reload_test: RuntimeError +[ $compiler == dartkb ] +*: Skip # Debugging capabilities are not yet supported in bytecode modes. + [ $compiler == dartkp ] *: SkipByDesign # Non-kernel also skips precompiled mode.
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart index 3913854..05c37a1 100644 --- a/runtime/observatory/tests/service/test_helper.dart +++ b/runtime/observatory/tests/service/test_helper.dart
@@ -132,6 +132,9 @@ if (pause_on_exit) { fullArgs.add('--pause-isolates-on-exit'); } + if (!useAuthToken) { + fullArgs.add('--disable-service-auth-codes'); + } if (pause_on_unhandled_exceptions) { fullArgs.add('--pause-isolates-on-unhandled-exceptions'); } @@ -147,7 +150,7 @@ fullArgs.addAll(args); return _spawnCommon(dartExecutable, fullArgs, - <String, String>{'DART_SERVICE_USE_AUTH': '$useAuthToken'}); + <String, String>{}); } Future<Process> _spawnSkyProcess(
diff --git a/runtime/runtime_args.gni b/runtime/runtime_args.gni index d830208..cf9e71d 100644 --- a/runtime/runtime_args.gni +++ b/runtime/runtime_args.gni
@@ -95,7 +95,7 @@ # We create a kernel service app-jit snapshot only for when the target # architecture is x64 for other cases we will use the '.dill' file # which is already linked in the VM. - if (dart_target_arch == "x64" && !dart_platform_bytecode) { + if (dart_target_arch == "x64") { create_kernel_service_snapshot = true } else { create_kernel_service_snapshot = false
diff --git a/runtime/tests/vm/dart/appjit_bytecode_simple_test.dart b/runtime/tests/vm/dart/appjit_bytecode_simple_test.dart index 6600482..d936339 100644 --- a/runtime/tests/vm/dart/appjit_bytecode_simple_test.dart +++ b/runtime/tests/vm/dart/appjit_bytecode_simple_test.dart
@@ -2,11 +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. +// OtherResources=appjit_bytecode_simple_test_body.dart + // Verify that app-jit snapshot contains dependencies between classes and CHA // optimized code. import 'dart:async'; +import 'dart:io' show Platform; import 'snapshot_test_helper.dart'; -Future<void> main() => runAppJitBytecodeTest(); +Future<void> main() => runAppJitBytecodeTest( + Platform.script.resolve('appjit_bytecode_simple_test_body.dart'));
diff --git a/runtime/tests/vm/dart/appjit_cha_deopt_test.dart b/runtime/tests/vm/dart/appjit_cha_deopt_test.dart index fabc41b..104d431 100644 --- a/runtime/tests/vm/dart/appjit_cha_deopt_test.dart +++ b/runtime/tests/vm/dart/appjit_cha_deopt_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. +// OtherResources=appjit_cha_deopt_test_body.dart // VMOptions=--optimization-counter-threshold=100 // Verify that app-jit snapshot contains dependencies between classes and CHA // optimized code. import 'dart:async'; +import 'dart:io' show Platform; import 'snapshot_test_helper.dart'; -Future<void> main() => runAppJitTest(); +Future<void> main() => + runAppJitTest(Platform.script.resolve('appjit_cha_deopt_test_body.dart'));
diff --git a/runtime/tests/vm/dart/appjit_load_static_licm_test.dart b/runtime/tests/vm/dart/appjit_load_static_licm_test.dart index 9f51b70..804e30c 100644 --- a/runtime/tests/vm/dart/appjit_load_static_licm_test.dart +++ b/runtime/tests/vm/dart/appjit_load_static_licm_test.dart
@@ -2,11 +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. +// OtherResources=appjit_load_static_licm_test_body.dart + // Verify that app-jit snapshot contains dependencies between classes and CHA // optimized code. import 'dart:async'; +import 'dart:io' show Platform; import 'snapshot_test_helper.dart'; -Future<void> main() => runAppJitTest(); +Future<void> main() => runAppJitTest( + Platform.script.resolve('appjit_load_static_licm_test_body.dart'));
diff --git a/runtime/tests/vm/dart/snapshot_test_helper.dart b/runtime/tests/vm/dart/snapshot_test_helper.dart index 0a043af..5c63da1 100644 --- a/runtime/tests/vm/dart/snapshot_test_helper.dart +++ b/runtime/tests/vm/dart/snapshot_test_helper.dart
@@ -151,12 +151,10 @@ }); } -runAppJitTest() async { +runAppJitTest(Uri testScriptUri) async { await withTempDir((String temp) async { final snapshotPath = p.join(temp, 'app.jit'); - final testPath = Platform.script - .toFilePath() - .replaceAll(new RegExp(r'_test.dart$'), '_test_body.dart'); + final testPath = testScriptUri.toFilePath(); final trainingResult = await runDart('TRAINING RUN', [ '--snapshot=$snapshotPath', @@ -170,12 +168,10 @@ }); } -Future<void> runAppJitBytecodeTest() async { +Future<void> runAppJitBytecodeTest(Uri testScriptUri) async { await withTempDir((String temp) async { final snapshotPath = p.join(temp, 'app.jit'); - final testPath = Platform.script - .toFilePath() - .replaceAll(new RegExp(r'_test.dart$'), '_test_body.dart'); + final testPath = testScriptUri.toFilePath(); final trainingResult = await runDart('TRAINING RUN', [ '--enable_interpreter',
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status index 6554bb2..b626857 100644 --- a/runtime/tests/vm/vm.status +++ b/runtime/tests/vm/vm.status
@@ -267,7 +267,6 @@ # Tests that use functionality not supported in Dart 2. [ ($compiler == dartk || $compiler == dartkb) || $compiler == dartkp ] cc/DartAPI_IsolateSetCheckedMode: SkipByDesign # Checked mode is not relevant for dart 2? -cc/CompileFunctionOnHelperThread: SkipByDesign cc/CompileFunction: SkipByDesign cc/InvokeDynamic_CompileError: SkipByDesign cc/InvokeStatic_CompileError: SkipByDesign @@ -299,3 +298,9 @@ [ $compiler == dartkp ] dart/v8_snapshot_profile_writer_test: Pass, Slow # Can be slow due to re-invoking the precompiler. + +[ $compiler == dartkb ] +cc/*: Skip # Bytecode modes are not properly hooked up in run_vm_tests. + +[ $mode == debug ] +cc/IRTest_TypedDataAOT_FunctionalGetSet: Skip # run_vm_tests contains JIT/AOT but FLAG_precompiled_mode is not always correct. This causes this test to fail in debug mode, hitting an assertion. See http://dartbug.com/36521
diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart index 27cd715..9f79e8a 100644 --- a/runtime/tools/dartfuzz/dartfuzz.dart +++ b/runtime/tools/dartfuzz/dartfuzz.dart
@@ -13,7 +13,7 @@ // Version of DartFuzz. Increase this each time changes are made // to preserve the property that a given version of DartFuzz yields // the same fuzzed program for a deterministic random seed. -const String version = '1.5'; +const String version = '1.7'; // Restriction on statement and expression depths. const int stmtDepth = 2; @@ -101,10 +101,10 @@ void emitClasses() { assert(classFields.length == classMethods.length); for (int i = 0; i < classFields.length; i++) { - currentClass = i; emitLn('class X$i ${i == 0 ? "" : "extends X${i - 1}"} {'); indent += 2; emitVarDecls('$fieldName${i}_', classFields[i]); + currentClass = i; emitMethods('$methodName${i}_', classMethods[i]); emitLn('void run() {'); indent += 2; @@ -156,7 +156,7 @@ for (int i = 0; i < vars.length; i++) { DartType tp = vars[i]; emitLn('${tp.name} $name$i = ', newline: false); - emitLiteral(tp); + emitLiteral(0, tp); emit(';', newline: true); } emit('', newline: true); @@ -534,39 +534,96 @@ void emitString() { emit("'"); - int l = rand.nextInt(8); - for (int i = 0; i < l; i++) { + for (int i = 0, n = rand.nextInt(8); i < n; i++) { emitChar(); } emit("'"); } - void emitList(String open, String close) { - emit('$open '); - int l = 1 + rand.nextInt(4); - for (int i = 0; i < l; i++) { - emitInt(); - if (i != (l - 1)) { + void emitElementExpr(int depth, DartType tp) { + if (currentMethod != null) { + emitExpr(depth, tp); + } else { + emitLiteral(depth, tp); + } + } + + void emitElement(int depth, DartType tp) { + if (tp == DartType.INT_STRING_MAP) { + emitSmallPositiveInt(); + emit(' : '); + emitElementExpr(depth, DartType.STRING); + } else { + emitElementExpr(depth, DartType.INT); + } + } + + void emitCollectionElement(int depth, DartType tp) { + int r = depth <= exprDepth ? rand.nextInt(10) : 10; + switch (r + 3) { + // TODO(ajcbik): enable when on by default + // Favors elements over control-flow collections. + case 0: + emit('...'); // spread + emitCollection(depth + 1, tp); + break; + case 1: + emit('if ('); + emitElementExpr(depth + 1, DartType.BOOL); + emit(') '); + emitCollectionElement(depth + 1, tp); + if (rand.nextBool()) { + emit(' else '); + emitCollectionElement(depth + 1, tp); + } + break; + case 2: + { + int i = localVars.length; + emit('for (int $localName$i '); + // For-loop (induction, list, set). + switch (rand.nextInt(3)) { + case 0: + emit('= 0; $localName$i < '); + emitSmallPositiveInt(); + emit('; $localName$i++) '); + break; + case 1: + emit('in '); + emitCollection(depth + 1, DartType.INT_LIST); + emit(') '); + break; + default: + emit('in '); + emitCollection(depth + 1, DartType.INT_SET); + emit(') '); + break; + } + nest++; + localVars.add(DartType.INT); + emitCollectionElement(depth + 1, tp); + localVars.removeLast(); + nest--; + break; + } + default: + emitElement(depth, tp); + break; + } + } + + void emitCollection(int depth, DartType tp) { + emit(tp == DartType.INT_LIST ? '[ ' : '{ '); + for (int i = 0, n = 1 + rand.nextInt(8); i < n; i++) { + emitCollectionElement(depth, tp); + if (i != (n - 1)) { emit(', '); } } - emit(' $close'); + emit(tp == DartType.INT_LIST ? ' ]' : ' }'); } - void emitMap() { - emit('{ '); - int l = 1 + rand.nextInt(4); - for (int i = 0; i < l; i++) { - emit('$i : '); - emitString(); - if (i != (l - 1)) { - emit(', '); - } - } - emit(' }'); - } - - void emitLiteral(DartType tp) { + void emitLiteral(int depth, DartType tp) { if (tp == DartType.BOOL) { emitBool(); } else if (tp == DartType.INT) { @@ -575,12 +632,10 @@ emitDouble(); } else if (tp == DartType.STRING) { emitString(); - } else if (tp == DartType.INT_LIST) { - emitList('[', ']'); - } else if (tp == DartType.INT_SET) { - emitList('{', '}'); - } else if (tp == DartType.INT_STRING_MAP) { - emitMap(); + } else if (tp == DartType.INT_LIST || + tp == DartType.INT_SET || + tp == DartType.INT_STRING_MAP) { + emitCollection(depth, tp); } else { assert(false); } @@ -642,7 +697,7 @@ void emitTerminal(int depth, DartType tp) { switch (rand.nextInt(2)) { case 0: - emitLiteral(tp); + emitLiteral(depth, tp); break; default: emitVar(depth, tp); @@ -694,7 +749,7 @@ emit('('); emitExpr(depth + 1, tp); emitBinaryOp(tp); - emitLiteral(tp); + emitLiteral(depth + 1, tp); emit(')'); return; } @@ -774,8 +829,9 @@ void emitMethodCall(int depth, DartType tp) { // Only call backward to avoid infinite recursion. if (currentClass == null) { - // Outside a class: call backward in global methods. - if (pickedCall(depth, tp, methodName, globalMethods, currentMethod)) { + // Outside a class but inside a method: call backward in global methods. + if (currentMethod != null && + pickedCall(depth, tp, methodName, globalMethods, currentMethod)) { return; } } else { @@ -996,8 +1052,7 @@ List<DartType> fillTypes1() { List<DartType> list = new List<DartType>(); - int n = 1 + rand.nextInt(4); - for (int i = 0; i < n; i++) { + for (int i = 0, n = 1 + rand.nextInt(4); i < n; i++) { list.add(getType()); } return list; @@ -1005,8 +1060,7 @@ List<List<DartType>> fillTypes2() { List<List<DartType>> list = new List<List<DartType>>(); - int n = 1 + rand.nextInt(4); - for (int i = 0; i < n; i++) { + for (int i = 0, n = 1 + rand.nextInt(4); i < n; i++) { list.add(fillTypes1()); } return list;
diff --git a/runtime/tools/dartfuzz/dartfuzz_api_table.dart b/runtime/tools/dartfuzz/dartfuzz_api_table.dart index de5df1c..170f19d 100644 --- a/runtime/tools/dartfuzz/dartfuzz_api_table.dart +++ b/runtime/tools/dartfuzz/dartfuzz_api_table.dart
@@ -50,12 +50,6 @@ DartLib('FileSystemEntity.isFileSync', 'VS'), DartLib('FileSystemEntity.isDirectorySync', 'VS'), DartLib('FileSystemEntity.isWatchSupported', 'Vv'), - DartLib('Platform.isLinux', 'Vv'), - DartLib('Platform.isMacOS', 'Vv'), - DartLib('Platform.isWindows', 'Vv'), - DartLib('Platform.isAndroid', 'Vv'), - DartLib('Platform.isIOS', 'Vv'), - DartLib('Platform.isFuchsia', 'Vv'), DartLib('SecurityContext.alpnSupported', 'Vv'), DartLib('NetworkInterface.listSupported', 'Vv'), ]; @@ -176,7 +170,6 @@ DartLib('FileSystemEvent.MOVE', 'Vv'), DartLib('FileSystemEvent.all', 'Vv'), DartLib('FileSystemEvent.ALL', 'Vv'), - DartLib('Platform.numberOfProcessors', 'Vv'), DartLib('exitCode', 'Vv'), DartLib('pid', 'Vv'), DartLib('ProcessInfo.currentRss', 'Vv'), @@ -798,14 +791,6 @@ DartLib('Uri.encodeFull', 'VS'), DartLib('Uri.decodeFull', 'VS'), DartLib('FileSystemEntity.parentOf', 'VS'), - DartLib('Platform.pathSeparator', 'Vv'), - DartLib('Platform.localeName', 'Vv'), - DartLib('Platform.operatingSystem', 'Vv'), - DartLib('Platform.operatingSystemVersion', 'Vv'), - DartLib('Platform.localHostname', 'Vv'), - DartLib('Platform.packageRoot', 'Vv'), - DartLib('Platform.packageConfig', 'Vv'), - DartLib('Platform.version', 'Vv'), ]; static const listLibs = [ DartLib('List.filled', 'VII'),
diff --git a/runtime/tools/dartfuzz/dartfuzz_test.dart b/runtime/tools/dartfuzz/dartfuzz_test.dart index e90bbae..5bdaadc 100644 --- a/runtime/tools/dartfuzz/dartfuzz_test.dart +++ b/runtime/tools/dartfuzz/dartfuzz_test.dart
@@ -69,7 +69,7 @@ } // Every once in a while, stress test JIT. if (mode.startsWith('jit') && rand.nextInt(4) == 0) { - final r = rand.nextInt(6); + final r = rand.nextInt(7); if (r == 0) { prefix += '-NOFIELDGUARDS'; extraFlags += ['--use_field_guards=false']; @@ -89,7 +89,6 @@ prefix += '-STACKTRACEEVERY'; extraFlags += ['--stacktrace_every=100']; } else if (r == 6) { - // Crashes (https://github.com/dart-lang/sdk/issues/35196): prefix += '-OPTCOUNTER'; extraFlags += ['--optimization_counter_threshold=1']; }
diff --git a/runtime/tools/dartfuzz/gen_api_table.dart b/runtime/tools/dartfuzz/gen_api_table.dart index e02a310..768ba39 100755 --- a/runtime/tools/dartfuzz/gen_api_table.dart +++ b/runtime/tools/dartfuzz/gen_api_table.dart
@@ -127,6 +127,10 @@ } void visitClass(ClassElement classElement) { + // Platform operations cause too many divergences. + if (classElement.name == 'Platform') { + return; + } // Every class element contains elements for the members, viz. `methods` visits // methods, `fields` visits fields, `accessors` visits getters and setters, etc. // There are also accessors to get the superclass, mixins, interfaces, type
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn index a82e940..680ab84 100644 --- a/runtime/vm/BUILD.gn +++ b/runtime/vm/BUILD.gn
@@ -119,6 +119,14 @@ "$root_out_dir/vm_outline" + output_postfix + ".dill", ] args = [ "dart:core" ] + is_product_flag = dart_runtime_mode == "release" + allow_causal_async_stacks = !is_product_flag + args += [ + "-Ddart.vm.product=$is_product_flag", + "-Ddart.developer.causal_async_stacks=$allow_causal_async_stacks", + "-Ddart.isVM=true", + ] + if (defined(invoker.exclude_source) && invoker.exclude_source) { args += [ "--exclude-source" ] }
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc index c3e1db3..10ddc29 100644 --- a/runtime/vm/benchmark_test.cc +++ b/runtime/vm/benchmark_test.cc
@@ -68,7 +68,7 @@ EXPECT(worked); Dart_Handle result = bin::DartUtils::PrepareForScriptLoading(false, false); - DART_CHECK_VALID(result); + EXPECT_VALID(result); // Setup package root. char buffer[2048]; @@ -79,7 +79,7 @@ Utils::SNPrint(buffer, 2048, packages_path, executable_path, path_separator, path_separator); result = bin::DartUtils::SetupPackageRoot(buffer, NULL); - DART_CHECK_VALID(result); + EXPECT_VALID(result); } void Benchmark::RunAll(const char* executable) { @@ -313,7 +313,7 @@ Dart_Handle lib = TestCase::LoadTestScript( kScriptChars, reinterpret_cast<Dart_NativeEntryResolver>(bm_uda_lookup), - USER_TEST_URI, false); + RESOLVED_USER_TEST_URI, false); Dart_Handle result = Dart_FinalizeLoading(false); EXPECT_VALID(result);
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc index f4d63f7..ce2bac2 100644 --- a/runtime/vm/class_finalizer.cc +++ b/runtime/vm/class_finalizer.cc
@@ -1088,19 +1088,6 @@ interface_class.AddDirectImplementor(cls, /* is_mixin = */ i == mixin_index); } - - if (FLAG_use_cha_deopt) { - // Invalidate all CHA code which depends on knowing the implementors of any - // of the interfaces implemented by this new class. - ClassTable* class_table = thread->isolate()->class_table(); - GrowableArray<intptr_t> cids; - InterfaceFinder finder(zone, class_table, &cids); - finder.FindAllInterfaces(cls); - for (intptr_t j = 0; j < cids.length(); ++j) { - interface_class = class_table->At(cids[j]); - interface_class.DisableCHAImplementorUsers(); - } - } } void ClassFinalizer::FinalizeClass(const Class& cls) { @@ -1169,6 +1156,22 @@ RemoveCHAOptimizedCode(cls, cids); } + if (FLAG_use_cha_deopt) { + Zone* zone = thread->zone(); + ClassTable* class_table = thread->isolate()->class_table(); + auto& interface_class = Class::Handle(zone); + + // We scan every interface this [cls] implements and invalidate all CHA code + // which depends on knowing the implementors of that interface. + GrowableArray<intptr_t> cids; + InterfaceFinder finder(zone, class_table, &cids); + finder.FindAllInterfaces(cls); + for (intptr_t j = 0; j < cids.length(); ++j) { + interface_class = class_table->At(cids[j]); + interface_class.DisableCHAImplementorUsers(); + } + } + if (cls.is_enum_class()) { AllocateEnumValues(cls); }
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc index f3f5fd5..70ad37c 100644 --- a/runtime/vm/class_table.cc +++ b/runtime/vm/class_table.cc
@@ -405,20 +405,6 @@ obj->AddProperty("promotedBytes", promoted_size); } -void ClassTable::UpdateAllocatedNew(intptr_t cid, intptr_t size) { - ClassHeapStats* stats = PreliminaryStatsAt(cid); - ASSERT(stats != NULL); - ASSERT(size != 0); - stats->recent.AddNew(size); -} - -void ClassTable::UpdateAllocatedOld(intptr_t cid, intptr_t size) { - ClassHeapStats* stats = PreliminaryStatsAt(cid); - ASSERT(stats != NULL); - ASSERT(size != 0); - stats->recent.AddOld(size); -} - void ClassTable::UpdateAllocatedOldGC(intptr_t cid, intptr_t size) { ClassHeapStats* stats = PreliminaryStatsAt(cid); ASSERT(stats != NULL);
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h index 6a49f54..fd2bdc1 100644 --- a/runtime/vm/class_table.h +++ b/runtime/vm/class_table.h
@@ -261,8 +261,18 @@ #ifndef PRODUCT // Called whenever a class is allocated in the runtime. - void UpdateAllocatedNew(intptr_t cid, intptr_t size); - void UpdateAllocatedOld(intptr_t cid, intptr_t size); + void UpdateAllocatedNew(intptr_t cid, intptr_t size) { + ClassHeapStats* stats = PreliminaryStatsAt(cid); + ASSERT(stats != NULL); + ASSERT(size != 0); + stats->recent.AddNew(size); + } + void UpdateAllocatedOld(intptr_t cid, intptr_t size) { + ClassHeapStats* stats = PreliminaryStatsAt(cid); + ASSERT(stats != NULL); + ASSERT(size != 0); + stats->recent.AddOld(size); + } void UpdateAllocatedOldGC(intptr_t cid, intptr_t size); void UpdateAllocatedExternalNew(intptr_t cid, intptr_t size); void UpdateAllocatedExternalOld(intptr_t cid, intptr_t size);
diff --git a/runtime/vm/compilation_trace.cc b/runtime/vm/compilation_trace.cc index e5f91a0..48db21c 100644 --- a/runtime/vm/compilation_trace.cc +++ b/runtime/vm/compilation_trace.cc
@@ -60,6 +60,13 @@ function_(Function::Handle(zone_)), function2_(Function::Handle(zone_)), field_(Field::Handle(zone_)), + sites_(Array::Handle(zone_)), + site_(ICData::Handle(zone_)), + static_type_(AbstractType::Handle(zone_)), + receiver_cls_(Class::Handle(zone_)), + target_(Function::Handle(zone_)), + selector_(String::Handle(zone_)), + args_desc_(Array::Handle(zone_)), error_(Object::Handle(zone_)) {} static char* FindCharacter(char* str, char goal, char* limit) { @@ -354,14 +361,75 @@ } RawObject* CompilationTraceLoader::CompileFunction(const Function& function) { - if (function.is_abstract()) { + if (function.is_abstract() || function.HasCode()) { return Object::null(); } + // Prevent premature code collection due to major GC during startup. if (function.usage_counter() < Function::kGraceUsageCounter) { function.set_usage_counter(Function::kGraceUsageCounter); } - return Compiler::CompileFunction(thread_, function); + + error_ = Compiler::CompileFunction(thread_, function); + if (error_.IsError()) { + return error_.raw(); + } + + SpeculateInstanceCallTargets(function); + + return error_.raw(); +} + +// For instance calls, if the receiver's static type has one concrete +// implementation, lookup the target for that implementation and add it +// to the ICData's entries. +// For some well-known interfaces, do the same for the most common concrete +// implementation (e.g., int -> _Smi). +void CompilationTraceLoader::SpeculateInstanceCallTargets( + const Function& function) { + sites_ = function.ic_data_array(); + if (sites_.IsNull()) { + return; + } + for (intptr_t i = 1; i < sites_.Length(); i++) { + site_ ^= sites_.At(i); + if (site_.rebind_rule() != ICData::kInstance) { + continue; + } + if (site_.NumArgsTested() != 1) { + continue; + } + + static_type_ = site_.receivers_static_type(); + if (static_type_.IsNull()) { + continue; + } else if (static_type_.IsDoubleType()) { + receiver_cls_ = Isolate::Current()->class_table()->At(kDoubleCid); + } else if (static_type_.IsIntType()) { + receiver_cls_ = Isolate::Current()->class_table()->At(kSmiCid); + } else if (static_type_.IsStringType()) { + receiver_cls_ = Isolate::Current()->class_table()->At(kOneByteStringCid); + } else if (static_type_.IsDartFunctionType() || + static_type_.IsDartClosureType()) { + receiver_cls_ = Isolate::Current()->class_table()->At(kClosureCid); + } else if (static_type_.HasTypeClass()) { + receiver_cls_ = static_type_.type_class(); + if (receiver_cls_.is_implemented() || receiver_cls_.is_abstract()) { + continue; + } + } else { + continue; + } + + selector_ = site_.target_name(); + args_desc_ = site_.arguments_descriptor(); + target_ = Resolver::ResolveDynamicForReceiverClass( + receiver_cls_, selector_, ArgumentsDescriptor(args_desc_)); + if (!target_.IsNull() && !site_.HasReceiverClassId(receiver_cls_.id())) { + intptr_t count = 0; // Don't pollute type feedback and coverage data. + site_.AddReceiverCheck(receiver_cls_.id(), target_, count); + } + } } TypeFeedbackSaver::TypeFeedbackSaver(WriteStream* stream)
diff --git a/runtime/vm/compilation_trace.h b/runtime/vm/compilation_trace.h index 699f08c..e3a8fbd 100644 --- a/runtime/vm/compilation_trace.h +++ b/runtime/vm/compilation_trace.h
@@ -42,6 +42,7 @@ const char* cls_cstr, const char* func_cstr); RawObject* CompileFunction(const Function& function); + void SpeculateInstanceCallTargets(const Function& function); Thread* thread_; Zone* zone_; @@ -54,6 +55,13 @@ Function& function_; Function& function2_; Field& field_; + Array& sites_; + ICData& site_; + AbstractType& static_type_; + Class& receiver_cls_; + Function& target_; + String& selector_; + Array& args_desc_; Object& error_; };
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc index b04473bf..07d879f 100644 --- a/runtime/vm/compiler/aot/aot_call_specializer.cc +++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -767,8 +767,6 @@ // TODO(dartbug.com/30635) Evaluate how much this can be shared with // JitCallSpecializer. void AotCallSpecializer::VisitInstanceCall(InstanceCallInstr* instr) { - ASSERT(FLAG_precompiled_mode); - // Type test is special as it always gets converted into inlined code. const Token::Kind op_kind = instr->token_kind(); if (Token::IsTypeTestOperator(op_kind)) {
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h index 2d224df..cef1ff6 100644 --- a/runtime/vm/compiler/assembler/assembler_arm.h +++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -15,7 +15,7 @@ #include "platform/utils.h" #include "vm/code_entry_kind.h" #include "vm/compiler/runtime_api.h" -#include "vm/constants_arm.h" +#include "vm/constants.h" #include "vm/cpu.h" #include "vm/hash_map.h" #include "vm/simulator.h"
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h index f542eea..de51436 100644 --- a/runtime/vm/compiler/assembler/assembler_arm64.h +++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -14,7 +14,7 @@ #include "platform/assert.h" #include "platform/utils.h" #include "vm/class_id.h" -#include "vm/constants_arm64.h" +#include "vm/constants.h" #include "vm/hash_map.h" #include "vm/simulator.h"
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h index e3e78c2..1ec4248 100644 --- a/runtime/vm/compiler/assembler/assembler_ia32.h +++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -11,7 +11,7 @@ #include "platform/assert.h" #include "platform/utils.h" -#include "vm/constants_ia32.h" +#include "vm/constants.h" #include "vm/constants_x86.h" #include "vm/pointer_tagging.h" @@ -466,7 +466,7 @@ F(sub, 0x2b, 0x29, 5) \ F(sbb, 0x1b, 0x19, 3) \ F(cmp, 0x3b, 0x39, 7) -// clang-format on + // clang-format on #define DECLARE_ALU(op, opcode, opcode2, modrm_opcode) \ void op##l(Register dst, Register src) { Alu(4, opcode, dst, src); } \
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h index 4e073d5..2df4c31 100644 --- a/runtime/vm/compiler/assembler/assembler_x64.h +++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -13,7 +13,7 @@ #include "platform/assert.h" #include "platform/utils.h" -#include "vm/constants_x64.h" +#include "vm/constants.h" #include "vm/constants_x86.h" #include "vm/hash_map.h" #include "vm/pointer_tagging.h"
diff --git a/runtime/vm/compiler/backend/block_builder.h b/runtime/vm/compiler/backend/block_builder.h new file mode 100644 index 0000000..0337556 --- /dev/null +++ b/runtime/vm/compiler/backend/block_builder.h
@@ -0,0 +1,132 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +#ifndef RUNTIME_VM_COMPILER_BACKEND_BLOCK_BUILDER_H_ +#define RUNTIME_VM_COMPILER_BACKEND_BLOCK_BUILDER_H_ + +#include "vm/compiler/backend/flow_graph.h" +#include "vm/compiler/backend/il.h" + +namespace dart { +namespace compiler { + +// Helper class for building basic blocks in SSA form. +class BlockBuilder : public ValueObject { + public: + BlockBuilder(FlowGraph* flow_graph, BlockEntryInstr* entry) + : flow_graph_(flow_graph), + entry_(entry), + current_(entry), + dummy_env_( + new Environment(0, 0, flow_graph->parsed_function(), nullptr)) {} + + Definition* AddToInitialDefinitions(Definition* def) { + def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); + auto normal_entry = flow_graph_->graph_entry()->normal_entry(); + flow_graph_->AddToInitialDefinitions(normal_entry, def); + return def; + } + + Definition* AddDefinition(Definition* def) { + def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); + AddInstruction(def); + return def; + } + + Instruction* AddInstruction(Instruction* instr) { + if (instr->ComputeCanDeoptimize()) { + // All instructions that can deoptimize must have an environment attached + // to them. + instr->SetEnvironment(dummy_env_); + } + current_ = current_->AppendInstruction(instr); + return instr; + } + + void AddReturn(Value* value) { + ReturnInstr* instr = new ReturnInstr( + TokenPos(), value, CompilerState::Current().GetNextDeoptId()); + AddInstruction(instr); + entry_->set_last_instruction(instr); + } + + Definition* AddParameter(intptr_t index, bool with_frame) { + return AddToInitialDefinitions(new ParameterInstr( + index, flow_graph_->graph_entry(), with_frame ? FPREG : SPREG)); + } + + TokenPosition TokenPos() { return flow_graph_->function().token_pos(); } + + Definition* AddNullDefinition() { + return flow_graph_->GetConstant(Object::ZoneHandle()); + } + + Definition* AddUnboxInstr(Representation rep, Value* value, bool is_checked) { + Definition* unboxed_value = + AddDefinition(UnboxInstr::Create(rep, value, DeoptId::kNone)); + if (is_checked) { + // The type of |value| has already been checked and it is safe to + // adjust reaching type. This is done manually because there is no type + // propagation when building intrinsics. + unboxed_value->AsUnbox()->value()->SetReachingType( + new CompileType(CompileType::FromCid(CidForRepresentation(rep)))); + } + return unboxed_value; + } + + Definition* AddUnboxInstr(Representation rep, + Definition* boxed, + bool is_checked) { + return AddUnboxInstr(rep, new Value(boxed), is_checked); + } + + BranchInstr* AddBranch(ComparisonInstr* comp, + TargetEntryInstr* true_successor, + TargetEntryInstr* false_successor) { + auto branch = + new BranchInstr(comp, CompilerState::Current().GetNextDeoptId()); + current_->AppendInstruction(branch); + current_ = nullptr; + + *branch->true_successor_address() = true_successor; + *branch->false_successor_address() = false_successor; + + return branch; + } + + void AddPhi(PhiInstr* phi) { + phi->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); + phi->mark_alive(); + entry_->AsJoinEntry()->InsertPhi(phi); + } + + private: + static intptr_t CidForRepresentation(Representation rep) { + switch (rep) { + case kUnboxedDouble: + return kDoubleCid; + case kUnboxedFloat32x4: + return kFloat32x4Cid; + case kUnboxedInt32x4: + return kInt32x4Cid; + case kUnboxedFloat64x2: + return kFloat64x2Cid; + case kUnboxedUint32: + return kDynamicCid; // smi or mint. + default: + UNREACHABLE(); + return kIllegalCid; + } + } + + FlowGraph* flow_graph_; + BlockEntryInstr* entry_; + Instruction* current_; + Environment* dummy_env_; +}; + +} // namespace compiler +} // namespace dart + +#endif // RUNTIME_VM_COMPILER_BACKEND_BLOCK_BUILDER_H_
diff --git a/runtime/vm/compiler/backend/compile_type.h b/runtime/vm/compiler/backend/compile_type.h index e659dbd..a6f4e93 100644 --- a/runtime/vm/compiler/backend/compile_type.h +++ b/runtime/vm/compiler/backend/compile_type.h
@@ -13,6 +13,7 @@ class AbstractType; class BufferFormatter; +class Definition; // CompileType describes type of a value produced by a definition. // @@ -41,6 +42,7 @@ type_(other.type_) {} CompileType& operator=(const CompileType& other) { + // This intentionally does not change the owner of this type. is_nullable_ = other.is_nullable_; cid_ = other.cid_; type_ = other.type_; @@ -89,7 +91,8 @@ // unreachable values) as None. return None(); } - return CompileType(kNonNullable, kIllegalCid, type_); + + return CompileType(kNonNullable, cid_, type_); } static CompileType CreateNullable(bool is_nullable, intptr_t cid) { @@ -209,14 +212,25 @@ void PrintTo(BufferFormatter* f) const; const char* ToCString() const; + // CompileType object might be unowned or owned by a definition. + // Owned CompileType objects can change during type propagation when + // [RecomputeType] is called on the owner. We keep track of which + // definition owns [CompileType] to prevent situations where + // owned [CompileType] is cached as a reaching type in a [Value] which + // is no longer connected to the original owning definition. + // See [Value::SetReachingType]. + void set_owner(Definition* owner) { owner_ = owner; } + Definition* owner() const { return owner_; } + private: bool CanComputeIsInstanceOf(const AbstractType& type, bool is_nullable, bool* is_instance); bool is_nullable_; - intptr_t cid_; + classid_t cid_; const AbstractType* type_; + Definition* owner_ = nullptr; }; } // namespace dart
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc index f8c33a1..e4e02d5 100644 --- a/runtime/vm/compiler/backend/flow_graph.cc +++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -567,7 +567,7 @@ InsertBefore(call, load_type_args, call->env(), FlowGraph::kValue); const AbstractType& type = - AbstractType::Handle(zone(), call->ic_data()->StaticReceiverType()); + AbstractType::Handle(zone(), call->ic_data()->receivers_static_type()); ASSERT(!type.IsNull()); const TypeArguments& args = TypeArguments::Handle(zone(), type.arguments()); Instruction* guard = new (zone()) CheckConditionInstr( @@ -2136,7 +2136,7 @@ // propagation information (e.g. it might no longer be a _Smi). for (Value::Iterator it(defn->input_use_list()); !it.Done(); it.Advance()) { - it.Current()->SetReachingType(NULL); + it.Current()->SetReachingType(nullptr); } if (defn->IsBinarySmiOp()) {
diff --git a/runtime/vm/compiler/backend/flow_graph.h b/runtime/vm/compiler/backend/flow_graph.h index 0012962..48f4ff0 100644 --- a/runtime/vm/compiler/backend/flow_graph.h +++ b/runtime/vm/compiler/backend/flow_graph.h
@@ -412,6 +412,9 @@ // Adds a 2-way phi. PhiInstr* AddPhi(JoinEntryInstr* join, Definition* d1, Definition* d2); + // SSA transformation methods and fields. + void ComputeDominators(GrowableArray<BitVector*>* dominance_frontier); + private: friend class FlowGraphCompiler; // TODO(ajcbik): restructure friend class FlowGraphChecker; @@ -421,9 +424,6 @@ friend class DeadCodeElimination; friend class compiler::GraphIntrinsifier; - // SSA transformation methods and fields. - void ComputeDominators(GrowableArray<BitVector*>* dominance_frontier); - void CompressPath(intptr_t start_index, intptr_t current_index, GrowableArray<intptr_t>* parent,
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc index 990ae31..54f1e50 100644 --- a/runtime/vm/compiler/backend/flow_graph_compiler.cc +++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -215,7 +215,7 @@ } } - if (!is_optimizing()) { + if (!is_optimizing() && FLAG_reorder_basic_blocks) { // Initialize edge counter array. const intptr_t num_counters = flow_graph_.preorder().length(); const Array& edge_counters = @@ -320,12 +320,12 @@ } intptr_t FlowGraphCompiler::UncheckedEntryOffset() const { - // On ARM64 we cannot use the position of the label bound in the - // FunctionEntryInstr, because `FunctionEntryInstr::EmitNativeCode` does not - // emit the monomorphic entry and frame entry (instead on ARM64 this is done - // in FlowGraphCompiler::CompileGraph()). - // - // See http://dartbug.com/34162 +// On ARM64 we cannot use the position of the label bound in the +// FunctionEntryInstr, because `FunctionEntryInstr::EmitNativeCode` does not +// emit the monomorphic entry and frame entry (instead on ARM64 this is done +// in FlowGraphCompiler::CompileGraph()). +// +// See http://dartbug.com/34162 #if defined(TARGET_ARCH_ARM64) return 0; #endif @@ -344,7 +344,7 @@ return target->Position(); } - // Intrinsification happened. +// Intrinsification happened. #ifdef DART_PRECOMPILER if (parsed_function().function().IsDynamicFunction()) { return Instructions::kMonomorphicEntryOffset; @@ -1259,7 +1259,7 @@ switch (ic_data.NumArgsTested()) { case 1: #if defined(TARGET_ARCH_X64) - if (ic_data.IsTrackingExactness()) { + if (ic_data.is_tracking_exactness()) { if (optimized) { return StubCode::OneArgOptimizedCheckInlineCacheWithExactnessCheck(); } else { @@ -1268,12 +1268,12 @@ } #else // TODO(dartbug.com/34170) Port exactness tracking to other platforms. - ASSERT(!ic_data.IsTrackingExactness()); + ASSERT(!ic_data.is_tracking_exactness()); #endif return optimized ? StubCode::OneArgOptimizedCheckInlineCache() : StubCode::OneArgCheckInlineCache(); case 2: - ASSERT(!ic_data.IsTrackingExactness()); + ASSERT(!ic_data.is_tracking_exactness()); return optimized ? StubCode::TwoArgsOptimizedCheckInlineCache() : StubCode::TwoArgsCheckInlineCache(); default: @@ -1759,7 +1759,7 @@ ASSERT(res->TypeArgsLen() == ArgumentsDescriptor(arguments_descriptor).TypeArgsLen()); ASSERT(!res->is_static_call()); - ASSERT(res->StaticReceiverType() == receiver_type.raw()); + ASSERT(res->receivers_static_type() == receiver_type.raw()); return res; } const ICData& ic_data = ICData::ZoneHandle( @@ -1809,6 +1809,9 @@ threshold = FLAG_reoptimization_counter_threshold; } else if (parsed_function_.function().IsIrregexpFunction()) { threshold = FLAG_regexp_optimization_counter_threshold; + } else if (FLAG_randomize_optimization_counter) { + threshold = Thread::Current()->GetRandomUInt64() % + FLAG_optimization_counter_threshold; } else { const intptr_t basic_blocks = flow_graph().preorder().length(); ASSERT(basic_blocks > 0); @@ -1818,6 +1821,21 @@ threshold = FLAG_optimization_counter_threshold; } } + + // Threshold = 0 doesn't make sense because we increment the counter before + // testing against the threshold. Perhaps we could interpret it to mean + // "generate optimized code immediately without unoptimized compilation + // first", but this isn't supported in our pipeline because there would be no + // code for the optimized code to deoptimize into. + if (threshold == 0) threshold = 1; + + // See Compiler::CanOptimizeFunction. In short, we have to allow the + // unoptimized code to run at least once to prevent an infinite compilation + // loop. + if (threshold == 1 && parsed_function().function().HasBreakpoint()) { + threshold = 2; + } + return threshold; }
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc index 465be1e..6c2c344 100644 --- a/runtime/vm/compiler/backend/il.cc +++ b/runtime/vm/compiler/backend/il.cc
@@ -479,15 +479,7 @@ } #endif // DEBUG -Definition::Definition(intptr_t deopt_id) - : Instruction(deopt_id), - range_(NULL), - type_(NULL), - temp_index_(-1), - ssa_temp_index_(-1), - input_use_list_(NULL), - env_use_list_(NULL), - constant_value_(NULL) {} +Definition::Definition(intptr_t deopt_id) : Instruction(deopt_id) {} // A value in the constant propagation lattice. // - non-constant sentinel @@ -4115,26 +4107,14 @@ const Array& arguments_descriptor = Array::Handle(zone, GetArgumentsDescriptor()); - AbstractType& static_receiver_type = AbstractType::Handle(zone); - -#if defined(TARGET_ARCH_X64) - // Enable static type exactness tracking for the callsite by setting - // static receiver type on the ICData. - if (checked_argument_count() == 1) { - if (static_receiver_type_ != nullptr && - static_receiver_type_->HasTypeClass()) { - const Class& cls = - Class::Handle(zone, static_receiver_type_->type_class()); - if (cls.IsGeneric() && !cls.IsFutureOrClass()) { - static_receiver_type = static_receiver_type_->raw(); - } - } + AbstractType& receivers_static_type = AbstractType::Handle(zone); + if (receivers_static_type_ != nullptr) { + receivers_static_type = receivers_static_type_->raw(); } -#endif call_ic_data = compiler->GetOrAddInstanceCallICData( deopt_id(), function_name(), arguments_descriptor, - checked_argument_count(), static_receiver_type); + checked_argument_count(), receivers_static_type); } else { call_ic_data = &ICData::ZoneHandle(zone, ic_data()->raw()); } @@ -5063,13 +5043,15 @@ intptr_t class_id, AlignmentType alignment, intptr_t deopt_id, - TokenPosition token_pos) + TokenPosition token_pos, + SpeculativeMode speculative_mode) : TemplateInstruction(deopt_id), emit_store_barrier_(emit_store_barrier), index_scale_(index_scale), class_id_(class_id), alignment_(StrengthenAlignment(class_id, alignment)), - token_pos_(token_pos) { + token_pos_(token_pos), + speculative_mode_(speculative_mode) { SetInputAt(kArrayPos, array); SetInputAt(kIndexPos, index); SetInputAt(kValuePos, value);
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h index fa4b7be..3440130 100644 --- a/runtime/vm/compiler/backend/il.h +++ b/runtime/vm/compiler/backend/il.h
@@ -30,6 +30,7 @@ class BufferFormatter; class CallTargets; class CatchBlockEntryInstr; +class CheckBoundBase; class ComparisonInstr; class Definition; class Environment; @@ -117,7 +118,8 @@ CompileType* Type(); - void SetReachingType(CompileType* type) { reaching_type_ = type; } + CompileType* reaching_type() const { return reaching_type_; } + void SetReachingType(CompileType* type); void RefineReachingType(CompileType* type); void PrintTo(BufferFormatter* f) const; @@ -758,6 +760,7 @@ DECLARE_INSTRUCTION_TYPE_CHECK(Definition, Definition) DECLARE_INSTRUCTION_TYPE_CHECK(BlockEntryWithInitialDefs, BlockEntryWithInitialDefs) + DECLARE_INSTRUCTION_TYPE_CHECK(CheckBoundBase, CheckBoundBase) FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) FOR_EACH_ABSTRACT_INSTRUCTION(INSTRUCTION_TYPE_CHECK) @@ -1839,7 +1842,9 @@ // propagation during graph building. CompileType* Type() { if (type_ == NULL) { - type_ = new CompileType(ComputeType()); + auto type = new CompileType(ComputeType()); + type->set_owner(this); + set_type(type); } return type_; } @@ -1865,8 +1870,10 @@ PRINT_TO_SUPPORT bool UpdateType(CompileType new_type) { - if (type_ == NULL) { - type_ = new CompileType(new_type); + if (type_ == nullptr) { + auto type = new CompileType(new_type); + type->set_owner(this); + set_type(type); return true; } @@ -1964,16 +1971,27 @@ friend class RangeAnalysis; friend class Value; - Range* range_; - CompileType* type_; + Range* range_ = nullptr; + + void set_type(CompileType* type) { + ASSERT(type->owner() == this); + type_ = type; + } + +#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER) + const char* TypeAsCString() const { + return HasType() ? type_->ToCString() : ""; + } +#endif private: - intptr_t temp_index_; - intptr_t ssa_temp_index_; - Value* input_use_list_; - Value* env_use_list_; + intptr_t temp_index_ = -1; + intptr_t ssa_temp_index_ = -1; + Value* input_use_list_ = nullptr; + Value* env_use_list_ = nullptr; - Object* constant_value_; + Object* constant_value_ = nullptr; + CompileType* type_ = nullptr; DISALLOW_COPY_AND_ASSIGN(Definition); }; @@ -2111,6 +2129,12 @@ DISALLOW_COPY_AND_ASSIGN(PhiInstr); }; +// This instruction represents an incomming parameter for a function entry, +// or incomming value for OSR entry or incomming value for a catch entry. +// When [base_reg] is set to FPREG [index] corresponds to environment +// variable index (0 is the very first parameter, 1 is next and so on). +// When [base_reg] is set to SPREG [index] corresponds to SP relative parameter +// indices (0 is the very last parameter, 1 is next and so on). class ParameterInstr : public Definition { public: ParameterInstr(intptr_t index, @@ -2220,7 +2244,9 @@ // the frame. This is asserted via `inliner.cc::CalleeGraphValidator`. class LoadIndexedUnsafeInstr : public TemplateDefinition<1, NoThrow> { public: - LoadIndexedUnsafeInstr(Value* index, intptr_t offset) : offset_(offset) { + LoadIndexedUnsafeInstr(Value* index, intptr_t offset, CompileType result_type) + : offset_(offset) { + UpdateType(result_type); SetInputAt(0, index); } @@ -2775,6 +2801,8 @@ virtual bool ComputeCanDeoptimize() const { return false; } virtual bool HasUnknownSideEffects() const { return false; } + PRINT_OPERANDS_TO_SUPPORT + private: CompileType* constrained_type_; DISALLOW_COPY_AND_ASSIGN(RedefinitionInstr); @@ -3299,9 +3327,9 @@ intptr_t checked_argument_count() const { return checked_argument_count_; } const Function& interface_target() const { return interface_target_; } - void set_static_receiver_type(const AbstractType* receiver_type) { - ASSERT(receiver_type != nullptr && receiver_type->IsInstantiated()); - static_receiver_type_ = receiver_type; + void set_receivers_static_type(const AbstractType* receiver_type) { + ASSERT(receiver_type != nullptr); + receivers_static_type_ = receiver_type; } bool has_unique_selector() const { return has_unique_selector_; } @@ -3362,7 +3390,7 @@ bool has_unique_selector_; Code::EntryKind entry_kind_ = Code::EntryKind::kNormal; - const AbstractType* static_receiver_type_ = nullptr; + const AbstractType* receivers_static_type_ = nullptr; DISALLOW_COPY_AND_ASSIGN(InstanceCallInstr); }; @@ -4695,7 +4723,8 @@ intptr_t class_id, AlignmentType alignment, intptr_t deopt_id, - TokenPosition token_pos); + TokenPosition token_pos, + SpeculativeMode speculative_mode = kGuardInputs); DECLARE_INSTRUCTION(StoreIndexed) enum { kArrayPos = 0, kIndexPos = 1, kValuePos = 2 }; @@ -4719,6 +4748,8 @@ (emit_store_barrier_ == kEmitStoreBarrier); } + virtual SpeculativeMode speculative_mode() const { return speculative_mode_; } + virtual bool ComputeCanDeoptimize() const { return false; } virtual Representation RequiredInputRepresentation(intptr_t idx) const; @@ -4745,6 +4776,7 @@ const intptr_t class_id_; const AlignmentType alignment_; const TokenPosition token_pos_; + const SpeculativeMode speculative_mode_; DISALLOW_COPY_AND_ASSIGN(StoreIndexedInstr); }; @@ -6247,6 +6279,7 @@ virtual bool ComputeCanDeoptimize() const { return false; } virtual CompileType ComputeType() const; + virtual bool RecomputeType(); virtual bool HasUnknownSideEffects() const { return true; } @@ -6994,8 +7027,10 @@ class DoubleToFloatInstr : public TemplateDefinition<1, NoThrow, Pure> { public: - DoubleToFloatInstr(Value* value, intptr_t deopt_id) - : TemplateDefinition(deopt_id) { + DoubleToFloatInstr(Value* value, + intptr_t deopt_id, + SpeculativeMode speculative_mode = kGuardInputs) + : TemplateDefinition(deopt_id), speculative_mode_(speculative_mode) { SetInputAt(0, value); } @@ -7020,6 +7055,8 @@ return kUnboxedDouble; } + virtual SpeculativeMode speculative_mode() const { return speculative_mode_; } + virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); } virtual bool AttributesEqual(Instruction* other) const { return true; } @@ -7027,6 +7064,8 @@ virtual Definition* Canonicalize(FlowGraph* flow_graph); private: + const SpeculativeMode speculative_mode_; + DISALLOW_COPY_AND_ASSIGN(DoubleToFloatInstr); }; @@ -7380,17 +7419,12 @@ DISALLOW_COPY_AND_ASSIGN(CheckClassIdInstr); }; -// Performs an array bounds check, where -// safe_index := CheckArrayBound(length, index) -// returns the "safe" index when -// 0 <= index < length -// or otherwise deoptimizes (viz. speculative). -class CheckArrayBoundInstr : public TemplateDefinition<2, NoThrow, Pure> { +// Base class for speculative [CheckArrayBoundInstr] and +// [GenericCheckBoundInstr] +class CheckBoundBase : public TemplateDefinition<2, NoThrow, Pure> { public: - CheckArrayBoundInstr(Value* length, Value* index, intptr_t deopt_id) - : TemplateDefinition(deopt_id), - generalized_(false), - licm_hoisted_(false) { + CheckBoundBase(Value* length, Value* index, intptr_t deopt_id) + : TemplateDefinition(deopt_id) { SetInputAt(kLengthPos, length); SetInputAt(kIndexPos, index); } @@ -7398,6 +7432,28 @@ Value* length() const { return inputs_[kLengthPos]; } Value* index() const { return inputs_[kIndexPos]; } + virtual bool IsCheckBoundBase() { return true; } + virtual CheckBoundBase* AsCheckBoundBase() { return this; } + + // Give a name to the location/input indices. + enum { kLengthPos = 0, kIndexPos = 1 }; + + private: + DISALLOW_COPY_AND_ASSIGN(CheckBoundBase); +}; + +// Performs an array bounds check, where +// safe_index := CheckArrayBound(length, index) +// returns the "safe" index when +// 0 <= index < length +// or otherwise deoptimizes (viz. speculative). +class CheckArrayBoundInstr : public CheckBoundBase { + public: + CheckArrayBoundInstr(Value* length, Value* index, intptr_t deopt_id) + : CheckBoundBase(length, index, deopt_id), + generalized_(false), + licm_hoisted_(false) {} + DECLARE_INSTRUCTION(CheckArrayBound) virtual CompileType ComputeType() const; @@ -7420,9 +7476,6 @@ void set_licm_hoisted(bool value) { licm_hoisted_ = value; } - // Give a name to the location/input indices. - enum { kLengthPos = 0, kIndexPos = 1 }; - private: bool generalized_; bool licm_hoisted_; @@ -7431,20 +7484,14 @@ }; // Performs an array bounds check, where -// safe_index := CheckArrayBound(length, index) +// safe_index := GenericCheckBound(length, index) // returns the "safe" index when // 0 <= index < length // or otherwise throws an out-of-bounds exception (viz. non-speculative). -class GenericCheckBoundInstr : public TemplateDefinition<2, Throws, Pure> { +class GenericCheckBoundInstr : public CheckBoundBase { public: GenericCheckBoundInstr(Value* length, Value* index, intptr_t deopt_id) - : TemplateDefinition(deopt_id) { - SetInputAt(kLengthPos, length); - SetInputAt(kIndexPos, index); - } - - Value* length() const { return inputs_[kLengthPos]; } - Value* index() const { return inputs_[kIndexPos]; } + : CheckBoundBase(length, index, deopt_id) {} virtual bool AttributesEqual(Instruction* other) const { return true; } @@ -7459,9 +7506,6 @@ bool IsRedundant(const RangeBoundary& length); - // Give a name to the location/input indices. - enum { kLengthPos = 0, kIndexPos = 1 }; - private: DISALLOW_COPY_AND_ASSIGN(GenericCheckBoundInstr); };
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc index 942c9e8..dd332867 100644 --- a/runtime/vm/compiler/backend/il_arm.cc +++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -1856,10 +1856,7 @@ __ strh(IP, field_nullability_operand); } - if (deopt == NULL) { - ASSERT(!compiler->is_optimizing()); - __ b(&ok); - } + __ b(&ok); } if (deopt == NULL) { @@ -1874,6 +1871,8 @@ __ Push(value_reg); __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); __ Drop(2); // Drop the field and the value. + } else { + __ b(fail); } } else { ASSERT(compiler->is_optimizing());
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc index c5a2cf0..67e080b 100644 --- a/runtime/vm/compiler/backend/il_arm64.cc +++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -1779,10 +1779,7 @@ __ str(TMP, field_nullability_operand, kUnsignedHalfword); } - if (deopt == NULL) { - ASSERT(!compiler->is_optimizing()); - __ b(&ok); - } + __ b(&ok); } if (deopt == NULL) { @@ -1798,6 +1795,8 @@ __ Push(value_reg); __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); __ Drop(2); // Drop the field and the value. + } else { + __ b(fail); } } else { ASSERT(compiler->is_optimizing());
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc index 71dedf6..19983a1 100644 --- a/runtime/vm/compiler/backend/il_ia32.cc +++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -1682,10 +1682,7 @@ __ movw(field_nullability_operand, Immediate(value_cid)); } - if (deopt == NULL) { - ASSERT(!compiler->is_optimizing()); - __ jmp(&ok); - } + __ jmp(&ok); } if (deopt == NULL) { @@ -1700,6 +1697,8 @@ __ pushl(value_reg); __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); __ Drop(2); // Drop the field and the value. + } else { + __ jmp(fail); } } else { ASSERT(compiler->is_optimizing());
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc index b735a6f..85d77dc 100644 --- a/runtime/vm/compiler/backend/il_printer.cc +++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -155,12 +155,15 @@ void CompileType::PrintTo(BufferFormatter* f) const { const char* type_name = "?"; - if ((cid_ != kIllegalCid) && (cid_ != kDynamicCid)) { + if (IsNone()) { + f->Print("T{}"); + return; + } else if ((cid_ != kIllegalCid) && (cid_ != kDynamicCid)) { const Class& cls = Class::Handle(Isolate::Current()->class_table()->At(cid_)); type_name = String::Handle(cls.ScrubbedName()).ToCString(); - } else if (type_ != NULL && !type_->IsDynamicType()) { - type_name = TypeToUserVisibleName(*type_); + } else if (type_ != NULL) { + type_name = type_->IsDynamicType() ? "*" : TypeToUserVisibleName(*type_); } else if (!is_nullable()) { type_name = "!null"; } @@ -249,9 +252,9 @@ const ICData& ic_data, intptr_t num_checks_to_print) { f->Print(" IC["); - if (ic_data.IsTrackingExactness()) { + if (ic_data.is_tracking_exactness()) { f->Print("(%s) ", - AbstractType::Handle(ic_data.StaticReceiverType()).ToCString()); + AbstractType::Handle(ic_data.receivers_static_type()).ToCString()); } f->Print("%" Pd ": ", ic_data.NumberOfChecks()); Function& target = Function::Handle(); @@ -275,7 +278,7 @@ f->Print("%s", String::Handle(cls.Name()).ToCString()); } f->Print(" cnt:%" Pd " trgt:'%s'", count, target.ToQualifiedCString()); - if (ic_data.IsTrackingExactness()) { + if (ic_data.is_tracking_exactness()) { f->Print(" %s", ic_data.GetExactnessAt(i).ToCString()); } } @@ -388,6 +391,13 @@ } } +void RedefinitionInstr::PrintOperandsTo(BufferFormatter* f) const { + Definition::PrintOperandsTo(f); + if (constrained_type_ != nullptr) { + f->Print(" ^ %s", constrained_type_->ToCString()); + } +} + void Value::PrintTo(BufferFormatter* f) const { PrintUse(f, *definition()); @@ -972,9 +982,8 @@ f->Print(" %s", RepresentationToCString(representation())); } - if (type_ != NULL) { - f->Print(" "); - type_->PrintTo(f); + if (HasType()) { + f->Print(" %s", TypeAsCString()); } }
diff --git a/runtime/vm/compiler/backend/il_test_helper.cc b/runtime/vm/compiler/backend/il_test_helper.cc new file mode 100644 index 0000000..4315c29 --- /dev/null +++ b/runtime/vm/compiler/backend/il_test_helper.cc
@@ -0,0 +1,328 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +#include "vm/compiler/backend/il_test_helper.h" + +#include "vm/compiler/aot/aot_call_specializer.h" +#include "vm/compiler/backend/block_scheduler.h" +#include "vm/compiler/backend/flow_graph.h" +#include "vm/compiler/backend/flow_graph_compiler.h" +#include "vm/compiler/backend/il.h" +#include "vm/compiler/backend/il_printer.h" +#include "vm/compiler/backend/inliner.h" +#include "vm/compiler/call_specializer.h" +#include "vm/compiler/compiler_pass.h" +#include "vm/compiler/jit/compiler.h" +#include "vm/compiler/jit/jit_call_specializer.h" +#include "vm/dart_api_impl.h" +#include "vm/parser.h" +#include "vm/unit_test.h" + +namespace dart { + +RawLibrary* LoadTestScript(const char* script, + Dart_NativeEntryResolver resolver, + const char* lib_uri) { + Dart_Handle api_lib; + { + TransitionVMToNative transition(Thread::Current()); + api_lib = TestCase::LoadTestScript(script, resolver, lib_uri); + } + auto& lib = Library::Handle(); + lib ^= Api::UnwrapHandle(api_lib); + EXPECT(!lib.IsNull()); + return lib.raw(); +} + +RawFunction* GetFunction(const Library& lib, const char* name) { + Thread* thread = Thread::Current(); + const auto& func = Function::Handle(lib.LookupFunctionAllowPrivate( + String::Handle(Symbols::New(thread, name)))); + EXPECT(!func.IsNull()); + return func.raw(); +} + +void Invoke(const Library& lib, const char* name) { + Thread* thread = Thread::Current(); + Dart_Handle api_lib = Api::NewHandle(thread, lib.raw()); + TransitionVMToNative transition(thread); + Dart_Handle result = + Dart_Invoke(api_lib, NewString(name), /*argc=*/0, /*argv=*/nullptr); + EXPECT_VALID(result); +} + +FlowGraph* TestPipeline::RunPasses( + std::initializer_list<CompilerPass::Id> passes) { + auto thread = Thread::Current(); + auto zone = thread->zone(); + const bool optimized = true; + const intptr_t osr_id = Compiler::kNoOSRDeoptId; + + auto pipeline = CompilationPipeline::New(zone, function_); + + parsed_function_ = new (zone) + ParsedFunction(thread, Function::ZoneHandle(zone, function_.raw())); + pipeline->ParseFunction(parsed_function_); + + // Extract type feedback before the graph is built, as the graph + // builder uses it to attach it to nodes. + ic_data_array_ = new (zone) ZoneGrowableArray<const ICData*>(); + if (mode_ == CompilerPass::kJIT) { + function_.RestoreICDataMap(ic_data_array_, /*clone_ic_data=*/false); + } + + flow_graph_ = pipeline->BuildFlowGraph(zone, parsed_function_, ic_data_array_, + osr_id, optimized); + + if (mode_ == CompilerPass::kAOT) { + flow_graph_->PopulateWithICData(function_); + } + + BlockScheduler block_scheduler(flow_graph_); + const bool reorder_blocks = + FlowGraph::ShouldReorderBlocks(function_, optimized); + if (mode_ == CompilerPass::kJIT && reorder_blocks) { + block_scheduler.AssignEdgeWeights(); + } + + SpeculativeInliningPolicy speculative_policy(/*enable_blacklist=*/false); + pass_state_ = new CompilerPassState(thread, flow_graph_, &speculative_policy); + pass_state_->block_scheduler = &block_scheduler; + pass_state_->reorder_blocks = reorder_blocks; + + if (optimized) { + pass_state_->inline_id_to_function.Add(&function_); + // We do not add the token position now because we don't know the + // position of the inlined call until later. A side effect of this + // is that the length of |inline_id_to_function| is always larger + // than the length of |inline_id_to_token_pos| by one. + // Top scope function has no caller (-1). We do this because we expect + // all token positions to be at an inlined call. + pass_state_->caller_inline_id.Add(-1); + + JitCallSpecializer jit_call_specializer(flow_graph_, &speculative_policy); + AotCallSpecializer aot_call_specializer(/*precompiler=*/nullptr, + flow_graph_, &speculative_policy); + if (mode_ == CompilerPass::kAOT) { + pass_state_->call_specializer = &aot_call_specializer; + } else { + pass_state_->call_specializer = &jit_call_specializer; + } + + if (passes.size() > 0) { + CompilerPass::RunPipelineWithPasses(pass_state_, passes); + } else { + CompilerPass::RunPipeline(mode_, pass_state_); + } + } + + return flow_graph_; +} + +void TestPipeline::CompileGraphAndAttachFunction() { + Zone* zone = thread_->zone(); + const bool optimized = true; + + SpeculativeInliningPolicy speculative_policy(/*enable_blacklist=*/false); + +#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_IA32) || \ + defined(TARGET_ARCH_DBC) + const bool use_far_branches = false; +#else + const bool use_far_branches = true; +#endif + + ASSERT(pass_state_->inline_id_to_function.length() == + pass_state_->caller_inline_id.length()); + ObjectPoolBuilder object_pool_builder; + Assembler assembler(&object_pool_builder, use_far_branches); + FlowGraphCompiler graph_compiler( + &assembler, flow_graph_, *parsed_function_, optimized, + &speculative_policy, pass_state_->inline_id_to_function, + pass_state_->inline_id_to_token_pos, pass_state_->caller_inline_id, + ic_data_array_); + + graph_compiler.CompileGraph(); + + const auto& deopt_info_array = + Array::Handle(zone, graph_compiler.CreateDeoptInfo(&assembler)); + const auto pool_attachment = Code::PoolAttachment::kAttachPool; + const auto& code = Code::Handle(Code::FinalizeCode( + &graph_compiler, &assembler, pool_attachment, optimized, nullptr)); + code.set_is_optimized(optimized); + code.set_owner(function_); + + graph_compiler.FinalizePcDescriptors(code); + code.set_deopt_info_array(deopt_info_array); + + graph_compiler.FinalizeStackMaps(code); + graph_compiler.FinalizeVarDescriptors(code); + graph_compiler.FinalizeExceptionHandlers(code); + graph_compiler.FinalizeCatchEntryMovesMap(code); + graph_compiler.FinalizeStaticCallTargetsTable(code); + graph_compiler.FinalizeCodeSourceMap(code); + + if (optimized) { + function_.InstallOptimizedCode(code); + } else { + function_.set_unoptimized_code(code); + function_.AttachCode(code); + } + + // We expect there to be no deoptimizations. + if (mode_ == CompilerPass::kAOT) { + // TODO(kustermann): Enable this once we get rid of [CheckedSmiSlowPath]s. + // EXPECT(deopt_info_array.IsNull() || deopt_info_array.Length() == 0); + } +} + +bool ILMatcher::TryMatch(std::initializer_list<MatchCode> match_codes) { + std::vector<MatchCode> qcodes = match_codes; + + if (trace_) { + OS::PrintErr("ILMatcher: Matching the following graph\n"); + FlowGraphPrinter::PrintGraph("ILMatcher", flow_graph_); + OS::PrintErr("ILMatcher: Starting match at %s:\n", cursor_->ToCString()); + } + + Instruction* cursor = cursor_; + for (size_t i = 0; i < qcodes.size(); ++i) { + Instruction** capture = qcodes[i].capture_; + if (trace_) { + OS::PrintErr(" matching %30s @ %s\n", + MatchOpCodeToCString(qcodes[i].opcode()), + cursor->ToCString()); + } + + auto next = MatchInternal(qcodes, i, cursor); + if (next == nullptr) { + if (trace_) { + OS::PrintErr(" -> Match failed\n"); + } + cursor = next; + break; + } + if (capture != nullptr) { + *capture = cursor; + } + cursor = next; + } + if (cursor != nullptr) { + cursor_ = cursor; + return true; + } + return false; +} + +Instruction* ILMatcher::MatchInternal(std::vector<MatchCode> match_codes, + size_t i, + Instruction* cursor) { + const MatchOpCode opcode = match_codes[i].opcode(); + if (opcode == kMatchAndMoveBranchTrue) { + auto branch = cursor->AsBranch(); + if (branch == nullptr) return nullptr; + return branch->true_successor(); + } + if (opcode == kMatchAndMoveBranchFalse) { + auto branch = cursor->AsBranch(); + if (branch == nullptr) return nullptr; + return branch->false_successor(); + } + if (opcode == kMoveAny) { + return cursor->next(); + } + if (opcode == kMoveParallelMoves) { + while (cursor != nullptr && cursor->IsParallelMove()) { + cursor = cursor->next(); + } + return cursor; + } + + if (opcode == kMoveGlob) { + ASSERT((i + 1) < match_codes.size()); + while (true) { + if (cursor == nullptr) return nullptr; + if (MatchInternal(match_codes, i + 1, cursor) != nullptr) { + return cursor; + } + if (auto as_goto = cursor->AsGoto()) { + cursor = as_goto->successor(); + } else { + cursor = cursor->next(); + } + } + } + + if (opcode == kMatchAndMoveGoto) { + if (auto goto_instr = cursor->AsGoto()) { + return goto_instr->successor(); + } + } + + switch (opcode) { +#define EMIT_CASE(Instruction, _) \ + case kMatch##Instruction: { \ + if (cursor->Is##Instruction()) { \ + return cursor; \ + } \ + return nullptr; \ + } \ + case kMatchAndMove##Instruction: { \ + if (cursor->Is##Instruction()) { \ + return cursor->next(); \ + } \ + return nullptr; \ + } \ + case kMatchAndMoveOptional##Instruction: { \ + if (cursor->Is##Instruction()) { \ + return cursor->next(); \ + } \ + return cursor; \ + } + FOR_EACH_INSTRUCTION(EMIT_CASE) +#undef EMIT_CASE + default: + UNREACHABLE(); + } + + UNREACHABLE(); + return nullptr; +} + +const char* ILMatcher::MatchOpCodeToCString(MatchOpCode opcode) { + if (opcode == kMatchAndMoveBranchTrue) { + return "kMatchAndMoveBranchTrue"; + } + if (opcode == kMatchAndMoveBranchFalse) { + return "kMatchAndMoveBranchFalse"; + } + if (opcode == kMoveAny) { + return "kMoveAny"; + } + if (opcode == kMoveParallelMoves) { + return "kMoveParallelMoves"; + } + if (opcode == kMoveGlob) { + return "kMoveGlob"; + } + + switch (opcode) { +#define EMIT_CASE(Instruction, _) \ + case kMatch##Instruction: \ + return "kMatch" #Instruction; \ + case kMatchAndMove##Instruction: \ + return "kMatchAndMove" #Instruction; \ + case kMatchAndMoveOptional##Instruction: \ + return "kMatchAndMoveOptional" #Instruction; + FOR_EACH_INSTRUCTION(EMIT_CASE) +#undef EMIT_CASE + default: + UNREACHABLE(); + } + + UNREACHABLE(); + return nullptr; +} + +} // namespace dart
diff --git a/runtime/vm/compiler/backend/il_test_helper.h b/runtime/vm/compiler/backend/il_test_helper.h new file mode 100644 index 0000000..84d7acf --- /dev/null +++ b/runtime/vm/compiler/backend/il_test_helper.h
@@ -0,0 +1,195 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +#ifndef RUNTIME_VM_COMPILER_BACKEND_IL_TEST_HELPER_H_ +#define RUNTIME_VM_COMPILER_BACKEND_IL_TEST_HELPER_H_ + +#include <vector> + +#include "include/dart_api.h" + +#include "platform/allocation.h" +#include "vm/compiler/backend/il.h" +#include "vm/compiler/compiler_pass.h" +#include "vm/compiler/compiler_state.h" +#include "vm/unit_test.h" + +// The helpers in this file make it easier to write C++ unit tests which assert +// that Dart code gets turned into certain IR. +// +// Here is an example on how to use it: +// +// ISOLATE_UNIT_TEST_CASE(MyIRTest) { +// const char* script = R"( +// void foo() { ... } +// void main() { foo(); } +// )"; +// +// // Load the script and exercise the code once. +// const auto& lib = Library::Handle(LoadTestScript(script); +// +// // Cause the code to be exercised once (to populate ICData). +// Invoke(lib, "main"); +// +// // Look up the function. +// const auto& function = Function::Handle(GetFunction(lib, "foo")); +// +// // Run the JIT compilation pipeline with two passes. +// TestPipeline pipeline(function); +// FlowGraph* graph = pipeline.RunJITPasses("ComputeSSA,TypePropagation"); +// +// ... +// } +// +namespace dart { + +class FlowGraph; +class Function; +class Library; +class RawFunction; +class RawLibrary; + +RawLibrary* LoadTestScript(const char* script, + Dart_NativeEntryResolver resolver = nullptr, + const char* lib_uri = RESOLVED_USER_TEST_URI); + +RawFunction* GetFunction(const Library& lib, const char* name); + +void Invoke(const Library& lib, const char* name); + +class TestPipeline : public ValueObject { + public: + explicit TestPipeline(const Function& function, + CompilerPass::PipelineMode mode) + : function_(function), + thread_(Thread::Current()), + compiler_state_(thread_), + mode_(mode) {} + ~TestPipeline() { delete pass_state_; } + + // As a side-effect this will populate + // - [ic_data_array_] + // - [parsed_function_] + // - [pass_state_] + // - [flow_graph_] + FlowGraph* RunPasses(std::initializer_list<CompilerPass::Id> passes); + + void CompileGraphAndAttachFunction(); + + private: + const Function& function_; + Thread* thread_; + CompilerState compiler_state_; + CompilerPass::PipelineMode mode_; + ZoneGrowableArray<const ICData*>* ic_data_array_ = nullptr; + ParsedFunction* parsed_function_ = nullptr; + CompilerPassState* pass_state_ = nullptr; + FlowGraph* flow_graph_ = nullptr; +}; + +// Match opcodes used for [ILMatcher], see below. +enum MatchOpCode { +// Emit a match and match-and-move code for every instruction. +#define DEFINE_MATCH_OPCODES(Instruction, _) \ + kMatch##Instruction, kMatchAndMove##Instruction, \ + kMatchAndMoveOptional##Instruction, + FOR_EACH_INSTRUCTION(DEFINE_MATCH_OPCODES) +#undef DEFINE_MATCH_OPCODES + + // Matches a branch and moves left. + kMatchAndMoveBranchTrue, + + // Matches a branch and moves right. + kMatchAndMoveBranchFalse, + + // Moves forward across any instruction. + kMoveAny, + + // Moves over all parallel moves. + kMoveParallelMoves, + + // Moves forward until the next match code matches. + kMoveGlob, +}; + +// Match codes used for [ILMatcher], see below. +class MatchCode { + public: + MatchCode(MatchOpCode opcode) // NOLINT + : opcode_(opcode), capture_(nullptr) {} + + MatchCode(MatchOpCode opcode, Instruction** capture) + : opcode_(opcode), capture_(capture) {} + +#define DEFINE_TYPED_CONSTRUCTOR(Type, ignored) \ + MatchCode(MatchOpCode opcode, Type##Instr** capture) \ + : opcode_(opcode), capture_(reinterpret_cast<Instruction**>(capture)) { \ + RELEASE_ASSERT(opcode == kMatch##Type || opcode == kMatchAndMove##Type); \ + } + FOR_EACH_INSTRUCTION(DEFINE_TYPED_CONSTRUCTOR) +#undef DEFINE_TYPED_CONSTRUCTOR + + MatchOpCode opcode() { return opcode_; } + + private: + friend class ILMatcher; + + MatchOpCode opcode_; + Instruction** capture_; +}; + +// Used for matching a sequence of IL instructions including capturing support. +// +// Example: +// +// TargetEntryInstr* entry = ....; +// BranchInstr* branch = nullptr; +// +// ILMatcher matcher(flow_graph, entry); +// if (matcher.TryMatch({ kMoveGlob, {kMatchBranch, &branch}, })) { +// EXPECT(branch->operation_cid() == kMintCid); +// ... +// } +// +// This match will start at [entry], follow any number instructions (including +// [GotoInstr]s until a [BranchInstr] is found). +// +// If the match was successful, this returns `true` and updates the current +// value for the cursor. +class ILMatcher : public ValueObject { + public: + ILMatcher(FlowGraph* flow_graph, Instruction* cursor, bool trace = true) + : flow_graph_(flow_graph), + cursor_(cursor), + // clang-format off +#if !defined(PRODUCT) + trace_(trace) {} +#else + trace_(false) {} +#endif + // clang-format on + + Instruction* value() { return cursor_; } + + // From the current [value] according to match_codes. + // + // Returns `true` if the match was successful and cursor has been updated, + // otherwise returns `false`. + bool TryMatch(std::initializer_list<MatchCode> match_codes); + + private: + Instruction* MatchInternal(std::vector<MatchCode> match_codes, + size_t i, + Instruction* cursor); + + const char* MatchOpCodeToCString(MatchOpCode code); + + FlowGraph* flow_graph_; + Instruction* cursor_; + bool trace_; +}; + +} // namespace dart + +#endif // RUNTIME_VM_COMPILER_BACKEND_IL_TEST_HELPER_H_
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc index 16569e8..6947e3c 100644 --- a/runtime/vm/compiler/backend/il_x64.cc +++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -1768,10 +1768,7 @@ __ movw(field_nullability_operand, Immediate(value_cid)); } - if (deopt == NULL) { - ASSERT(!compiler->is_optimizing()); - __ jmp(&ok); - } + __ jmp(&ok); } if (deopt == NULL) { @@ -1786,6 +1783,8 @@ __ pushq(value_reg); __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); __ Drop(2); // Drop the field and the value. + } else { + __ jmp(fail); } } else { ASSERT(compiler->is_optimizing());
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc index b53f252..8d34ae8 100644 --- a/runtime/vm/compiler/backend/inliner.cc +++ b/runtime/vm/compiler/backend/inliner.cc
@@ -1069,15 +1069,14 @@ if (FLAG_precompiled_mode) { callee_graph->PopulateWithICData(parsed_function->function()); } -#else +#endif + // If we inline a function which is intrinsified without a fall-through // to IR code, we will not have any ICData attached, so we do it // manually here. - if (function.is_intrinsic()) { + if (!FLAG_precompiled_mode && function.is_intrinsic()) { callee_graph->PopulateWithICData(parsed_function->function()); } -#endif // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) && \ - // !defined(TARGET_ARCH_IA32) // The parameter stubs are a copy of the actual arguments providing // concrete information about the values, for example constant values, @@ -2858,59 +2857,25 @@ // Emits preparatory code for a typed getter/setter. // Handles three cases: -// (1) dynamic: generates a conditional on the receiver cid -// that handles external (load untagged) and -// internal storage at runtime. -// (2) external: generates load untagged. +// (1) dynamic: generates load untagged (internal or external) +// (2) external: generates load untagged // (3) internal: no code required. static void PrepareInlineByteArrayBaseOp(FlowGraph* flow_graph, Instruction* call, Definition* receiver, intptr_t array_cid, Definition** array, - Instruction** cursor, - TargetEntryInstr** block_external, - TargetEntryInstr** block_internal) { - if (array_cid == kDynamicCid) { - // Dynamic case: runtime resolution between external/internal typed data. - // cid = LoadCid - // if cid in [ kExternalTypedDataInt8ArrayCid, - // kExternalTypedDataFloat64x2ArrayCid ] - // block_external: LoadUntagged - // .. - // else - // block_internal: .. - // - // TODO(ajcbik): as suggested above, subtract + single unsigned test. - // - LoadClassIdInstr* load_cid = - new (Z) LoadClassIdInstr(new (Z) Value(receiver)); - *cursor = flow_graph->AppendTo(*cursor, load_cid, NULL, FlowGraph::kValue); - ConstantInstr* cid_lo = flow_graph->GetConstant( - Smi::ZoneHandle(Smi::New(kExternalTypedDataInt8ArrayCid))); - RelationalOpInstr* le_lo = new (Z) - RelationalOpInstr(call->token_pos(), Token::kLTE, new (Z) Value(cid_lo), - new (Z) Value(load_cid), kSmiCid, call->deopt_id()); - ConstantInstr* cid_hi = flow_graph->GetConstant( - Smi::ZoneHandle(Smi::New(kExternalTypedDataFloat64x2ArrayCid))); - RelationalOpInstr* le_hi = new (Z) RelationalOpInstr( - call->token_pos(), Token::kLTE, new (Z) Value(load_cid), - new (Z) Value(cid_hi), kSmiCid, call->deopt_id()); - *cursor = flow_graph->NewDiamond(*cursor, call, - FlowGraph::LogicalAnd(le_lo, le_hi), - block_external, block_internal); - LoadUntaggedInstr* elements = new (Z) LoadUntaggedInstr( - new (Z) Value(*array), ExternalTypedData::data_offset()); - flow_graph->InsertAfter(*block_external, elements, NULL, FlowGraph::kValue); - *array = elements; // return load untagged definition in array - } else if (RawObject::IsExternalTypedDataClassId(array_cid)) { - // External typed data: load untagged. - LoadUntaggedInstr* elements = new (Z) LoadUntaggedInstr( - new (Z) Value(*array), ExternalTypedData::data_offset()); + Instruction** cursor) { + if (array_cid == kDynamicCid || + RawObject::IsExternalTypedDataClassId(array_cid)) { + // Internal or External typed data: load untagged. + auto elements = new (Z) LoadUntaggedInstr( + new (Z) Value(*array), TypedDataBase::data_field_offset()); *cursor = flow_graph->AppendTo(*cursor, elements, NULL, FlowGraph::kValue); *array = elements; } else { // Internal typed data: no action. + ASSERT(RawObject::IsTypedDataClassId(array_cid)); } } @@ -2968,33 +2933,11 @@ // Generates a template for the load, either a dynamic conditional // that dispatches on external and internal storage, or a single // case that deals with either external or internal storage. - TargetEntryInstr* block_external = nullptr; - TargetEntryInstr* block_internal = nullptr; PrepareInlineByteArrayBaseOp(flow_graph, call, receiver, array_cid, &array, - &cursor, &block_external, &block_internal); + &cursor); // Fill out the generated template with loads. - if (array_cid == kDynamicCid) { - ASSERT(block_external != nullptr && block_internal != nullptr); - // Load from external in block_external and internal in block_internal - // (resolves (B)). The former loads from "array", which is the returned - // load untagged definition. The latter loads from the original "receiver". - LoadIndexedInstr* load1 = NewLoad(flow_graph, call, array, index, view_cid); - ASSERT(block_external->next() == array); - flow_graph->InsertAfter( - block_external->next(), load1, - call->deopt_id() != DeoptId::kNone ? call->env() : nullptr, - FlowGraph::kValue); - LoadIndexedInstr* load2 = - NewLoad(flow_graph, call, receiver, index, view_cid); - flow_graph->InsertAfter( - block_internal, load2, - call->deopt_id() != DeoptId::kNone ? call->env() : nullptr, - FlowGraph::kValue); - // Construct phi of external and internal load. - *last = flow_graph->AddPhi(cursor->AsJoinEntry(), load1, load2); - } else { - ASSERT(block_external == nullptr && block_internal == nullptr); + { // Load from either external or internal. LoadIndexedInstr* load = NewLoad(flow_graph, call, array, index, view_cid); flow_graph->AppendTo( @@ -3184,31 +3127,11 @@ // Generates a template for the store, either a dynamic conditional // that dispatches on external and internal storage, or a single // case that deals with either external or internal storage. - TargetEntryInstr* block_external = nullptr; - TargetEntryInstr* block_internal = nullptr; PrepareInlineByteArrayBaseOp(flow_graph, call, receiver, array_cid, &array, - &cursor, &block_external, &block_internal); + &cursor); // Fill out the generated template with stores. - if (array_cid == kDynamicCid) { - ASSERT(block_external != nullptr && block_internal != nullptr); - // Store to external in block_external and internal in block_internal - // (resolves (B)). The former stores to "array", which is the returned - // load untagged definition. The latter stores to the original "receiver". - ASSERT(block_external->next() == array); - flow_graph->InsertAfter( - block_external->next(), - NewStore(flow_graph, call, array, index, stored_value, view_cid), - call->deopt_id() != DeoptId::kNone ? call->env() : nullptr, - FlowGraph::kEffect); - flow_graph->InsertAfter( - block_internal, - NewStore(flow_graph, call, receiver, index, stored_value, view_cid), - call->deopt_id() != DeoptId::kNone ? call->env() : nullptr, - FlowGraph::kEffect); - *last = cursor; - } else { - ASSERT(block_external == nullptr && block_internal == nullptr); + { // Store on either external or internal. StoreIndexedInstr* store = NewStore(flow_graph, call, array, index, stored_value, view_cid);
diff --git a/runtime/vm/compiler/backend/linearscan.cc b/runtime/vm/compiler/backend/linearscan.cc index d786d83..9c7d766 100644 --- a/runtime/vm/compiler/backend/linearscan.cc +++ b/runtime/vm/compiler/backend/linearscan.cc
@@ -752,6 +752,9 @@ if (param->base_reg() == FPREG) { slot_index = compiler::target::frame_layout.FrameSlotForVariableIndex(-slot_index); + } else { + ASSERT(param->base_reg() == SPREG); + slot_index += compiler::target::frame_layout.last_param_from_entry_sp; } range->set_assigned_location( Location::StackSlot(slot_index, param->base_reg()));
diff --git a/runtime/vm/compiler/backend/loops_test.cc b/runtime/vm/compiler/backend/loops_test.cc index 1e9c8cd..4b208f8 100644 --- a/runtime/vm/compiler/backend/loops_test.cc +++ b/runtime/vm/compiler/backend/loops_test.cc
@@ -9,6 +9,7 @@ #include "vm/compiler/backend/loops.h" #include "vm/compiler/backend/il_printer.h" +#include "vm/compiler/backend/il_test_helper.h" #include "vm/compiler/backend/inliner.h" #include "vm/compiler/backend/type_propagator.h" #include "vm/compiler/compiler_pass.h" @@ -62,43 +63,18 @@ // Helper method to build CFG and compute induction. static const char* ComputeInduction(Thread* thread, const char* script_chars) { - // Invoke the script. - Dart_Handle script = TestCase::LoadTestScript(script_chars, NULL); - Dart_Handle result = Dart_Invoke(script, NewString("main"), 0, NULL); - EXPECT_VALID(result); + // Load the script and exercise the code once. + const auto& root_library = Library::Handle(LoadTestScript(script_chars)); + Invoke(root_library, "main"); - // Find parsed function "foo". - TransitionNativeToVM transition(thread); - Zone* zone = thread->zone(); - Library& lib = - Library::ZoneHandle(Library::RawCast(Api::UnwrapHandle(script))); - RawFunction* raw_func = - lib.LookupLocalFunction(String::Handle(Symbols::New(thread, "foo"))); - ParsedFunction* parsed_function = - new (zone) ParsedFunction(thread, Function::ZoneHandle(zone, raw_func)); - EXPECT(parsed_function != nullptr); - - // Build flow graph. - CompilerState state(thread); - ZoneGrowableArray<const ICData*>* ic_data_array = - new (zone) ZoneGrowableArray<const ICData*>(); - parsed_function->function().RestoreICDataMap(ic_data_array, true); - kernel::FlowGraphBuilder builder(parsed_function, ic_data_array, nullptr, - nullptr, true, DeoptId::kNone); - FlowGraph* flow_graph = builder.BuildGraph(); - EXPECT(flow_graph != nullptr); - - // Setup some pass data structures and perform minimum passes. - SpeculativeInliningPolicy speculative_policy(/*enable_blacklist*/ false); - CompilerPassState pass_state(thread, flow_graph, &speculative_policy); - JitCallSpecializer call_specializer(flow_graph, &speculative_policy); - pass_state.call_specializer = &call_specializer; - flow_graph->ComputeSSA(0, nullptr); - FlowGraphTypePropagator::Propagate(flow_graph); - call_specializer.ApplyICData(); - flow_graph->SelectRepresentations(); - FlowGraphTypePropagator::Propagate(flow_graph); - flow_graph->Canonicalize(); + std::initializer_list<CompilerPass::Id> passes = { + CompilerPass::kComputeSSA, CompilerPass::kTypePropagation, + CompilerPass::kApplyICData, CompilerPass::kSelectRepresentations, + CompilerPass::kTypePropagation, CompilerPass::kCanonicalize, + }; + const auto& function = Function::Handle(GetFunction(root_library, "foo")); + TestPipeline pipeline(function, CompilerPass::kJIT); + FlowGraph* flow_graph = pipeline.RunPasses(passes); // Build loop hierarchy and find induction. const LoopHierarchy& hierarchy = flow_graph->GetLoopHierarchy(); @@ -116,15 +92,17 @@ // Induction tests. // -TEST_CASE(BasicInductionUp) { +ISOLATE_UNIT_TEST_CASE(BasicInductionUp) { const char* script_chars = - "foo() {\n" - " for (int i = 0; i < 100; i++) {\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + for (int i = 0; i < 100; i++) { + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " LIN(0 + 1 * i) 100\n" // phi @@ -133,15 +111,17 @@ EXPECT_STREQ(expected, ComputeInduction(thread, script_chars)); } -TEST_CASE(BasicInductionDown) { +ISOLATE_UNIT_TEST_CASE(BasicInductionDown) { const char* script_chars = - "foo() {\n" - " for (int i = 100; i > 0; i--) {\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + for (int i = 100; i > 0; i--) { + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " LIN(100 + -1 * i) 0\n" // phi @@ -150,15 +130,17 @@ EXPECT_STREQ(expected, ComputeInduction(thread, script_chars)); } -TEST_CASE(BasicInductionStepUp) { +ISOLATE_UNIT_TEST_CASE(BasicInductionStepUp) { const char* script_chars = - "foo() {\n" - " for (int i = 10; i < 100; i += 2) {\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + for (int i = 10; i < 100; i += 2) { + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " LIN(10 + 2 * i)\n" // phi @@ -167,15 +149,17 @@ EXPECT_STREQ(expected, ComputeInduction(thread, script_chars)); } -TEST_CASE(BasicInductionStepDown) { +ISOLATE_UNIT_TEST_CASE(BasicInductionStepDown) { const char* script_chars = - "foo() {\n" - " for (int i = 100; i >= 0; i -= 7) {\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + for (int i = 100; i >= 0; i -= 7) { + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " LIN(100 + -7 * i)\n" // phi @@ -184,19 +168,21 @@ EXPECT_STREQ(expected, ComputeInduction(thread, script_chars)); } -TEST_CASE(BasicInductionLoopNest) { +ISOLATE_UNIT_TEST_CASE(BasicInductionLoopNest) { const char* script_chars = - "foo() {\n" - " for (int i = 0; i < 100; i++) {\n" - " for (int j = 1; j < 100; j++) {\n" - " for (int k = 2; k < 100; k++) {\n" - " }\n" - " }\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + for (int i = 0; i < 100; i++) { + for (int j = 1; j < 100; j++) { + for (int k = 2; k < 100; k++) { + } + } + } + } + main() { + foo(); + } + )"; const char* expected = " [2\n" " LIN(0 + 1 * i) 100\n" // i @@ -213,18 +199,20 @@ EXPECT_STREQ(expected, ComputeInduction(thread, script_chars)); } -TEST_CASE(ChainInduction) { +ISOLATE_UNIT_TEST_CASE(ChainInduction) { const char* script_chars = - "foo() {\n" - " int j = 1;\n" - " for (int i = 0; i < 100; i++) {\n" - " j += 5;\n" - " j += 7;\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + int j = 1; + for (int i = 0; i < 100; i++) { + j += 5; + j += 7; + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " LIN(1 + 12 * i)\n" // phi (j) @@ -236,21 +224,23 @@ EXPECT_STREQ(expected, ComputeInduction(thread, script_chars)); } -TEST_CASE(TwoWayInduction) { +ISOLATE_UNIT_TEST_CASE(TwoWayInduction) { const char* script_chars = - "foo() {\n" - " int j = 123;\n" - " for (int i = 0; i < 100; i++) {\n" - " if (i == 10) {\n" - " j += 3;\n" - " } else {\n" - " j += 3;\n" - " }\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + int j = 123; + for (int i = 0; i < 100; i++) { + if (i == 10) { + j += 3; + } else { + j += 3; + } + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " LIN(123 + 3 * i)\n" // phi (j) @@ -263,19 +253,21 @@ EXPECT_STREQ(expected, ComputeInduction(thread, script_chars)); } -TEST_CASE(DerivedInduction) { +ISOLATE_UNIT_TEST_CASE(DerivedInduction) { const char* script_chars = - "foo() {\n" - " for (int i = 1; i < 100; i++) {\n" - " int a = i + 3;\n" - " int b = i - 5;\n" - " int c = i * 7;\n" - " int d = - i;\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + for (int i = 1; i < 100; i++) { + int a = i + 3; + int b = i - 5; + int c = i * 7; + int d = - i; + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " LIN(1 + 1 * i) 100\n" // phi @@ -288,21 +280,23 @@ EXPECT_STREQ(expected, ComputeInduction(thread, script_chars)); } -TEST_CASE(WrapAroundAndDerived) { +ISOLATE_UNIT_TEST_CASE(WrapAroundAndDerived) { const char* script_chars = - "foo() {\n" - " int w = 99;\n" - " for (int i = 0; i < 100; i++) {\n" - " int a = w + 3;\n" - " int b = w - 5;\n" - " int c = w * 7;\n" - " int d = - w;\n" - " w = i;\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + int w = 99; + for (int i = 0; i < 100; i++) { + int a = w + 3; + int b = w - 5; + int c = w * 7; + int d = - w; + w = i; + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " WRAP(99, LIN(0 + 1 * i))\n" // phi (w) @@ -316,23 +310,25 @@ EXPECT_STREQ(ComputeInduction(thread, script_chars), expected); } -TEST_CASE(PeriodicAndDerived) { +ISOLATE_UNIT_TEST_CASE(PeriodicAndDerived) { const char* script_chars = - "foo() {\n" - " int p1 = 3;\n" - " int p2 = 5;\n" - " for (int i = 0; i < 100; i++) {\n" - " int a = p1 + 3;\n" - " int b = p1 - 5;\n" - " int c = p1 * 7;\n" - " int d = - p1;\n" - " p1 = - p1;\n" - " p2 = 100 - p2;\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + int p1 = 3; + int p2 = 5; + for (int i = 0; i < 100; i++) { + int a = p1 + 3; + int b = p1 - 5; + int c = p1 * 7; + int d = - p1; + p1 = - p1; + p2 = 100 - p2; + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " PERIOD(3, -3)\n" // phi(p1) @@ -353,15 +349,17 @@ // Bound specific tests. // -TEST_CASE(NonStrictConditionUp) { +ISOLATE_UNIT_TEST_CASE(NonStrictConditionUp) { const char* script_chars = - "foo() {\n" - " for (int i = 0; i <= 100; i++) {\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + for (int i = 0; i <= 100; i++) { + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " LIN(0 + 1 * i) 101\n" // phi @@ -371,16 +369,18 @@ } #ifndef TARGET_ARCH_DBC -TEST_CASE(NonStrictConditionUpWrap) { +ISOLATE_UNIT_TEST_CASE(NonStrictConditionUpWrap) { const char* script_chars = - "foo() {\n" - " for (int i = 0x7ffffffffffffffe; i <= 0x7fffffffffffffff; i++) {\n" - " if (i < 0) break;\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + for (int i = 0x7ffffffffffffffe; i <= 0x7fffffffffffffff; i++) { + if (i < 0) break; + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " LIN(9223372036854775806 + 1 * i)\n" // phi @@ -394,15 +394,17 @@ } #endif -TEST_CASE(NonStrictConditionDown) { +ISOLATE_UNIT_TEST_CASE(NonStrictConditionDown) { const char* script_chars = - "foo() {\n" - " for (int i = 100; i >= 0; i--) {\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + for (int i = 100; i >= 0; i--) { + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " LIN(100 + -1 * i) -1\n" // phi @@ -412,16 +414,18 @@ } #ifndef TARGET_ARCH_DBC -TEST_CASE(NonStrictConditionDownWrap) { +ISOLATE_UNIT_TEST_CASE(NonStrictConditionDownWrap) { const char* script_chars = - "foo() {\n" - " for (int i = 0x8000000000000001; i >= 0x8000000000000000; i--) {\n" - " if (i > 0) break;\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + for (int i = 0x8000000000000001; i >= 0x8000000000000000; i--) { + if (i > 0) break; + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " LIN(-9223372036854775807 + -1 * i)\n" // phi @@ -433,17 +437,20 @@ " ]\n"; EXPECT_STREQ(expected, ComputeInduction(thread, script_chars)); } + #endif -TEST_CASE(NotEqualConditionUp) { +ISOLATE_UNIT_TEST_CASE(NotEqualConditionUp) { const char* script_chars = - "foo() {\n" - " for (int i = 10; i != 20; i++) {\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + for (int i = 10; i != 20; i++) { + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " LIN(10 + 1 * i) 20\n" // phi @@ -452,15 +459,17 @@ EXPECT_STREQ(expected, ComputeInduction(thread, script_chars)); } -TEST_CASE(NotEqualConditionDown) { +ISOLATE_UNIT_TEST_CASE(NotEqualConditionDown) { const char* script_chars = - "foo() {\n" - " for (int i = 20; i != 10; i--) {\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + for (int i = 20; i != 10; i--) { + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " LIN(20 + -1 * i) 10\n" // phi @@ -469,16 +478,18 @@ EXPECT_STREQ(expected, ComputeInduction(thread, script_chars)); } -TEST_CASE(SecondExitUp) { +ISOLATE_UNIT_TEST_CASE(SecondExitUp) { const char* script_chars = - "foo() {\n" - " for (int i = 0; i < 100; i++) {\n" - " if (i >= 50) break;\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + for (int i = 0; i < 100; i++) { + if (i >= 50) break; + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " LIN(0 + 1 * i) 100 50\n" // phi @@ -487,16 +498,18 @@ EXPECT_STREQ(expected, ComputeInduction(thread, script_chars)); } -TEST_CASE(SecondExitDown) { +ISOLATE_UNIT_TEST_CASE(SecondExitDown) { const char* script_chars = - "foo() {\n" - " for (int i = 100; i > 0; i--) {\n" - " if (i <= 10) break;\n" - " }\n" - "}\n" - "main() {\n" - " foo();\n" - "}\n"; + R"( + foo() { + for (int i = 100; i > 0; i--) { + if (i <= 10) break; + } + } + main() { + foo(); + } + )"; const char* expected = " [0\n" " LIN(100 + -1 * i) 0 10\n" // phi
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc index e06cd75..c2bd37b 100644 --- a/runtime/vm/compiler/backend/range_analysis.cc +++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -64,12 +64,8 @@ for (intptr_t i = 0; i < graph_entry->SuccessorCount(); ++i) { auto successor = graph_entry->SuccessorAt(i); - if (successor->IsFunctionEntry() || successor->IsCatchBlockEntry()) { - auto function_entry = successor->AsFunctionEntry(); - auto catch_entry = successor->AsCatchBlockEntry(); - const auto& initial = function_entry != nullptr - ? *function_entry->initial_definitions() - : *catch_entry->initial_definitions(); + if (auto entry = successor->AsBlockEntryWithInitialDefs()) { + const auto& initial = *entry->initial_definitions(); for (intptr_t j = 0; j < initial.length(); ++j) { Definition* current = initial[j]; if (IsIntegerDefinition(current)) { @@ -215,31 +211,31 @@ void RangeAnalysis::InsertConstraintsFor(Definition* defn) { for (Value* use = defn->input_use_list(); use != NULL; use = use->next_use()) { - if (use->instruction()->IsBranch()) { + if (auto branch = use->instruction()->AsBranch()) { if (ConstrainValueAfterBranch(use, defn)) { - Value* other_value = use->instruction()->InputAt(1 - use->use_index()); + Value* other_value = branch->InputAt(1 - use->use_index()); if (!IsIntegerDefinition(other_value->definition())) { ConstrainValueAfterBranch(other_value, other_value->definition()); } } - } else if (use->instruction()->IsCheckArrayBound()) { - ConstrainValueAfterCheckArrayBound(use, defn); + } else if (auto check = use->instruction()->AsCheckBoundBase()) { + ConstrainValueAfterCheckBound(use, check, defn); } } } -void RangeAnalysis::ConstrainValueAfterCheckArrayBound(Value* use, - Definition* defn) { - CheckArrayBoundInstr* check = use->instruction()->AsCheckArrayBound(); - intptr_t use_index = use->use_index(); +void RangeAnalysis::ConstrainValueAfterCheckBound(Value* use, + CheckBoundBase* check, + Definition* defn) { + const intptr_t use_index = use->use_index(); Range* constraint_range = NULL; - if (use_index == CheckArrayBoundInstr::kIndexPos) { + if (use_index == CheckBoundBase::kIndexPos) { Definition* length = check->length()->definition(); constraint_range = new (Z) Range(RangeBoundary::FromConstant(0), RangeBoundary::FromDefinition(length, -1)); } else { - ASSERT(use_index == CheckArrayBoundInstr::kLengthPos); + ASSERT(use_index == CheckBoundBase::kLengthPos); Definition* index = check->index()->definition(); constraint_range = new (Z) Range(RangeBoundary::FromDefinition(index, 1), RangeBoundary::MaxSmi());
diff --git a/runtime/vm/compiler/backend/range_analysis.h b/runtime/vm/compiler/backend/range_analysis.h index 8a8ca4b..a16ea2b 100644 --- a/runtime/vm/compiler/backend/range_analysis.h +++ b/runtime/vm/compiler/backend/range_analysis.h
@@ -566,7 +566,9 @@ Instruction* after); bool ConstrainValueAfterBranch(Value* use, Definition* defn); - void ConstrainValueAfterCheckArrayBound(Value* use, Definition* defn); + void ConstrainValueAfterCheckBound(Value* use, + CheckBoundBase* check, + Definition* defn); // Infer ranges for integer (smi or mint) definitions. void InferRanges();
diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc index dc9e015..21e63d8 100644 --- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc +++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
@@ -4,6 +4,7 @@ #include "vm/compiler/backend/redundancy_elimination.h" #include "vm/compiler/backend/il_printer.h" +#include "vm/compiler/backend/il_test_helper.h" #include "vm/compiler/backend/inliner.h" #include "vm/compiler/backend/loops.h" #include "vm/compiler/backend/type_propagator.h" @@ -28,53 +29,6 @@ return reinterpret_cast<Dart_NativeFunction>(&NoopNative); } -// Helper method to build CFG and run some preliminary optimizations on it. -// TODO(vegorov) we should consider moving this function into utils to share -// between all compiler tests. -static FlowGraph* BuildOptimizedGraph(Thread* thread, - const char* script_chars) { - // Invoke the script. - Dart_Handle script = - TestCase::LoadTestScript(script_chars, &NoopNativeLookup); - Dart_Handle result = Dart_Invoke(script, NewString("main"), 0, nullptr); - EXPECT_VALID(result); - - // Find parsed function "foo". - TransitionNativeToVM transition(thread); - Zone* zone = thread->zone(); - Library& lib = - Library::ZoneHandle(Library::RawCast(Api::UnwrapHandle(script))); - RawFunction* raw_func = - lib.LookupLocalFunction(String::Handle(Symbols::New(thread, "foo"))); - ParsedFunction* parsed_function = - new (zone) ParsedFunction(thread, Function::ZoneHandle(zone, raw_func)); - EXPECT(parsed_function != nullptr); - - // Build flow graph. - CompilerState state(thread); - ZoneGrowableArray<const ICData*>* ic_data_array = - new (zone) ZoneGrowableArray<const ICData*>(); - parsed_function->function().RestoreICDataMap(ic_data_array, true); - kernel::FlowGraphBuilder builder(parsed_function, ic_data_array, nullptr, - nullptr, true, DeoptId::kNone); - FlowGraph* flow_graph = builder.BuildGraph(); - EXPECT(flow_graph != nullptr); - - // Setup some pass data structures and perform minimum passes. - SpeculativeInliningPolicy speculative_policy(/*enable_blacklist=*/false); - CompilerPassState pass_state(thread, flow_graph, &speculative_policy); - JitCallSpecializer call_specializer(flow_graph, &speculative_policy); - pass_state.call_specializer = &call_specializer; - flow_graph->ComputeSSA(0, nullptr); - FlowGraphTypePropagator::Propagate(flow_graph); - call_specializer.ApplyICData(); - flow_graph->SelectRepresentations(); - FlowGraphTypePropagator::Propagate(flow_graph); - flow_graph->Canonicalize(); - - return flow_graph; -} - // Flatten all non-captured LocalVariables from the given scope and its children // and siblings into the given array based on their environment index. static void FlattenScopeIntoEnvironment(FlowGraph* graph, @@ -106,13 +60,25 @@ Thread* thread, const char* script_chars, std::initializer_list<const char*> synchronized) { - FlowGraph* graph = BuildOptimizedGraph(thread, script_chars); + // Load the script and exercise the code once. + const auto& root_library = + Library::Handle(LoadTestScript(script_chars, &NoopNativeLookup)); + Invoke(root_library, "main"); + + // Build the flow graph. + std::initializer_list<CompilerPass::Id> passes = { + CompilerPass::kComputeSSA, CompilerPass::kTypePropagation, + CompilerPass::kApplyICData, CompilerPass::kSelectRepresentations, + CompilerPass::kTypePropagation, CompilerPass::kCanonicalize, + }; + const auto& function = Function::Handle(GetFunction(root_library, "foo")); + TestPipeline pipeline(function, CompilerPass::kJIT); + FlowGraph* graph = pipeline.RunPasses(passes); // Finally run TryCatchAnalyzer on the graph (in AOT mode). OptimizeCatchEntryStates(graph, /*is_aot=*/true); EXPECT_EQ(1, graph->graph_entry()->catch_entries().length()); - auto scope = graph->parsed_function().node_sequence()->scope(); GrowableArray<LocalVariable*> env; @@ -146,7 +112,7 @@ // Tests for TryCatchOptimizer. // -TEST_CASE(TryCatchOptimizer_DeadParameterElimination_Simple1) { +ISOLATE_UNIT_TEST_CASE(TryCatchOptimizer_DeadParameterElimination_Simple1) { const char* script_chars = R"( dynamic blackhole([dynamic val]) native 'BlackholeNative'; foo(int p) { @@ -165,7 +131,7 @@ TryCatchOptimizerTest(thread, script_chars, /*synchronized=*/{}); } -TEST_CASE(TryCatchOptimizer_DeadParameterElimination_Simple2) { +ISOLATE_UNIT_TEST_CASE(TryCatchOptimizer_DeadParameterElimination_Simple2) { const char* script_chars = R"( dynamic blackhole([dynamic val]) native 'BlackholeNative'; foo(int p) { @@ -185,7 +151,7 @@ TryCatchOptimizerTest(thread, script_chars, /*synchronized=*/{"a"}); } -TEST_CASE(TryCatchOptimizer_DeadParameterElimination_Cyclic1) { +ISOLATE_UNIT_TEST_CASE(TryCatchOptimizer_DeadParameterElimination_Cyclic1) { const char* script_chars = R"( dynamic blackhole([dynamic val]) native 'BlackholeNative'; foo(int p) { @@ -207,7 +173,7 @@ TryCatchOptimizerTest(thread, script_chars, /*synchronized=*/{"a", "i"}); } -TEST_CASE(TryCatchOptimizer_DeadParameterElimination_Cyclic2) { +ISOLATE_UNIT_TEST_CASE(TryCatchOptimizer_DeadParameterElimination_Cyclic2) { const char* script_chars = R"( dynamic blackhole([dynamic val]) native 'BlackholeNative'; foo(int p) {
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc index e3f4f7d..0dec0c9 100644 --- a/runtime/vm/compiler/backend/type_propagator.cc +++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -580,12 +580,14 @@ CompileType* CompileType::ComputeRefinedType(CompileType* old_type, CompileType* new_type) { + ASSERT(new_type != nullptr); + // In general, prefer the newly inferred type over old type. // It is possible that new and old types are unrelated or do not intersect // at all (for example, in case of unreachable code). // Discard None type as it is used to denote an unknown type. - if (old_type->IsNone()) { + if (old_type == nullptr || old_type->IsNone()) { return new_type; } if (new_type->IsNone()) { @@ -826,13 +828,22 @@ return reaching_type_; } -void Value::RefineReachingType(CompileType* type) { - ASSERT(type != NULL); - if (reaching_type_ == NULL) { - reaching_type_ = type; - } else { - reaching_type_ = CompileType::ComputeRefinedType(reaching_type_, type); +void Value::SetReachingType(CompileType* type) { + // If [type] is owned but not by the definition which flows into this use + // then we need to disconect the type from original owner by cloning it. + // This is done to prevent situations when [type] is updated by its owner + // but [owner] is no longer connected to this use through def-use chain + // and as a result type propagator does not recompute type of the current + // instruction. + if (type != nullptr && type->owner() != nullptr && + type->owner() != definition()) { + type = new CompileType(*type); } + reaching_type_ = type; +} + +void Value::RefineReachingType(CompileType* type) { + SetReachingType(CompileType::ComputeRefinedType(reaching_type_, type)); } CompileType PhiInstr::ComputeType() const { @@ -1447,6 +1458,10 @@ return CompileType::Dynamic(); } +bool CheckedSmiOpInstr::RecomputeType() { + return UpdateType(ComputeType()); +} + CompileType CheckedSmiComparisonInstr::ComputeType() const { if (Isolate::Current()->can_use_strong_mode_types()) { CompileType* type = call()->Type();
diff --git a/runtime/vm/compiler/backend/type_propagator_test.cc b/runtime/vm/compiler/backend/type_propagator_test.cc new file mode 100644 index 0000000..ab6501bc --- /dev/null +++ b/runtime/vm/compiler/backend/type_propagator_test.cc
@@ -0,0 +1,519 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +#include <utility> + +#include "vm/compiler/backend/block_builder.h" +#include "vm/compiler/backend/il_printer.h" +#include "vm/compiler/backend/inliner.h" +#include "vm/compiler/backend/loops.h" +#include "vm/compiler/backend/redundancy_elimination.h" +#include "vm/compiler/backend/type_propagator.h" +#include "vm/compiler/compiler_pass.h" +#include "vm/compiler/frontend/kernel_to_il.h" +#include "vm/compiler/jit/compiler.h" +#include "vm/compiler/jit/jit_call_specializer.h" +#include "vm/log.h" +#include "vm/object.h" +#include "vm/parser.h" +#include "vm/symbols.h" +#include "vm/unit_test.h" + +namespace dart { + +#if !defined(PRODUCT) +#define TOCSTRING(v) ((v)->ToCString()) +#else +#define TOCSTRING(v) "<?>" +#endif + +#define EXPECT_PROPERTY(entity, property) \ + do { \ + auto& it = *entity; \ + if (!(property)) { \ + dart::Expect(__FILE__, __LINE__) \ + .Fail("expected " #property " for " #entity " which is %s.\n", \ + TOCSTRING(entity)); \ + } \ + } while (0) + +using compiler::BlockBuilder; + +FlowGraph* MakeDummyGraph(Thread* thread) { + const Function& func = Function::ZoneHandle(Function::New( + String::Handle(Symbols::New(thread, "dummy")), + RawFunction::kRegularFunction, + /*is_static=*/true, + /*is_const=*/false, + /*is_abstract=*/false, + /*is_external=*/false, + /*is_native=*/true, + Class::Handle(thread->isolate()->object_store()->object_class()), + TokenPosition::kNoSource)); + + Zone* zone = thread->zone(); + ParsedFunction* parsed_function = new (zone) ParsedFunction(thread, func); + + parsed_function->SetNodeSequence(new SequenceNode( + TokenPosition::kNoSource, new LocalScope(nullptr, 0, 0))); + + auto graph_entry = + new GraphEntryInstr(*parsed_function, Compiler::kNoOSRDeoptId); + + intptr_t block_id = 1; // 0 is GraphEntry. + graph_entry->set_normal_entry( + new FunctionEntryInstr(graph_entry, block_id, kInvalidTryIndex, + CompilerState::Current().GetNextDeoptId())); + return new FlowGraph(*parsed_function, graph_entry, block_id, + PrologueInfo{-1, -1}); +} + +namespace { +class FlowGraphBuilderHelper { + public: + explicit FlowGraphBuilderHelper(FlowGraph* flow_graph) + : state_(CompilerState::Current()), + flow_graph_(*flow_graph), + constant_dead_(flow_graph->GetConstant(Symbols::OptimizedOut())) {} + + TargetEntryInstr* TargetEntry(intptr_t try_index = kInvalidTryIndex) const { + return new TargetEntryInstr(flow_graph_.allocate_block_id(), try_index, + state_.GetNextDeoptId()); + } + + JoinEntryInstr* JoinEntry(intptr_t try_index = kInvalidTryIndex) const { + return new JoinEntryInstr(flow_graph_.allocate_block_id(), try_index, + state_.GetNextDeoptId()); + } + + ConstantInstr* IntConstant(int64_t value) const { + return flow_graph_.GetConstant( + Integer::Handle(Integer::New(value, Heap::kOld))); + } + + ConstantInstr* DoubleConstant(double value) { + return flow_graph_.GetConstant( + Double::Handle(Double::New(value, Heap::kOld))); + } + + PhiInstr* Phi(JoinEntryInstr* join, + std::initializer_list<std::pair<BlockEntryInstr*, Definition*>> + incomming) { + auto phi = new PhiInstr(join, incomming.size()); + for (size_t i = 0; i < incomming.size(); i++) { + auto input = new Value(constant_dead_); + phi->SetInputAt(i, input); + input->definition()->AddInputUse(input); + } + for (auto pair : incomming) { + pending_phis_.Add({phi, pair.first, pair.second}); + } + return phi; + } + + void FinishGraph() { + flow_graph_.DiscoverBlocks(); + GrowableArray<BitVector*> dominance_frontier; + flow_graph_.ComputeDominators(&dominance_frontier); + + for (auto& pending : pending_phis_) { + auto join = pending.phi->block(); + EXPECT(pending.phi->InputCount() == join->PredecessorCount()); + auto pred_index = join->IndexOfPredecessor(pending.pred); + EXPECT(pred_index != -1); + pending.phi->InputAt(pred_index)->BindTo(pending.defn); + } + } + + private: + CompilerState& state_; + FlowGraph& flow_graph_; + ConstantInstr* constant_dead_; + + struct PendingPhiInput { + PhiInstr* phi; + BlockEntryInstr* pred; + Definition* defn; + }; + GrowableArray<PendingPhiInput> pending_phis_; +}; +} // namespace + +ISOLATE_UNIT_TEST_CASE(TypePropagator_RedefinitionAfterStrictCompareWithNull) { + CompilerState S(thread); + + FlowGraph* flow_graph = MakeDummyGraph(thread); + FlowGraphBuilderHelper H(flow_graph); + + // Add a variable into the scope which would provide static type for the + // parameter. + LocalVariable* v0_var = + new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, + String::Handle(Symbols::New(thread, "v0")), + AbstractType::ZoneHandle(Type::IntType())); + v0_var->set_type_check_mode(LocalVariable::kTypeCheckedByCaller); + flow_graph->parsed_function().node_sequence()->scope()->AddVariable(v0_var); + + auto normal_entry = flow_graph->graph_entry()->normal_entry(); + + // We are going to build the following graph: + // + // B0[graph_entry]: + // B1[function_entry]: + // v0 <- Parameter(0) + // if v0 == null then B2 else B3 + // B2: + // Return(v0) + // B3: + // Return(v0) + + Definition* v0; + auto b2 = H.TargetEntry(); + auto b3 = H.TargetEntry(); + + { + BlockBuilder builder(flow_graph, normal_entry); + v0 = builder.AddParameter(0, /*with_frame=*/true); + builder.AddBranch( + new StrictCompareInstr( + TokenPosition::kNoSource, Token::kEQ_STRICT, new Value(v0), + new Value(flow_graph->GetConstant(Object::Handle())), + /*needs_number_check=*/false, S.GetNextDeoptId()), + b2, b3); + } + + { + BlockBuilder builder(flow_graph, b2); + builder.AddReturn(new Value(v0)); + } + + { + BlockBuilder builder(flow_graph, b3); + builder.AddReturn(new Value(v0)); + } + + H.FinishGraph(); + + FlowGraphTypePropagator::Propagate(flow_graph); + + // We expect that v0 is inferred to be nullable int because that is what + // static type of an associated variable tells us. + EXPECT(v0->Type()->IsNullableInt()); + + // In B2 v0 should not have any additional type information so reaching + // type should be still nullable int. + auto b2_value = b2->last_instruction()->AsReturn()->value(); + EXPECT(b2_value->Type()->IsNullableInt()); + + // In B3 v0 is constrained by comparison with null - it should be non-nullable + // integer. There should be a Redefinition inserted to prevent LICM past + // the branch. + auto b3_value = b3->last_instruction()->AsReturn()->value(); + EXPECT(b3_value->Type()->IsInt()); + EXPECT(b3_value->definition()->IsRedefinition()); + EXPECT(b3_value->definition()->GetBlock() == b3); +} + +ISOLATE_UNIT_TEST_CASE( + TypePropagator_RedefinitionAfterStrictCompareWithLoadClassId) { + CompilerState S(thread); + + FlowGraph* flow_graph = MakeDummyGraph(thread); + FlowGraphBuilderHelper H(flow_graph); + + // We are going to build the following graph: + // + // B0[graph_entry]: + // B1[function_entry]: + // v0 <- Parameter(0) + // v1 <- LoadClassId(v0) + // if v1 == kDoubleCid then B2 else B3 + // B2: + // Return(v0) + // B3: + // Return(v0) + + Definition* v0; + auto b1 = flow_graph->graph_entry()->normal_entry(); + auto b2 = H.TargetEntry(); + auto b3 = H.TargetEntry(); + + { + BlockBuilder builder(flow_graph, b1); + v0 = builder.AddParameter(0, /*with_frame=*/true); + auto load_cid = builder.AddDefinition(new LoadClassIdInstr(new Value(v0))); + builder.AddBranch( + new StrictCompareInstr( + TokenPosition::kNoSource, Token::kEQ_STRICT, new Value(load_cid), + new Value(H.IntConstant(kDoubleCid)), + /*needs_number_check=*/false, S.GetNextDeoptId()), + b2, b3); + } + + { + BlockBuilder builder(flow_graph, b2); + builder.AddReturn(new Value(v0)); + } + + { + BlockBuilder builder(flow_graph, b3); + builder.AddReturn(new Value(v0)); + } + + H.FinishGraph(); + + FlowGraphTypePropagator::Propagate(flow_graph); + + // There should be no information available about the incoming type of + // the parameter either on entry or in B3. + EXPECT_PROPERTY(v0->Type()->ToAbstractType(), it.IsDynamicType()); + auto b3_value = b3->last_instruction()->AsReturn()->value(); + EXPECT(b3_value->Type() == v0->Type()); + + // In B3 v0 is constrained by comparison of its cid with kDoubleCid - it + // should be non-nullable double. There should be a Redefinition inserted to + // prevent LICM past the branch. + auto b2_value = b2->last_instruction()->AsReturn()->value(); + EXPECT_PROPERTY(b2_value->Type(), it.IsDouble()); + EXPECT_PROPERTY(b2_value->definition(), it.IsRedefinition()); + EXPECT_PROPERTY(b2_value->definition()->GetBlock(), &it == b2); +} + +ISOLATE_UNIT_TEST_CASE(TypePropagator_Refinement) { + CompilerState S(thread); + + const Class& object_class = + Class::Handle(thread->isolate()->object_store()->object_class()); + + const Function& target_func = Function::ZoneHandle(Function::New( + String::Handle(Symbols::New(thread, "dummy2")), + RawFunction::kRegularFunction, + /*is_static=*/true, + /*is_const=*/false, + /*is_abstract=*/false, + /*is_external=*/false, + /*is_native=*/true, object_class, TokenPosition::kNoSource)); + target_func.set_result_type(AbstractType::Handle(Type::IntType())); + + const Field& field = Field::ZoneHandle( + Field::New(String::Handle(Symbols::New(thread, "dummy")), + /*is_static=*/true, + /*is_final=*/false, + /*is_const=*/false, + /*is_reflectable=*/true, object_class, Object::dynamic_type(), + TokenPosition::kNoSource, TokenPosition::kNoSource)); + + FlowGraph* flow_graph = MakeDummyGraph(thread); + FlowGraphBuilderHelper H(flow_graph); + + // We are going to build the following graph: + // + // B0[graph_entry] + // B1[function_entry]: + // v0 <- Parameter(0) + // v1 <- Constant(0) + // if v0 == 1 then B3 else B2 + // B2: + // v2 <- StaticCall(target_func) + // goto B4 + // B3: + // goto B4 + // B4: + // v3 <- phi(v1, v2) + // return v5 + + Definition* v0; + Definition* v2; + PhiInstr* v3; + auto b1 = flow_graph->graph_entry()->normal_entry(); + auto b2 = H.TargetEntry(); + auto b3 = H.TargetEntry(); + auto b4 = H.JoinEntry(); + + { + BlockBuilder builder(flow_graph, b1); + v0 = builder.AddParameter(0, /*with_frame=*/true); + builder.AddBranch(new StrictCompareInstr( + TokenPosition::kNoSource, Token::kEQ_STRICT, + new Value(v0), new Value(H.IntConstant(1)), + /*needs_number_check=*/false, S.GetNextDeoptId()), + b2, b3); + } + + { + BlockBuilder builder(flow_graph, b2); + v2 = builder.AddDefinition( + new StaticCallInstr(TokenPosition::kNoSource, target_func, + /*type_args_len=*/0, + /*argument_names=*/Array::empty_array(), + new PushArgumentsArray(0), S.GetNextDeoptId(), + /*call_count=*/0, ICData::RebindRule::kStatic)); + builder.AddInstruction(new GotoInstr(b4, S.GetNextDeoptId())); + } + + { + BlockBuilder builder(flow_graph, b3); + builder.AddInstruction(new GotoInstr(b4, S.GetNextDeoptId())); + } + + { + BlockBuilder builder(flow_graph, b4); + v3 = H.Phi(b4, {{b2, v2}, {b3, H.IntConstant(0)}}); + builder.AddPhi(v3); + builder.AddReturn(new Value(v3)); + } + + H.FinishGraph(); + FlowGraphTypePropagator::Propagate(flow_graph); + + EXPECT_PROPERTY(v2->Type(), it.IsNullableInt()); + EXPECT_PROPERTY(v3->Type(), it.IsNullableInt()); + + auto v4 = new LoadStaticFieldInstr(new Value(flow_graph->GetConstant(field)), + TokenPosition::kNoSource); + flow_graph->InsertBefore(v2, v4, nullptr, FlowGraph::kValue); + v2->ReplaceUsesWith(v4); + v2->RemoveFromGraph(); + + FlowGraphTypePropagator::Propagate(flow_graph); + + EXPECT_PROPERTY(v3->Type(), it.IsNullableInt()); +} + +// This test verifies that mutable compile types are not incorrectly cached +// as reaching types after inference. +ISOLATE_UNIT_TEST_CASE(TypePropagator_Regress36156) { + CompilerState S(thread); + + FlowGraph* flow_graph = MakeDummyGraph(thread); + FlowGraphBuilderHelper H(flow_graph); + + // We are going to build the following graph: + // + // B0[graph_entry] + // B1[function_entry]: + // v0 <- Parameter(0) + // v1 <- Constant(42) + // v2 <- Constant(24) + // v4 <- Constant(1.0) + // if v0 == 1 then B6 else B2 + // B2: + // if v0 == 2 then B3 else B4 + // B3: + // goto B5 + // B4: + // goto B5 + // B5: + // v3 <- phi(v1, v2) + // goto B7 + // B6: + // goto B7 + // B7: + // v5 <- phi(v4, v3) + // return v5 + + Definition* v0; + PhiInstr* v3; + PhiInstr* v5; + auto b1 = flow_graph->graph_entry()->normal_entry(); + auto b2 = H.TargetEntry(); + auto b3 = H.TargetEntry(); + auto b4 = H.TargetEntry(); + auto b5 = H.JoinEntry(); + auto b6 = H.TargetEntry(); + auto b7 = H.JoinEntry(); + + { + BlockBuilder builder(flow_graph, b1); + v0 = builder.AddParameter(0, /*with_frame=*/true); + builder.AddBranch(new StrictCompareInstr( + TokenPosition::kNoSource, Token::kEQ_STRICT, + new Value(v0), new Value(H.IntConstant(1)), + /*needs_number_check=*/false, S.GetNextDeoptId()), + b6, b2); + } + + { + BlockBuilder builder(flow_graph, b2); + builder.AddBranch(new StrictCompareInstr( + TokenPosition::kNoSource, Token::kEQ_STRICT, + new Value(v0), new Value(H.IntConstant(2)), + /*needs_number_check=*/false, S.GetNextDeoptId()), + b3, b4); + } + + { + BlockBuilder builder(flow_graph, b3); + builder.AddInstruction(new GotoInstr(b5, S.GetNextDeoptId())); + } + + { + BlockBuilder builder(flow_graph, b4); + builder.AddInstruction(new GotoInstr(b5, S.GetNextDeoptId())); + } + + { + BlockBuilder builder(flow_graph, b5); + v3 = H.Phi(b5, {{b3, H.IntConstant(42)}, {b4, H.IntConstant(24)}}); + builder.AddPhi(v3); + builder.AddInstruction(new GotoInstr(b7, S.GetNextDeoptId())); + } + + { + BlockBuilder builder(flow_graph, b6); + builder.AddInstruction(new GotoInstr(b7, S.GetNextDeoptId())); + } + + { + BlockBuilder builder(flow_graph, b7); + v5 = H.Phi(b7, {{b5, v3}, {b6, H.DoubleConstant(1.0)}}); + builder.AddPhi(v5); + builder.AddInstruction(new ReturnInstr(TokenPosition::kNoSource, + new Value(v5), S.GetNextDeoptId())); + } + + H.FinishGraph(); + + FlowGraphTypePropagator::Propagate(flow_graph); + + // We expect that v3 has an integer type, and v5 is either T{Object} or + // T{num}. + EXPECT_PROPERTY(v3->Type(), it.IsInt()); + EXPECT_PROPERTY(v5->Type()->ToAbstractType(), + it.IsObjectType() || it.IsNumberType()); + + // Now unbox v3 phi by inserting unboxing for both inputs and boxing + // for the result. + { + v3->set_representation(kUnboxedInt64); + for (intptr_t i = 0; i < v3->InputCount(); i++) { + auto input = v3->InputAt(i); + auto unbox = + new UnboxInt64Instr(input->CopyWithType(), S.GetNextDeoptId(), + Instruction::kNotSpeculative); + flow_graph->InsertBefore( + v3->block()->PredecessorAt(i)->last_instruction(), unbox, nullptr, + FlowGraph::kValue); + input->BindTo(unbox); + } + + auto box = new BoxInt64Instr(new Value(v3)); + v3->ReplaceUsesWith(box); + flow_graph->InsertBefore(b4->last_instruction(), box, nullptr, + FlowGraph::kValue); + } + + // Run type propagation again. + FlowGraphTypePropagator::Propagate(flow_graph); + + // If CompileType of v3 would be cached as a reaching type at its use in + // v5 then we will be incorrect type propagation results. + // We expect that v3 has an integer type, and v5 is either T{Object} or + // T{num}. + EXPECT_PROPERTY(v3->Type(), it.IsInt()); + EXPECT_PROPERTY(v5->Type()->ToAbstractType(), + it.IsObjectType() || it.IsNumberType()); +} + +} // namespace dart
diff --git a/runtime/vm/compiler/backend/typed_data_aot_test.cc b/runtime/vm/compiler/backend/typed_data_aot_test.cc new file mode 100644 index 0000000..65156bf --- /dev/null +++ b/runtime/vm/compiler/backend/typed_data_aot_test.cc
@@ -0,0 +1,450 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +#include <vector> + +#include "vm/compiler/backend/il_printer.h" +#include "vm/compiler/backend/il_test_helper.h" +#include "vm/compiler/call_specializer.h" +#include "vm/compiler/compiler_pass.h" +#include "vm/object.h" +#include "vm/unit_test.h" + +namespace dart { + +#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) + +// This test asserts that we are inlining accesses to typed data interfaces +// (e.g. Uint8List) if there are no instantiated 3rd party classes. +ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_Inlining) { + const char* kScript = + R"( + import 'dart:typed_data'; + + void foo(Uint8List list, int from) { + if (from >= list.length) { + list[from]; + } + } + )"; + + const auto& root_library = Library::Handle(LoadTestScript(kScript)); + const auto& function = Function::Handle(GetFunction(root_library, "foo")); + + TestPipeline pipeline(function, CompilerPass::kAOT); + FlowGraph* flow_graph = pipeline.RunPasses({}); + + auto entry = flow_graph->graph_entry()->normal_entry(); + EXPECT(entry != nullptr); + + CheckNullInstr* check_null = nullptr; + LoadFieldInstr* load_field = nullptr; + GenericCheckBoundInstr* bounds_check = nullptr; + Instruction* load_untagged = nullptr; + LoadIndexedInstr* load_indexed = nullptr; + + ILMatcher cursor(flow_graph, entry); + RELEASE_ASSERT(cursor.TryMatch({ + kMoveGlob, + {kMatchAndMoveCheckNull, &check_null}, + {kMatchAndMoveLoadField, &load_field}, + kMoveGlob, + kMatchAndMoveBranchTrue, + kMoveGlob, + {kMatchAndMoveGenericCheckBound, &bounds_check}, + {kMatchAndMoveLoadUntagged, &load_untagged}, + kMoveParallelMoves, + {kMatchAndMoveLoadIndexed, &load_indexed}, + kMoveGlob, + kMatchReturn, + })); + + EXPECT(load_field->InputAt(0)->definition()->IsParameter()); + EXPECT(bounds_check->InputAt(0)->definition() == load_field); + EXPECT(load_untagged->InputAt(0)->definition()->IsParameter()); + EXPECT(load_indexed->InputAt(0)->definition() == load_untagged); +} + +// This test asserts that we are not inlining accesses to typed data interfaces +// (e.g. Uint8List) if there are instantiated 3rd party classes (e.g. +// UnmodifiableUint8ListView). +ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_NotInlining) { + const char* kScript = + R"( + import 'dart:typed_data'; + + createThirdPartyUint8List() => UnmodifiableUint8ListView(Uint8List(10)); + + void foo(Uint8List list, int from) { + if (from >= list.length) { + list[from]; + } + } + )"; + + const auto& root_library = Library::Handle(LoadTestScript(kScript)); + + // Firstly we ensure a non internal/external/view Uint8List is allocated. + Invoke(root_library, "createThirdPartyUint8List"); + + // Now we ensure that we don't perform the inlining of the `list[from]` + // access. + const auto& function = Function::Handle(GetFunction(root_library, "foo")); + TestPipeline pipeline(function, CompilerPass::kAOT); + FlowGraph* flow_graph = pipeline.RunPasses({}); + + auto entry = flow_graph->graph_entry()->normal_entry(); + EXPECT(entry != nullptr); + + InstanceCallInstr* length_call = nullptr; + PushArgumentInstr* pusharg1 = nullptr; + PushArgumentInstr* pusharg2 = nullptr; + InstanceCallInstr* index_get_call = nullptr; + + ILMatcher cursor(flow_graph, entry); + RELEASE_ASSERT(cursor.TryMatch({ + kMoveGlob, + {kMatchAndMoveInstanceCall, &length_call}, + kMoveGlob, + kMatchAndMoveBranchTrue, + kMoveGlob, + {kMatchAndMovePushArgument, &pusharg1}, + {kMatchAndMovePushArgument, &pusharg2}, + {kMatchAndMoveInstanceCall, &index_get_call}, + kMoveGlob, + kMatchReturn, + })); + + EXPECT(length_call->Selector() == Symbols::GetLength().raw()); + EXPECT(pusharg1->InputAt(0)->definition()->IsParameter()); + EXPECT(pusharg2->InputAt(0)->definition()->IsParameter()); + EXPECT(index_get_call->Selector() == Symbols::IndexToken().raw()); +} + +// This test asserts that we are inlining get:length, [] and []= for all typed +// data interfaces. It also ensures that the asserted IR actually works by +// exercising it. +ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_FunctionalGetSet) { + const char* kTemplate = + R"( + import 'dart:typed_data'; + + void reverse%s(%s list) { + final length = list.length; + final halfLength = length ~/ 2; + for (int i = 0; i < halfLength; ++i) { + final tmp = list[length-i-1]; + list[length-i-1] = list[i]; + list[i] = tmp; + } + } + )"; + + std::initializer_list<MatchCode> expected_il = { + // Before loop + kMoveGlob, + kMatchAndMoveCheckNull, + kMatchAndMoveLoadField, + kMoveGlob, + kMatchAndMoveBranchTrue, + + // Loop + kMoveGlob, + // Load 1 + kMatchAndMoveGenericCheckBound, + kMoveGlob, + kMatchAndMoveLoadUntagged, + kMoveParallelMoves, + kMatchAndMoveLoadIndexed, + kMoveGlob, + // Load 2 + kMatchAndMoveGenericCheckBound, + kMoveGlob, + kMatchAndMoveLoadUntagged, + kMoveParallelMoves, + kMatchAndMoveLoadIndexed, + kMoveGlob, + // Store 1 + kMatchAndMoveGenericCheckBound, + kMoveGlob, + kMoveParallelMoves, + kMatchAndMoveLoadUntagged, + kMoveParallelMoves, + kMatchAndMoveStoreIndexed, + kMoveGlob, + // Store 2 + kMoveParallelMoves, + kMatchAndMoveLoadUntagged, + kMoveParallelMoves, + kMatchAndMoveStoreIndexed, + kMoveGlob, + + // Exit the loop. + kMatchAndMoveBranchFalse, + kMoveGlob, + kMatchReturn, + }; + + char script_buffer[1024]; + char uri_buffer[1024]; + char function_name[1024]; + auto& lib = Library::Handle(); + auto& function = Function::Handle(); + auto& view = TypedDataView::Handle(); + auto& arguments = Array::Handle(); + auto& result = Object::Handle(); + + auto run_reverse_list = [&](const char* name, const TypedDataBase& data) { + // Fill in the template with the [name]. + Utils::SNPrint(script_buffer, sizeof(script_buffer), kTemplate, name, name); + Utils::SNPrint(uri_buffer, sizeof(uri_buffer), "file:///reverse-%s.dart", + name); + Utils::SNPrint(function_name, sizeof(function_name), "reverse%s", name); + + // Create a new library, load the function and compile it using our AOT + // pipeline. + lib = LoadTestScript(script_buffer, nullptr, uri_buffer); + function = GetFunction(lib, function_name); + TestPipeline pipeline(function, CompilerPass::kAOT); + FlowGraph* flow_graph = pipeline.RunPasses({}); + auto entry = flow_graph->graph_entry()->normal_entry(); + + // Ensure the IL matches what we expect. + ILMatcher cursor(flow_graph, entry); + EXPECT(cursor.TryMatch(expected_il)); + + // Compile the graph and attach the code. + pipeline.CompileGraphAndAttachFunction(); + + // Class ids are numbered from internal/view/external. + const classid_t view_cid = data.GetClassId() + 1; + ASSERT(RawObject::IsTypedDataViewClassId(view_cid)); + + // First and last element are not in the view, i.e. + // view[0:view.length()-1] = data[1:data.length()-2] + const intptr_t length_in_bytes = + (data.LengthInBytes() - 2 * data.ElementSizeInBytes()); + view = TypedDataView::New(view_cid, data, data.ElementSizeInBytes(), + length_in_bytes / data.ElementSizeInBytes()); + ASSERT(data.ElementType() == view.ElementType()); + + arguments = Array::New(1); + arguments.SetAt(0, view); + result = DartEntry::InvokeFunction(function, arguments); + EXPECT(result.IsNull()); + + // Ensure we didn't deoptimize to unoptimized code. + EXPECT(function.unoptimized_code() == Code::null()); + }; + + const auto& uint8_list = + TypedData::Handle(TypedData::New(kTypedDataUint8ArrayCid, 16)); + const auto& uint8c_list = + TypedData::Handle(TypedData::New(kTypedDataUint8ClampedArrayCid, 16)); + const auto& int16_list = + TypedData::Handle(TypedData::New(kTypedDataInt16ArrayCid, 16)); + const auto& uint16_list = + TypedData::Handle(TypedData::New(kTypedDataUint16ArrayCid, 16)); + const auto& int32_list = + TypedData::Handle(TypedData::New(kTypedDataInt32ArrayCid, 16)); + const auto& uint32_list = + TypedData::Handle(TypedData::New(kTypedDataUint32ArrayCid, 16)); + const auto& int64_list = + TypedData::Handle(TypedData::New(kTypedDataInt64ArrayCid, 16)); + const auto& uint64_list = + TypedData::Handle(TypedData::New(kTypedDataUint64ArrayCid, 16)); + const auto& float32_list = + TypedData::Handle(TypedData::New(kTypedDataFloat32ArrayCid, 16)); + const auto& float64_list = + TypedData::Handle(TypedData::New(kTypedDataFloat64ArrayCid, 16)); + const auto& int8_list = + TypedData::Handle(TypedData::New(kTypedDataInt8ArrayCid, 16)); + for (intptr_t i = 0; i < 16; ++i) { + int8_list.SetInt8(i, i); + uint8_list.SetUint8(i, i); + uint8c_list.SetUint8(i, i); + int16_list.SetInt16(2 * i, i); + uint16_list.SetUint16(2 * i, i); + int32_list.SetInt32(4 * i, i); + uint32_list.SetUint32(4 * i, i); + int64_list.SetInt64(8 * i, i); + uint64_list.SetUint64(8 * i, i); + float32_list.SetFloat32(4 * i, i + 0.5); + float64_list.SetFloat64(8 * i, i + 0.7); + } + run_reverse_list("Uint8List", int8_list); + run_reverse_list("Int8List", uint8_list); + run_reverse_list("Uint8ClampedList", uint8c_list); + run_reverse_list("Int16List", int16_list); + run_reverse_list("Uint16List", uint16_list); + run_reverse_list("Int32List", int32_list); + run_reverse_list("Uint32List", uint32_list); + run_reverse_list("Int64List", int64_list); + run_reverse_list("Uint64List", uint64_list); + run_reverse_list("Float32List", float32_list); + run_reverse_list("Float64List", float64_list); + for (intptr_t i = 0; i < 16; ++i) { + // Only the values in the view are reversed. + const bool in_view = i >= 1 && i < 15; + + const int64_t expected_value = in_view ? (16 - i - 1) : i; + const uint64_t expected_uvalue = in_view ? (16 - i - 1) : i; + const float expected_fvalue = (in_view ? (16 - i - 1) : i) + 0.5; + const double expected_dvalue = (in_view ? (16 - i - 1) : i) + 0.7; + + EXPECT(int8_list.GetInt8(i) == expected_value); + EXPECT(uint8_list.GetUint8(i) == expected_uvalue); + EXPECT(uint8c_list.GetUint8(i) == expected_uvalue); + EXPECT(int16_list.GetInt16(2 * i) == expected_value); + EXPECT(uint16_list.GetUint16(2 * i) == expected_uvalue); + EXPECT(int32_list.GetInt32(4 * i) == expected_value); + EXPECT(uint32_list.GetUint32(4 * i) == expected_uvalue); + EXPECT(int64_list.GetInt64(8 * i) == expected_value); + EXPECT(uint64_list.GetUint64(8 * i) == expected_uvalue); + EXPECT(float32_list.GetFloat32(4 * i) == expected_fvalue); + EXPECT(float64_list.GetFloat64(8 * i) == expected_dvalue); + } +} + +// This test asserts that we get errors if receiver, index or value are null. +ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_FunctionalIndexError) { + const char* kTemplate = + R"( + import 'dart:typed_data'; + void set%s(%s list, int index, %s value) { + list[index] = value; + } + )"; + + std::initializer_list<MatchCode> expected_il = { + // Receiver null check + kMoveGlob, + kMatchAndMoveCheckNull, + + // Index null check + kMoveGlob, + kMatchAndMoveCheckNull, + + // Value null check + kMoveGlob, + kMatchAndMoveCheckNull, + + // LoadField length + kMoveGlob, + kMatchAndMoveLoadField, + + // Bounds check + kMoveGlob, + kMatchAndMoveGenericCheckBound, + + // Store value. + kMoveGlob, + kMatchAndMoveLoadUntagged, + kMoveParallelMoves, + kMatchAndMoveOptionalUnbox, + kMoveParallelMoves, + kMatchAndMoveStoreIndexed, + + // Return + kMoveGlob, + kMatchReturn, + }; + + char script_buffer[1024]; + char uri_buffer[1024]; + char function_name[1024]; + auto& lib = Library::Handle(); + auto& function = Function::Handle(); + auto& arguments = Array::Handle(); + auto& result = Object::Handle(); + + const intptr_t kIndex = 1; + const intptr_t kLastStage = 3; + + auto run_test = [&](const char* name, const char* type, + const TypedDataBase& data, const Object& value, + int stage) { + // Fill in the template with the [name]. + Utils::SNPrint(script_buffer, sizeof(script_buffer), kTemplate, name, name, + type); + Utils::SNPrint(uri_buffer, sizeof(uri_buffer), "file:///set-%s.dart", name); + Utils::SNPrint(function_name, sizeof(function_name), "set%s", name); + + // Create a new library, load the function and compile it using our AOT + // pipeline. + lib = LoadTestScript(script_buffer, nullptr, uri_buffer); + function = GetFunction(lib, function_name); + TestPipeline pipeline(function, CompilerPass::kAOT); + FlowGraph* flow_graph = pipeline.RunPasses({}); + auto entry = flow_graph->graph_entry()->normal_entry(); + + // Ensure the IL matches what we expect. + ILMatcher cursor(flow_graph, entry, /*trace=*/true); + EXPECT(cursor.TryMatch(expected_il)); + + // Compile the graph and attach the code. + pipeline.CompileGraphAndAttachFunction(); + + arguments = Array::New(3); + arguments.SetAt(0, stage == 0 ? Object::null_object() : data); + arguments.SetAt( + 1, stage == 1 ? Object::null_object() : Smi::Handle(Smi::New(kIndex))); + arguments.SetAt(2, stage == 2 ? Object::null_object() : value); + result = DartEntry::InvokeFunction(function, arguments); + + // Ensure we didn't deoptimize to unoptimized code. + EXPECT(function.unoptimized_code() == Code::null()); + + if (stage == kLastStage) { + // The last stage must be successful + EXPECT(result.IsNull()); + } else { + // Ensure we get an error. + EXPECT(result.IsUnhandledException()); + result = UnhandledException::Cast(result).exception(); + } + }; + + const auto& uint8_list = + TypedData::Handle(TypedData::New(kTypedDataUint8ArrayCid, 16)); + const auto& uint8c_list = + TypedData::Handle(TypedData::New(kTypedDataUint8ClampedArrayCid, 16)); + const auto& int16_list = + TypedData::Handle(TypedData::New(kTypedDataInt16ArrayCid, 16)); + const auto& uint16_list = + TypedData::Handle(TypedData::New(kTypedDataUint16ArrayCid, 16)); + const auto& int32_list = + TypedData::Handle(TypedData::New(kTypedDataInt32ArrayCid, 16)); + const auto& uint32_list = + TypedData::Handle(TypedData::New(kTypedDataUint32ArrayCid, 16)); + const auto& int64_list = + TypedData::Handle(TypedData::New(kTypedDataInt64ArrayCid, 16)); + const auto& uint64_list = + TypedData::Handle(TypedData::New(kTypedDataUint64ArrayCid, 16)); + const auto& float32_list = + TypedData::Handle(TypedData::New(kTypedDataFloat32ArrayCid, 16)); + const auto& float64_list = + TypedData::Handle(TypedData::New(kTypedDataFloat64ArrayCid, 16)); + const auto& int8_list = + TypedData::Handle(TypedData::New(kTypedDataInt8ArrayCid, 16)); + const auto& int_value = Integer::Handle(Integer::New(42)); + const auto& float_value = Double::Handle(Double::New(4.2)); + for (intptr_t stage = 0; stage <= kLastStage; ++stage) { + run_test("Uint8List", "int", int8_list, int_value, stage); + run_test("Int8List", "int", uint8_list, int_value, stage); + run_test("Uint8ClampedList", "int", uint8c_list, int_value, stage); + run_test("Int16List", "int", int16_list, int_value, stage); + run_test("Uint16List", "int", uint16_list, int_value, stage); + run_test("Int32List", "int", int32_list, int_value, stage); + run_test("Uint32List", "int", uint32_list, int_value, stage); + run_test("Int64List", "int", int64_list, int_value, stage); + run_test("Uint64List", "int", uint64_list, int_value, stage); + run_test("Float32List", "double", float32_list, float_value, stage); + run_test("Float64List", "double", float64_list, float_value, stage); + } +} + +#endif // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) + +} // namespace dart
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc index d5a4c2d..c141850 100644 --- a/runtime/vm/compiler/call_specializer.cc +++ b/runtime/vm/compiler/call_specializer.cc
@@ -17,6 +17,13 @@ #define I (isolate()) #define Z (zone()) +static void RefineUseTypes(Definition* instr) { + CompileType* new_type = instr->Type(); + for (Value::Iterator it(instr->input_use_list()); !it.Done(); it.Advance()) { + it.Current()->RefineReachingType(new_type); + } +} + static bool ShouldInlineSimd() { return FlowGraphCompiler::SupportsUnboxedSimd128(); } @@ -921,7 +928,7 @@ if (load->slot().nullable_cid() != kDynamicCid) { // Reset value types if we know concrete cid. for (Value::Iterator it(load->input_use_list()); !it.Done(); it.Advance()) { - it.Current()->SetReachingType(NULL); + it.Current()->SetReachingType(nullptr); } } } @@ -1626,5 +1633,261 @@ return true; // May deoptimize since we have not identified all 'true' tests. } +void TypedDataSpecializer::Optimize(FlowGraph* flow_graph) { + TypedDataSpecializer optimizer(flow_graph); + optimizer.VisitBlocks(); +} + +void TypedDataSpecializer::EnsureIsInitialized() { + if (initialized_) return; + + initialized_ = true; + + int_type_ = Type::IntType(); + double_type_ = Type::Double(); + + const auto& typed_data = Library::Handle( + Z, Library::LookupLibrary(thread_, Symbols::DartTypedData())); + + auto& td_class = Class::Handle(Z); + auto& direct_implementors = GrowableObjectArray::Handle(Z); + +#define INIT_HANDLE(iface, member_name, type, cid) \ + td_class = typed_data.LookupClass(Symbols::iface()); \ + ASSERT(!td_class.IsNull()); \ + direct_implementors = td_class.direct_implementors(); \ + if (!HasThirdPartyImplementor(direct_implementors)) { \ + member_name = td_class.RareType(); \ + } + + PUBLIC_TYPED_DATA_CLASS_LIST(INIT_HANDLE) +#undef INIT_HANDLE +} + +bool TypedDataSpecializer::HasThirdPartyImplementor( + const GrowableObjectArray& direct_implementors) { + // Check if there are non internal/external/view implementors. + for (intptr_t i = 0; i < direct_implementors.Length(); ++i) { + implementor_ ^= direct_implementors.At(i); + + // We only consider [implementor_] a 3rd party implementor if it was + // finalized by the class finalizer, since only then can we have concrete + // instances of the [implementor_]. + if (implementor_.is_finalized()) { + const classid_t cid = implementor_.id(); + if (!RawObject::IsTypedDataClassId(cid) && + !RawObject::IsTypedDataViewClassId(cid) && + !RawObject::IsExternalTypedDataClassId(cid)) { + return true; + } + } + } + return false; +} + +void TypedDataSpecializer::VisitInstanceCall(InstanceCallInstr* call) { + TryInlineCall(call); +} + +void TypedDataSpecializer::VisitStaticCall(StaticCallInstr* call) { + TryInlineCall(call); +} + +void TypedDataSpecializer::TryInlineCall(TemplateDartCall<0>* call) { + const bool is_length_getter = call->Selector() == Symbols::GetLength().raw(); + const bool is_index_get = call->Selector() == Symbols::IndexToken().raw(); + const bool is_index_set = + call->Selector() == Symbols::AssignIndexToken().raw(); + + if (is_length_getter || is_index_get || is_index_set) { + EnsureIsInitialized(); + + const intptr_t receiver_index = call->FirstArgIndex(); + + CompileType* receiver_type = call->ArgumentAt(receiver_index + 0)->Type(); + + CompileType* index_type = nullptr; + if (is_index_get || is_index_set) { + index_type = call->ArgumentAt(receiver_index + 1)->Type(); + } + + CompileType* value_type = nullptr; + if (is_index_set) { + value_type = call->ArgumentAt(receiver_index + 2)->Type(); + } + + auto& type_class = Class::Handle(zone_); +#define TRY_INLINE(iface, member_name, type, cid) \ + if (!member_name.IsNull()) { \ + if (receiver_type->IsAssignableTo(member_name)) { \ + if (is_length_getter) { \ + type_class = member_name.type_class(); \ + ReplaceWithLengthGetter(call); \ + } else if (is_index_get) { \ + if (!index_type->IsNullableInt()) return; \ + type_class = member_name.type_class(); \ + ReplaceWithIndexGet(call, cid); \ + } else { \ + if (!index_type->IsNullableInt()) return; \ + if (!value_type->IsAssignableTo(type)) return; \ + type_class = member_name.type_class(); \ + ReplaceWithIndexSet(call, cid); \ + } \ + return; \ + } \ + } + PUBLIC_TYPED_DATA_CLASS_LIST(TRY_INLINE) +#undef INIT_HANDLE + } +} + +void TypedDataSpecializer::ReplaceWithLengthGetter(TemplateDartCall<0>* call) { + const intptr_t receiver_idx = call->FirstArgIndex(); + auto array = call->PushArgumentAt(receiver_idx + 0)->value()->definition(); + + if (array->Type()->is_nullable()) { + AppendNullCheck(call, &array); + } + Definition* length = AppendLoadLength(call, array); + flow_graph_->ReplaceCurrentInstruction(current_iterator(), call, length); + RefineUseTypes(length); +} + +void TypedDataSpecializer::ReplaceWithIndexGet(TemplateDartCall<0>* call, + classid_t cid) { + const intptr_t receiver_idx = call->FirstArgIndex(); + auto array = call->PushArgumentAt(receiver_idx + 0)->value()->definition(); + auto index = call->PushArgumentAt(receiver_idx + 1)->value()->definition(); + + if (array->Type()->is_nullable()) { + AppendNullCheck(call, &array); + } + if (index->Type()->is_nullable()) { + AppendNullCheck(call, &index); + } + AppendBoundsCheck(call, array, &index); + Definition* value = AppendLoadIndexed(call, array, index, cid); + flow_graph_->ReplaceCurrentInstruction(current_iterator(), call, value); + RefineUseTypes(value); +} + +void TypedDataSpecializer::ReplaceWithIndexSet(TemplateDartCall<0>* call, + classid_t cid) { + const intptr_t receiver_idx = call->FirstArgIndex(); + auto array = call->PushArgumentAt(receiver_idx + 0)->value()->definition(); + auto index = call->PushArgumentAt(receiver_idx + 1)->value()->definition(); + auto value = call->PushArgumentAt(receiver_idx + 2)->value()->definition(); + + if (array->Type()->is_nullable()) { + AppendNullCheck(call, &array); + } + if (index->Type()->is_nullable()) { + AppendNullCheck(call, &index); + } + if (value->Type()->is_nullable()) { + AppendNullCheck(call, &value); + } + AppendBoundsCheck(call, array, &index); + AppendStoreIndexed(call, array, index, value, cid); + + RELEASE_ASSERT(!call->HasUses()); + flow_graph_->ReplaceCurrentInstruction(current_iterator(), call, nullptr); +} + +void TypedDataSpecializer::AppendNullCheck(TemplateDartCall<0>* call, + Definition** value) { + auto check = + new (Z) CheckNullInstr(new (Z) Value(*value), Symbols::OptimizedOut(), + call->deopt_id(), call->token_pos()); + flow_graph_->InsertBefore(call, check, call->env(), FlowGraph::kValue); + + // Use data dependency as control dependency. + *value = check; +} + +void TypedDataSpecializer::AppendBoundsCheck(TemplateDartCall<0>* call, + Definition* array, + Definition** index) { + auto length = new (Z) LoadFieldInstr( + new (Z) Value(array), Slot::TypedDataBase_length(), call->token_pos()); + flow_graph_->InsertBefore(call, length, call->env(), FlowGraph::kValue); + + auto check = new (Z) GenericCheckBoundInstr( + new (Z) Value(length), new (Z) Value(*index), DeoptId::kNone); + flow_graph_->InsertBefore(call, check, call->env(), FlowGraph::kValue); + + // Use data dependency as control dependency. + *index = check; +} + +Definition* TypedDataSpecializer::AppendLoadLength(TemplateDartCall<0>* call, + Definition* array) { + auto length = new (Z) LoadFieldInstr( + new (Z) Value(array), Slot::TypedDataBase_length(), call->token_pos()); + flow_graph_->InsertBefore(call, length, call->env(), FlowGraph::kValue); + return length; +} + +Definition* TypedDataSpecializer::AppendLoadIndexed(TemplateDartCall<0>* call, + Definition* array, + Definition* index, + classid_t cid) { + const intptr_t element_size = TypedDataBase::ElementSizeFor(cid); + const intptr_t index_scale = element_size; + + auto data = new (Z) LoadUntaggedInstr(new (Z) Value(array), + TypedDataBase::data_field_offset()); + flow_graph_->InsertBefore(call, data, call->env(), FlowGraph::kValue); + + Definition* load = new (Z) + LoadIndexedInstr(new (Z) Value(data), new (Z) Value(index), index_scale, + cid, kAlignedAccess, DeoptId::kNone, call->token_pos()); + flow_graph_->InsertBefore(call, load, call->env(), FlowGraph::kValue); + + if (cid == kTypedDataFloat32ArrayCid) { + load = new (Z) FloatToDoubleInstr(new (Z) Value(load), call->deopt_id()); + flow_graph_->InsertBefore(call, load, call->env(), FlowGraph::kValue); + } + + return load; +} + +void TypedDataSpecializer::AppendStoreIndexed(TemplateDartCall<0>* call, + Definition* array, + Definition* index, + Definition* value, + classid_t cid) { + const intptr_t element_size = TypedDataBase::ElementSizeFor(cid); + const intptr_t index_scale = element_size; + + const auto deopt_id = call->deopt_id(); + + if (cid == kTypedDataFloat32ArrayCid) { + value = new (Z) DoubleToFloatInstr(new (Z) Value(value), deopt_id, + Instruction::kNotSpeculative); + flow_graph_->InsertBefore(call, value, call->env(), FlowGraph::kValue); + } else if (cid == kTypedDataInt32ArrayCid) { + value = new (Z) + UnboxInt32Instr(UnboxInt32Instr::kTruncate, new (Z) Value(value), + deopt_id, Instruction::kNotSpeculative); + flow_graph_->InsertBefore(call, value, call->env(), FlowGraph::kValue); + } else if (cid == kTypedDataUint32ArrayCid) { + value = new (Z) UnboxUint32Instr(new (Z) Value(value), deopt_id, + Instruction::kNotSpeculative); + ASSERT(value->AsUnboxInteger()->is_truncating()); + flow_graph_->InsertBefore(call, value, call->env(), FlowGraph::kValue); + } + + auto data = new (Z) LoadUntaggedInstr(new (Z) Value(array), + TypedDataBase::data_field_offset()); + flow_graph_->InsertBefore(call, data, call->env(), FlowGraph::kValue); + + auto store = new (Z) StoreIndexedInstr( + new (Z) Value(data), new (Z) Value(index), new (Z) Value(value), + kNoStoreBarrier, index_scale, cid, kAlignedAccess, DeoptId::kNone, + call->token_pos(), Instruction::kNotSpeculative); + flow_graph_->InsertBefore(call, store, call->env(), FlowGraph::kEffect); +} + } // namespace dart #endif // DART_PRECOMPILED_RUNTIME
diff --git a/runtime/vm/compiler/call_specializer.h b/runtime/vm/compiler/call_specializer.h index cb9ca8c..e9a0a6d 100644 --- a/runtime/vm/compiler/call_specializer.h +++ b/runtime/vm/compiler/call_specializer.h
@@ -178,6 +178,106 @@ FlowGraph* flow_graph_; }; +#define PUBLIC_TYPED_DATA_CLASS_LIST(V) \ + V(Int8List, int8_list_type_, int_type_, kTypedDataInt8ArrayCid) \ + V(Uint8List, uint8_list_type_, int_type_, kTypedDataUint8ArrayCid) \ + V(Uint8ClampedList, uint8_clamped_type_, int_type_, \ + kTypedDataUint8ClampedArrayCid) \ + V(Int16List, int16_list_type_, int_type_, kTypedDataInt16ArrayCid) \ + V(Uint16List, uint16_list_type_, int_type_, kTypedDataUint16ArrayCid) \ + V(Int32List, int32_list_type_, int_type_, kTypedDataInt32ArrayCid) \ + V(Uint32List, uint32_list_type_, int_type_, kTypedDataUint32ArrayCid) \ + V(Int64List, int64_list_type_, int_type_, kTypedDataInt64ArrayCid) \ + V(Uint64List, uint64_list_type_, int_type_, kTypedDataUint64ArrayCid) \ + V(Float32List, float32_list_type_, double_type_, kTypedDataFloat32ArrayCid) \ + V(Float64List, float64_list_type_, double_type_, kTypedDataFloat64ArrayCid) + +// Specializes instance/static calls with receiver type being a typed data +// interface (if that interface is only implemented by internal/external/view +// typed data classes). +// +// For example: +// +// foo(Uint8List bytes) => bytes[0]; +// +// Would be translated to something like this: +// +// v0 <- Constant(0) +// +// // Ensures the list is non-null. +// v1 <- ParameterInstr(0) +// v2 <- CheckNull(v1) +// +// // Load the length & perform bounds checks +// v3 <- LoadField(v2, "TypedDataBase.length"); +// v4 <- GenericCheckBounds(v3, v0); +// +// // Directly access the byte, independent of whether `bytes` is +// // _Uint8List, _Uint8ArrayView or _ExternalUint8Array. +// v5 <- LoadUntagged(v1, "TypedDataBase.data"); +// v5 <- LoadIndexed(v5, v4) +// +class TypedDataSpecializer : public FlowGraphVisitor { + public: + static void Optimize(FlowGraph* flow_graph); + + virtual void VisitInstanceCall(InstanceCallInstr* instr); + virtual void VisitStaticCall(StaticCallInstr* instr); + + private: + // clang-format off + explicit TypedDataSpecializer(FlowGraph* flow_graph) + : FlowGraphVisitor(flow_graph->reverse_postorder()), + thread_(Thread::Current()), + zone_(thread_->zone()), + flow_graph_(flow_graph), +#define ALLOCATE_HANDLE(iface, member_name, type, cid) \ + member_name(AbstractType::Handle(zone_)), + PUBLIC_TYPED_DATA_CLASS_LIST(ALLOCATE_HANDLE) +#undef INIT_HANDLE + int_type_(AbstractType::Handle()), + double_type_(AbstractType::Handle()), + implementor_(Class::Handle()) { + } + // clang-format on + + void EnsureIsInitialized(); + bool HasThirdPartyImplementor(const GrowableObjectArray& direct_implementors); + void TryInlineCall(TemplateDartCall<0>* call); + void ReplaceWithLengthGetter(TemplateDartCall<0>* call); + void ReplaceWithIndexGet(TemplateDartCall<0>* call, classid_t cid); + void ReplaceWithIndexSet(TemplateDartCall<0>* call, classid_t cid); + void AppendNullCheck(TemplateDartCall<0>* call, Definition** array); + void AppendBoundsCheck(TemplateDartCall<0>* call, + Definition* array, + Definition** index); + Definition* AppendLoadLength(TemplateDartCall<0>* call, Definition* array); + Definition* AppendLoadIndexed(TemplateDartCall<0>* call, + Definition* array, + Definition* index, + classid_t cid); + void AppendStoreIndexed(TemplateDartCall<0>* call, + Definition* array, + Definition* index, + Definition* value, + classid_t cid); + + Zone* zone() const { return zone_; } + + Thread* thread_; + Zone* zone_; + FlowGraph* flow_graph_; + bool initialized_ = false; + +#define DEF_HANDLE(iface, member_name, type, cid) AbstractType& member_name; + PUBLIC_TYPED_DATA_CLASS_LIST(DEF_HANDLE) +#undef DEF_HANDLE + + AbstractType& int_type_; + AbstractType& double_type_; + Class& implementor_; +}; + } // namespace dart #endif // RUNTIME_VM_COMPILER_CALL_SPECIALIZER_H_
diff --git a/runtime/vm/compiler/compiler_pass.cc b/runtime/vm/compiler/compiler_pass.cc index 9303066..3e08c06 100644 --- a/runtime/vm/compiler/compiler_pass.cc +++ b/runtime/vm/compiler/compiler_pass.cc
@@ -241,6 +241,9 @@ // unreachable code. INVOKE_PASS(ApplyICData); } + if (mode == kAOT) { + INVOKE_PASS(OptimizeTypedDataAccesses); + } #endif INVOKE_PASS(WidenSmiToInt32); INVOKE_PASS(SelectRepresentations); @@ -270,6 +273,14 @@ INVOKE_PASS(ReorderBlocks); } +void CompilerPass::RunPipelineWithPasses( + CompilerPassState* state, + std::initializer_list<CompilerPass::Id> passes) { + for (auto pass_id : passes) { + passes_[pass_id]->Run(state); + } +} + COMPILER_PASS(ComputeSSA, { // Transform to SSA (virtual register 0 and no inlining arguments). flow_graph->ComputeSSA(0, NULL); @@ -363,6 +374,9 @@ ConstantPropagator::OptimizeBranches(flow_graph); }); +COMPILER_PASS(OptimizeTypedDataAccesses, + { TypedDataSpecializer::Optimize(flow_graph); }); + COMPILER_PASS(TryCatchOptimization, { OptimizeCatchEntryStates(flow_graph, /*is_aot=*/FLAG_precompiled_mode); });
diff --git a/runtime/vm/compiler/compiler_pass.h b/runtime/vm/compiler/compiler_pass.h index 044ae6e..e5aa823 100644 --- a/runtime/vm/compiler/compiler_pass.h +++ b/runtime/vm/compiler/compiler_pass.h
@@ -7,6 +7,8 @@ #ifndef DART_PRECOMPILED_RUNTIME +#include <initializer_list> + #include "vm/growable_array.h" #include "vm/token_position.h" #include "vm/zone.h" @@ -34,6 +36,7 @@ V(LICM) \ V(OptimisticallySpecializeSmiPhis) \ V(OptimizeBranches) \ + V(OptimizeTypedDataAccesses) \ V(RangeAnalysis) \ V(ReorderBlocks) \ V(SelectRepresentations) \ @@ -141,6 +144,10 @@ static void RunPipeline(PipelineMode mode, CompilerPassState* state); + static void RunPipelineWithPasses( + CompilerPassState* state, + std::initializer_list<CompilerPass::Id> passes); + protected: // This function executes the pass. If it returns true then // we will run Canonicalize on the graph and execute the pass
diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni index ff5b6ed..f388295 100644 --- a/runtime/vm/compiler/compiler_sources.gni +++ b/runtime/vm/compiler/compiler_sources.gni
@@ -37,6 +37,7 @@ "assembler/disassembler_kbc.h", "assembler/disassembler_x86.cc", "assembler/object_pool_builder.h", + "backend/block_builder.h", "backend/block_scheduler.cc", "backend/block_scheduler.h", "backend/branch_optimizer.cc", @@ -154,10 +155,14 @@ "assembler/assembler_x64_test.cc", "assembler/disassembler_test.cc", "backend/il_test.cc", + "backend/il_test_helper.h", + "backend/il_test_helper.cc", "backend/locations_helpers_test.cc", "backend/loops_test.cc", "backend/range_analysis_test.cc", "backend/redundancy_elimination_test.cc", "backend/slot_test.cc", + "backend/type_propagator_test.cc", + "backend/typed_data_aot_test.cc", "cha_test.cc", ]
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc index c6df1ea..0b6878c 100644 --- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc +++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -7,6 +7,7 @@ #include "vm/compiler/frontend/flow_graph_builder.h" // For InlineExitCollector. #include "vm/compiler/jit/compiler.h" // For Compiler::IsBackgroundCompilation(). #include "vm/compiler/runtime_api.h" +#include "vm/object_store.h" #if !defined(DART_PRECOMPILED_RUNTIME) @@ -406,10 +407,7 @@ Fragment BaseFlowGraphBuilder::PushArgument() { PushArgumentInstr* argument = new (Z) PushArgumentInstr(Pop()); Push(argument); - - argument->set_temp_index(argument->temp_index() - 1); ++pending_argument_count_; - return Fragment(argument); } @@ -549,7 +547,7 @@ LocalVariable* BaseFlowGraphBuilder::MakeTemporary() { char name[64]; intptr_t index = stack_->definition()->temp_index(); - Utils::SNPrint(name, 64, ":temp%" Pd, index); + Utils::SNPrint(name, 64, ":t%" Pd, index); const String& symbol_name = String::ZoneHandle(Z, Symbols::New(thread_, name)); LocalVariable* variable = @@ -557,8 +555,8 @@ symbol_name, Object::dynamic_type()); // Set the index relative to the base of the expression stack including // outgoing arguments. - variable->set_index(VariableIndex(-parsed_function_->num_stack_locals() - - pending_argument_count_ - index)); + variable->set_index( + VariableIndex(-parsed_function_->num_stack_locals() - index)); // The value has uses as if it were a local variable. Mark the definition // as used so that its temp index will not be cleared (causing it to never @@ -688,8 +686,10 @@ return Fragment(instr); } -Fragment BaseFlowGraphBuilder::LoadFpRelativeSlot(intptr_t offset) { - LoadIndexedUnsafeInstr* instr = new (Z) LoadIndexedUnsafeInstr(Pop(), offset); +Fragment BaseFlowGraphBuilder::LoadFpRelativeSlot(intptr_t offset, + CompileType result_type) { + LoadIndexedUnsafeInstr* instr = + new (Z) LoadIndexedUnsafeInstr(Pop(), offset, result_type); Push(instr); return Fragment(instr); } @@ -738,6 +738,18 @@ return Fragment(allocate); } +Fragment BaseFlowGraphBuilder::AllocateClosure( + TokenPosition position, + const Function& closure_function) { + const Class& cls = Class::ZoneHandle(Z, I->object_store()->closure_class()); + ArgumentArray arguments = new (Z) ZoneGrowableArray<PushArgumentInstr*>(Z, 0); + AllocateObjectInstr* allocate = + new (Z) AllocateObjectInstr(position, cls, arguments); + allocate->set_closure_function(closure_function); + Push(allocate); + return Fragment(allocate); +} + Fragment BaseFlowGraphBuilder::CreateArray() { Value* element_count = Pop(); CreateArrayInstr* array =
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h index 21fb118..5eb086b 100644 --- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h +++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -212,7 +212,7 @@ Fragment NullConstant(); Fragment SmiRelationalOp(Token::Kind kind); Fragment SmiBinaryOp(Token::Kind op, bool is_truncating = false); - Fragment LoadFpRelativeSlot(intptr_t offset); + Fragment LoadFpRelativeSlot(intptr_t offset, CompileType result_type); Fragment StoreFpRelativeSlot(intptr_t offset); Fragment BranchIfTrue(TargetEntryInstr** then_entry, TargetEntryInstr** otherwise_entry, @@ -271,6 +271,8 @@ Fragment AssertBool(TokenPosition position); Fragment BooleanNegate(); Fragment AllocateContext(const GrowableArray<LocalVariable*>& scope); + Fragment AllocateClosure(TokenPosition position, + const Function& closure_function); Fragment CreateArray(); Fragment InstantiateType(const AbstractType& type); Fragment InstantiateTypeArguments(const TypeArguments& type_arguments); @@ -280,6 +282,11 @@ // enters the function through the unchecked entry. bool InliningUncheckedEntry() const { return inlining_unchecked_entry_; } + // Returns depth of expression stack. + intptr_t GetStackDepth() const { + return stack_ == nullptr ? 0 : stack_->definition()->temp_index() + 1; + } + protected: intptr_t AllocateBlockId() { return ++last_used_block_id_; }
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc index ca0eb36..03c8fc5 100644 --- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc +++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -288,12 +288,12 @@ intptr_t BytecodeFlowGraphBuilder::GetStackDepth() const { ASSERT(!is_generating_interpreter()); - return B->stack_ == nullptr ? 0 : B->stack_->definition()->temp_index() + 1; + return B->GetStackDepth(); } bool BytecodeFlowGraphBuilder::IsStackEmpty() const { ASSERT(!is_generating_interpreter()); - return B->stack_ == nullptr; + return B->GetStackDepth() == 0; } ArgumentArray BytecodeFlowGraphBuilder::GetArguments(int count) { @@ -327,12 +327,6 @@ return; } - // Stack state propagation is supported for forward branches only. - // Bytecode generation guarantees that expression stack is empty between - // statements and backward jumps are only used to transfer control between - // statements (e.g. in loop and continue statements). - RELEASE_ASSERT(target_pc > pc_); - Value* current_stack = B->stack_; Value* target_stack = stack_states_.Lookup(target_pc); @@ -341,6 +335,8 @@ // all incoming branches. RELEASE_ASSERT(target_stack == current_stack); } else { + // Stack state propagation is supported for forward branches only. + RELEASE_ASSERT(target_pc > pc_); stack_states_.Insert(target_pc, current_stack); } } @@ -632,7 +628,8 @@ store_type_args += B->LoadArgDescriptor(); store_type_args += B->LoadNativeField(Slot::ArgumentsDescriptor_count()); store_type_args += B->LoadFpRelativeSlot( - kWordSize * (1 + compiler::target::frame_layout.param_end_from_fp)); + kWordSize * (1 + compiler::target::frame_layout.param_end_from_fp), + CompileType::CreateNullable(/*is_nullable=*/true, kTypeArgumentsCid)); store_type_args += B->StoreLocalRaw(TokenPosition::kNoSource, type_args_var); store_type_args += B->Drop(); @@ -666,11 +663,15 @@ } const intptr_t loop_depth = DecodeOperandA().value(); if (loop_depth == 0) { + ASSERT(IsStackEmpty()); code_ += B->CheckStackOverflowInPrologue(position_); } else { - code_ += B->CheckStackOverflow(position_, loop_depth); + // Avoid OSR points inside block-expressions with pending stack slots. + // TODO(ajcbik): make sure OSR works for such cases too. + if (IsStackEmpty()) { + code_ += B->CheckStackOverflow(position_, loop_depth); + } } - ASSERT(IsStackEmpty()); } void BytecodeFlowGraphBuilder::BuildPushConstant() { @@ -787,7 +788,9 @@ UNIMPLEMENTED(); // TODO(alexmarkov): interpreter } - const String& name = String::Cast(ConstantAt(DecodeOperandD()).value()); + const Function& interface_target = + Function::Cast(ConstantAt(DecodeOperandD()).value()); + const String& name = String::ZoneHandle(Z, interface_target.name()); ASSERT(name.IsSymbol()); const Array& arg_desc_array = @@ -811,12 +814,10 @@ const ArgumentArray arguments = GetArguments(argc); - // TODO(alexmarkov): store interface_target in bytecode and pass it here. - InstanceCallInstr* call = new (Z) InstanceCallInstr( position_, name, token_kind, arguments, arg_desc.TypeArgsLen(), Array::ZoneHandle(Z, arg_desc.GetArgumentNames()), checked_argument_count, - *ic_data_array_, B->GetNextDeoptId()); + *ic_data_array_, B->GetNextDeoptId(), interface_target); // TODO(alexmarkov): add type info - call->SetResultType() @@ -842,12 +843,12 @@ const ArgumentArray arguments = GetArguments(argc); - // TODO(alexmarkov): store interface_target in bytecode and pass it here. + const Function& interface_target = Function::null_function(); InstanceCallInstr* call = new (Z) InstanceCallInstr( position_, name, token_kind, arguments, arg_desc.TypeArgsLen(), Array::ZoneHandle(Z, arg_desc.GetArgumentNames()), icdata.NumArgsTested(), - *ic_data_array_, icdata.deopt_id()); + *ic_data_array_, icdata.deopt_id(), interface_target); ASSERT(call->ic_data() != nullptr); ASSERT(call->ic_data()->Original() == icdata.raw()); @@ -1631,6 +1632,15 @@ BuildIntOp(Symbols::LessEqualOperator(), Token::kLTE, 2); } +void BytecodeFlowGraphBuilder::BuildAllocateClosure() { + if (is_generating_interpreter()) { + UNIMPLEMENTED(); // TODO(alexmarkov): interpreter + } + + const Function& target = Function::Cast(ConstantAt(DecodeOperandD()).value()); + code_ += B->AllocateClosure(position_, target); +} + static bool IsICDataEntry(const ObjectPool& object_pool, intptr_t index) { if (object_pool.TypeAt(index) != ObjectPool::EntryType::kTaggedObject) { return false; @@ -1824,7 +1834,10 @@ if (join != nullptr) { Value* stack_state = stack_states_.Lookup(pc_); if (code_.is_open()) { - ASSERT((stack_state == nullptr) || (stack_state == B->stack_)); + if (stack_state != B->stack_) { + ASSERT(stack_state == nullptr); + stack_states_.Insert(pc_, B->stack_); + } code_ += B->Goto(join); } else { ASSERT(IsStackEmpty());
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc index 0834b09..6e53e13 100644 --- a/runtime/vm/compiler/frontend/bytecode_reader.cc +++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -474,32 +474,32 @@ // be kept in sync with pkg/vm/lib/bytecode/constant_pool.dart. enum ConstantPoolTag { kInvalid, - kNull, // TODO(alexmarkov): obsolete, remove - kString, // TODO(alexmarkov): obsolete, remove - kInt, // TODO(alexmarkov): obsolete, remove - kDouble, // TODO(alexmarkov): obsolete, remove - kBool, // TODO(alexmarkov): obsolete, remove - kArgDesc, + kUnused1, + kUnused2, + kUnused3, + kUnused4, + kUnused5, + kUnused6, kICData, - kStaticICData, + kUnused7, kStaticField, kInstanceField, kClass, kTypeArgumentsField, - kTearOff, // TODO(alexmarkov): obsolete, remove + kUnused8, kType, - kTypeArguments, // TODO(alexmarkov): obsolete, remove - kList, // TODO(alexmarkov): obsolete, remove - kInstance, // TODO(alexmarkov): obsolete, remove - kTypeArgumentsForInstanceAllocation, // TODO(alexmarkov): obsolete, remove + kUnused9, + kUnused10, + kUnused11, + kUnused12, kClosureFunction, kEndClosureFunctionScope, kNativeEntry, kSubtypeTestCache, - kPartialTearOffInstantiation, // TODO(alexmarkov): obsolete, remove + kUnused13, kEmptyTypeArguments, - kSymbol, // TODO(alexmarkov): obsolete, remove - kInterfaceCallV1, // TODO(alexmarkov): obsolete, remove + kUnused14, + kUnused15, kObjectRef, kDirectCall, kInterfaceCall, @@ -520,9 +520,6 @@ Field& field = Field::Handle(Z); Class& cls = Class::Handle(Z); String& name = String::Handle(Z); - TypeArguments& type_args = TypeArguments::Handle(Z); - Class* symbol_class = nullptr; - Field* symbol_name_field = nullptr; const String* simpleInstanceOf = nullptr; const intptr_t obj_count = pool.Length(); for (intptr_t i = 0; i < obj_count; ++i) { @@ -530,50 +527,6 @@ switch (tag) { case ConstantPoolTag::kInvalid: UNREACHABLE(); - case ConstantPoolTag::kNull: - obj = Object::null(); - break; - case ConstantPoolTag::kString: - obj = ReadString(); - ASSERT(obj.IsString() && obj.IsCanonical()); - break; - case ConstantPoolTag::kInt: { - uint32_t low_bits = helper_->ReadUInt32(); - int64_t value = helper_->ReadUInt32(); - value = (value << 32) | low_bits; - obj = Integer::New(value, Heap::kOld); - obj = H.Canonicalize(Integer::Cast(obj)); - } break; - case ConstantPoolTag::kDouble: { - uint32_t low_bits = helper_->ReadUInt32(); - uint64_t bits = helper_->ReadUInt32(); - bits = (bits << 32) | low_bits; - double value = bit_cast<double, uint64_t>(bits); - obj = Double::New(value, Heap::kOld); - obj = H.Canonicalize(Double::Cast(obj)); - } break; - case ConstantPoolTag::kBool: - if (helper_->ReadByte() == 1) { - obj = Bool::True().raw(); - } else { - obj = Bool::False().raw(); - } - break; - case ConstantPoolTag::kArgDesc: { - intptr_t num_arguments = helper_->ReadUInt(); - intptr_t num_type_args = helper_->ReadUInt(); - intptr_t num_arg_names = helper_->ReadListLength(); - if (num_arg_names == 0) { - obj = ArgumentsDescriptor::New(num_type_args, num_arguments); - } else { - array = Array::New(num_arg_names); - for (intptr_t j = 0; j < num_arg_names; j++) { - name = ReadString(); - array.SetAt(j, name); - } - obj = ArgumentsDescriptor::New(num_type_args, num_arguments, array); - } - } break; case ConstantPoolTag::kICData: { intptr_t flags = helper_->ReadByte(); InvocationKind kind = @@ -614,21 +567,6 @@ H.thread()->compiler_state().GetNextDeoptId(), checked_argument_count, ICData::RebindRule::kInstance); } break; - case ConstantPoolTag::kStaticICData: { - elem = ReadObject(); - ASSERT(elem.IsFunction()); - name = Function::Cast(elem).name(); - const int num_args_checked = - MethodRecognizer::NumArgsCheckedForStaticCall(Function::Cast(elem)); - intptr_t arg_desc_index = helper_->ReadUInt(); - ASSERT(arg_desc_index < i); - array ^= pool.ObjectAt(arg_desc_index); - obj = ICData::New(function, name, - array, // Arguments descriptor. - H.thread()->compiler_state().GetNextDeoptId(), - num_args_checked, ICData::RebindRule::kStatic); - ICData::Cast(obj).AddTarget(Function::Cast(elem)); - } break; case ConstantPoolTag::kStaticField: obj = ReadObject(); ASSERT(obj.IsField()); @@ -654,63 +592,10 @@ cls ^= ReadObject(); obj = Smi::New(cls.type_arguments_field_offset() / kWordSize); break; - case ConstantPoolTag::kTearOff: - obj = ReadObject(); - ASSERT(obj.IsFunction()); - obj = Function::Cast(obj).ImplicitClosureFunction(); - ASSERT(obj.IsFunction()); - obj = Function::Cast(obj).ImplicitStaticClosure(); - ASSERT(obj.IsInstance()); - obj = H.Canonicalize(Instance::Cast(obj)); - break; case ConstantPoolTag::kType: obj = ReadObject(); ASSERT(obj.IsAbstractType()); break; - case ConstantPoolTag::kTypeArguments: - cls = Class::null(); - obj = ReadTypeArguments(cls); - ASSERT(obj.IsNull() || obj.IsTypeArguments()); - break; - case ConstantPoolTag::kList: { - obj = ReadObject(); - ASSERT(obj.IsAbstractType()); - const intptr_t length = helper_->ReadListLength(); - array = Array::New(length, AbstractType::Cast(obj)); - for (intptr_t j = 0; j < length; j++) { - intptr_t elem_index = helper_->ReadUInt(); - ASSERT(elem_index < i); - elem = pool.ObjectAt(elem_index); - array.SetAt(j, elem); - } - array.MakeImmutable(); - obj = H.Canonicalize(Array::Cast(array)); - ASSERT(!obj.IsNull()); - } break; - case ConstantPoolTag::kInstance: { - cls ^= ReadObject(); - obj = Instance::New(cls, Heap::kOld); - intptr_t type_args_index = helper_->ReadUInt(); - ASSERT(type_args_index < i); - type_args ^= pool.ObjectAt(type_args_index); - if (!type_args.IsNull()) { - Instance::Cast(obj).SetTypeArguments(type_args); - } - intptr_t num_fields = helper_->ReadUInt(); - for (intptr_t j = 0; j < num_fields; j++) { - field ^= ReadObject(); - intptr_t elem_index = helper_->ReadUInt(); - ASSERT(elem_index < i); - elem = pool.ObjectAt(elem_index); - Instance::Cast(obj).SetField(field, elem); - } - obj = H.Canonicalize(Instance::Cast(obj)); - } break; - case ConstantPoolTag::kTypeArgumentsForInstanceAllocation: { - cls ^= ReadObject(); - obj = ReadTypeArguments(cls); - ASSERT(obj.IsNull() || obj.IsTypeArguments()); - } break; case ConstantPoolTag::kClosureFunction: { intptr_t closure_index = helper_->ReadUInt(); obj = closures_->At(closure_index); @@ -731,61 +616,9 @@ case ConstantPoolTag::kSubtypeTestCache: { obj = SubtypeTestCache::New(); } break; - case ConstantPoolTag::kPartialTearOffInstantiation: { - intptr_t tearoff_index = helper_->ReadUInt(); - ASSERT(tearoff_index < i); - const Closure& old_closure = - Closure::CheckedHandle(Z, pool.ObjectAt(tearoff_index)); - - intptr_t type_args_index = helper_->ReadUInt(); - ASSERT(type_args_index < i); - type_args ^= pool.ObjectAt(type_args_index); - - obj = Closure::New( - TypeArguments::Handle(Z, old_closure.instantiator_type_arguments()), - TypeArguments::Handle(Z, old_closure.function_type_arguments()), - type_args, Function::Handle(Z, old_closure.function()), - Context::Handle(Z, old_closure.context()), Heap::kOld); - obj = H.Canonicalize(Instance::Cast(obj)); - } break; case ConstantPoolTag::kEmptyTypeArguments: obj = Object::empty_type_arguments().raw(); break; - case ConstantPoolTag::kSymbol: { - name ^= ReadObject(); - ASSERT(name.IsSymbol()); - if (symbol_class == nullptr) { - elem = Library::InternalLibrary(); - ASSERT(!elem.IsNull()); - symbol_class = &Class::Handle( - Z, Library::Cast(elem).LookupClass(Symbols::Symbol())); - ASSERT(!symbol_class->IsNull()); - symbol_name_field = &Field::Handle( - Z, - symbol_class->LookupInstanceFieldAllowPrivate(Symbols::_name())); - ASSERT(!symbol_name_field->IsNull()); - } - obj = Instance::New(*symbol_class, Heap::kOld); - Instance::Cast(obj).SetField(*symbol_name_field, name); - obj = H.Canonicalize(Instance::Cast(obj)); - } break; - case ConstantPoolTag::kInterfaceCallV1: { - helper_->ReadByte(); // TODO(regis): Remove, unneeded. - name ^= ReadObject(); - ASSERT(name.IsSymbol()); - intptr_t arg_desc_index = helper_->ReadUInt(); - ASSERT(arg_desc_index < i); - array ^= pool.ObjectAt(arg_desc_index); - // InterfaceCall constant occupies 2 entries. - // The first entry is used for selector name. - pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject, - ObjectPool::Patchability::kNotPatchable); - pool.SetObjectAt(i, name); - ++i; - ASSERT(i < obj_count); - // The second entry is used for arguments descriptor. - obj = array.raw(); - } break; case ConstantPoolTag::kObjectRef: obj = ReadObject(); break; @@ -805,13 +638,11 @@ case ConstantPoolTag::kInterfaceCall: { elem = ReadObject(); ASSERT(elem.IsFunction()); - name = Function::Cast(elem).name(); - ASSERT(name.IsSymbol()); // InterfaceCall constant occupies 2 entries. - // The first entry is used for selector name. + // The first entry is used for interface target. pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject, ObjectPool::Patchability::kNotPatchable); - pool.SetObjectAt(i, name); + pool.SetObjectAt(i, elem); ++i; ASSERT(i < obj_count); // The second entry is used for arguments descriptor. @@ -1678,12 +1509,16 @@ if (is_static) { field.SetStaticValue(value, true); } else { - // Note: optimizer relies on DoubleInitialized bit in its field-unboxing - // heuristics. See JitCallSpecializer::VisitStoreInstanceField for more - // details. - field.RecordStore(value); - if (value.IsDouble()) { - field.set_is_double_initialized(true); + // Null-initialized instance fields are tracked separately for each + // constructor (see handling of kHasNullableFieldsFlag). + if (!value.IsNull()) { + // Note: optimizer relies on DoubleInitialized bit in its + // field-unboxing heuristics. + // See JitCallSpecializer::VisitStoreInstanceField for more details. + field.RecordStore(value); + if (value.IsDouble()) { + field.set_is_double_initialized(true); + } } } }
diff --git a/runtime/vm/compiler/frontend/constant_evaluator.cc b/runtime/vm/compiler/frontend/constant_evaluator.cc index 002b8f8f..2aba84f 100644 --- a/runtime/vm/compiler/frontend/constant_evaluator.cc +++ b/runtime/vm/compiler/frontend/constant_evaluator.cc
@@ -97,6 +97,7 @@ case kListConcatenation: case kSetConcatenation: case kMapConcatenation: + case kInstanceCreation: // These only occur inside unevaluated constants, so if we decide to // remove support for late evaluation of environment constants from // dill files in the VM, an implementation here will not be necessary. @@ -1037,7 +1038,8 @@ if (!IsBuildingFlowGraph()) return false; const Function& function = flow_graph_builder_->parsed_function_->function(); - if (function.kind() == RawFunction::kImplicitStaticFinalGetter) { + if (function.kind() == RawFunction::kImplicitStaticFinalGetter && + !I->CanOptimizeImmediately()) { // Don't cache constants in initializer expressions. They get // evaluated only once. return false; @@ -1068,7 +1070,8 @@ if (!IsBuildingFlowGraph()) return; const Function& function = flow_graph_builder_->parsed_function_->function(); - if (function.kind() == RawFunction::kImplicitStaticFinalGetter) { + if (function.kind() == RawFunction::kImplicitStaticFinalGetter && + !I->CanOptimizeImmediately()) { // Don't cache constants in initializer expressions. They get // evaluated only once. return;
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc index 83a9d2a..6f326e7 100644 --- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc +++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -1159,8 +1159,9 @@ case kListConcatenation: case kSetConcatenation: case kMapConcatenation: - // Collection concatenation operations are removed by the constant - // evaluator. + case kInstanceCreation: + // Collection concatenation and instance creation operations are removed + // by the constant evaluator. UNREACHABLE(); break; case kIsExpression: @@ -1624,12 +1625,6 @@ return flow_graph_builder_->AllocateObject(position, klass, argument_count); } -Fragment StreamingFlowGraphBuilder::AllocateObject( - const Class& klass, - const Function& closure_function) { - return flow_graph_builder_->AllocateObject(klass, closure_function); -} - Fragment StreamingFlowGraphBuilder::AllocateContext( const GrowableArray<LocalVariable*>& context_variables) { return flow_graph_builder_->AllocateContext(context_variables); @@ -4135,7 +4130,7 @@ // Avoid OSR point inside block-expressions. // TODO(ajcbik): make sure OSR works inside BE too - if (block_expression_depth() == 0) loop += CheckStackOverflow(position); + if (B->GetStackDepth() == 0) loop += CheckStackOverflow(position); if (condition.entry != nullptr) { loop <<= condition.entry; @@ -4212,7 +4207,7 @@ // Avoid OSR point inside block-expressions. // TODO(ajcbik): make sure OSR works inside BE too - if (block_expression_depth() == 0) loop += CheckStackOverflow(position); + if (B->GetStackDepth() == 0) loop += CheckStackOverflow(position); loop += condition; } else { @@ -4955,11 +4950,8 @@ function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kEnd); - const Class& closure_class = - Class::ZoneHandle(Z, I->object_store()->closure_class()); - ASSERT(!closure_class.IsNull()); Fragment instructions = - flow_graph_builder_->AllocateObject(closure_class, function); + flow_graph_builder_->AllocateClosure(TokenPosition::kNoSource, function); LocalVariable* closure = MakeTemporary(); // The function signature can have uninstantiated class type parameters.
diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc index 1a88f1ba..be15d45 100644 --- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc +++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
@@ -450,8 +450,9 @@ case kListConcatenation: case kSetConcatenation: case kMapConcatenation: - // Collection concatenation operations are removed by the constant - // evaluator. + case kInstanceCreation: + // Collection concatenation and instance creation operations are removed + // by the constant evaluator. UNREACHABLE(); break; case kIsExpression:
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc index b7b19a9..713139f 100644 --- a/runtime/vm/compiler/frontend/kernel_to_il.cc +++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -224,16 +224,6 @@ return Fragment(allocate); } -Fragment FlowGraphBuilder::AllocateObject(const Class& klass, - const Function& closure_function) { - ArgumentArray arguments = new (Z) ZoneGrowableArray<PushArgumentInstr*>(Z, 0); - AllocateObjectInstr* allocate = - new (Z) AllocateObjectInstr(TokenPosition::kNoSource, klass, arguments); - allocate->set_closure_function(closure_function); - Push(allocate); - return Fragment(allocate); -} - Fragment FlowGraphBuilder::CatchBlockEntry(const Array& handler_types, intptr_t handler_index, bool needs_stacktrace, @@ -367,7 +357,12 @@ } if (call_site_attrs != nullptr && call_site_attrs->receiver_type != nullptr && call_site_attrs->receiver_type->IsInstantiated()) { - call->set_static_receiver_type(call_site_attrs->receiver_type); + call->set_receivers_static_type(call_site_attrs->receiver_type); + } else if (!interface_target.IsNull()) { + const Class& owner = Class::Handle(Z, interface_target.Owner()); + const AbstractType& type = + AbstractType::ZoneHandle(Z, owner.DeclarationType()); + call->set_receivers_static_type(&type); } Push(call); return Fragment(call); @@ -1068,9 +1063,7 @@ Fragment FlowGraphBuilder::BuildImplicitClosureCreation( const Function& target) { Fragment fragment; - const Class& closure_class = - Class::ZoneHandle(Z, I->object_store()->closure_class()); - fragment += AllocateObject(closure_class, target); + fragment += AllocateClosure(TokenPosition::kNoSource, target); LocalVariable* closure = MakeTemporary(); // The function signature can have uninstantiated class type parameters. @@ -1773,7 +1766,8 @@ loop_body += LoadLocal(index); loop_body += SmiBinaryOp(Token::kSUB, /*truncate=*/true); loop_body += LoadFpRelativeSlot( - kWordSize * compiler::target::frame_layout.param_end_from_fp); + kWordSize * compiler::target::frame_layout.param_end_from_fp, + CompileType::Dynamic()); loop_body += StoreIndexed(kArrayCid); // ++i
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h index 4355383..c7fb8da 100644 --- a/runtime/vm/compiler/frontend/kernel_to_il.h +++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -125,7 +125,6 @@ Fragment AllocateObject(TokenPosition position, const Class& klass, intptr_t argument_count); - Fragment AllocateObject(const Class& klass, const Function& closure_function); Fragment CatchBlockEntry(const Array& handler_types, intptr_t handler_index, bool needs_stacktrace,
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc index 5fd9a77..971ac05 100644 --- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc +++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -2237,8 +2237,9 @@ case kListConcatenation: case kSetConcatenation: case kMapConcatenation: - // Collection concatenation operations are removed by the constant - // evaluator. + case kInstanceCreation: + // Collection concatenation and instance creation operations are removed + // by the constant evaluator. UNREACHABLE(); break; case kIsExpression:
diff --git a/runtime/vm/compiler/frontend/prologue_builder.cc b/runtime/vm/compiler/frontend/prologue_builder.cc index 3c5103c..deb29dc 100644 --- a/runtime/vm/compiler/frontend/prologue_builder.cc +++ b/runtime/vm/compiler/frontend/prologue_builder.cc
@@ -21,6 +21,14 @@ #define Z (zone_) +// Returns static type of the parameter if it can be trusted (was type checked +// by caller) and dynamic otherwise. +static CompileType ParameterType(LocalVariable* param) { + return param->was_type_checked_by_caller() + ? CompileType::FromAbstractType(param->type()) + : CompileType::Dynamic(); +} + bool PrologueBuilder::PrologueSkippableOnUncheckedEntry( const Function& function) { return !function.HasOptionalParameters() && @@ -182,7 +190,8 @@ copy_args_prologue += LoadLocal(optional_count_var); copy_args_prologue += LoadFpRelativeSlot( kWordSize * (compiler::target::frame_layout.param_end_from_fp + - num_fixed_params - param)); + num_fixed_params - param), + ParameterType(ParameterVariable(param))); copy_args_prologue += StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param)); copy_args_prologue += Drop(); @@ -202,7 +211,8 @@ good += LoadLocal(optional_count_var); good += LoadFpRelativeSlot( kWordSize * (compiler::target::frame_layout.param_end_from_fp + - num_fixed_params - param)); + num_fixed_params - param), + ParameterType(ParameterVariable(param))); good += StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param)); good += Drop(); @@ -300,7 +310,8 @@ } good += SmiBinaryOp(Token::kSUB, /* truncate= */ true); good += LoadFpRelativeSlot( - kWordSize * compiler::target::frame_layout.param_end_from_fp); + kWordSize * compiler::target::frame_layout.param_end_from_fp, + ParameterType(ParameterVariable(opt_param_position[i]))); // Copy down. good += StoreLocalRaw(TokenPosition::kNoSource, @@ -405,7 +416,8 @@ store_type_args += LoadArgDescriptor(); store_type_args += LoadNativeField(Slot::ArgumentsDescriptor_count()); store_type_args += LoadFpRelativeSlot( - kWordSize * (1 + compiler::target::frame_layout.param_end_from_fp)); + kWordSize * (1 + compiler::target::frame_layout.param_end_from_fp), + CompileType::CreateNullable(/*is_nullable=*/true, kTypeArgumentsCid)); store_type_args += StoreLocal(TokenPosition::kNoSource, type_args_var); store_type_args += Drop();
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc index e23bf10..ea837d5 100644 --- a/runtime/vm/compiler/frontend/scope_builder.cc +++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -765,8 +765,9 @@ case kListConcatenation: case kSetConcatenation: case kMapConcatenation: - // Collection concatenation operations are removed by the constant - // evaluator. + case kInstanceCreation: + // Collection concatenation and instance creation operations are removed + // by the constant evaluator. UNREACHABLE(); break; case kIsExpression:
diff --git a/runtime/vm/compiler/graph_intrinsifier.cc b/runtime/vm/compiler/graph_intrinsifier.cc index 1b2f8e8..85b9e11 100644 --- a/runtime/vm/compiler/graph_intrinsifier.cc +++ b/runtime/vm/compiler/graph_intrinsifier.cc
@@ -7,6 +7,7 @@ #if !defined(DART_PRECOMPILED_RUNTIME) && !defined(TARGET_ARCH_DBC) #include "vm/compiler/graph_intrinsifier.h" +#include "vm/compiler/backend/block_builder.h" #include "vm/compiler/backend/flow_graph.h" #include "vm/compiler/backend/flow_graph_compiler.h" #include "vm/compiler/backend/il.h" @@ -115,24 +116,6 @@ return true; } -static intptr_t CidForRepresentation(Representation rep) { - switch (rep) { - case kUnboxedDouble: - return kDoubleCid; - case kUnboxedFloat32x4: - return kFloat32x4Cid; - case kUnboxedInt32x4: - return kInt32x4Cid; - case kUnboxedFloat64x2: - return kFloat64x2Cid; - case kUnboxedUint32: - return kDynamicCid; // smi or mint. - default: - UNREACHABLE(); - return kIllegalCid; - } -} - static Representation RepresentationForCid(intptr_t cid) { switch (cid) { case kDoubleCid: @@ -154,100 +137,6 @@ // IR instructions which would jump to a deoptimization sequence on failure // instead branch to the intrinsic slow path. // -class BlockBuilder : public ValueObject { - public: - BlockBuilder(FlowGraph* flow_graph, BlockEntryInstr* entry) - : flow_graph_(flow_graph), - entry_(entry), - current_(entry), - fall_through_env_(new Environment(0, - 0, - flow_graph->parsed_function(), - NULL)) {} - - Definition* AddToInitialDefinitions(Definition* def) { - def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); - auto normal_entry = flow_graph_->graph_entry()->normal_entry(); - flow_graph_->AddToInitialDefinitions(normal_entry, def); - return def; - } - - Definition* AddDefinition(Definition* def) { - def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); - AddInstruction(def); - return def; - } - - Instruction* AddInstruction(Instruction* instr) { - if (instr->ComputeCanDeoptimize()) { - // Since we use the presence of an environment to determine if an - // instructions can deoptimize, we need an empty environment for - // instructions that "deoptimize" to the intrinsic fall-through code. - instr->SetEnvironment(fall_through_env_); - } - current_ = current_->AppendInstruction(instr); - return instr; - } - - void AddIntrinsicReturn(Value* value) { - ReturnInstr* instr = new ReturnInstr( - TokenPos(), value, CompilerState::Current().GetNextDeoptId()); - AddInstruction(instr); - entry_->set_last_instruction(instr); - } - - Definition* AddParameter(intptr_t index) { - intptr_t adjustment = GraphIntrinsifier::ParameterSlotFromSp(); - return AddToInitialDefinitions(new ParameterInstr( - adjustment + index, flow_graph_->graph_entry(), SPREG)); - } - - TokenPosition TokenPos() { return flow_graph_->function().token_pos(); } - - Definition* AddNullDefinition() { - return AddDefinition(new ConstantInstr(Object::ZoneHandle(Object::null()))); - } - - Definition* AddUnboxInstr(Representation rep, Value* value, bool is_checked) { - Definition* unboxed_value = - AddDefinition(UnboxInstr::Create(rep, value, DeoptId::kNone)); - if (is_checked) { - // The type of |value| has already been checked and it is safe to - // adjust reaching type. This is done manually because there is no type - // propagation when building intrinsics. - unboxed_value->AsUnbox()->value()->SetReachingType( - new CompileType(CompileType::FromCid(CidForRepresentation(rep)))); - } - return unboxed_value; - } - - Definition* AddUnboxInstr(Representation rep, - Definition* boxed, - bool is_checked) { - return AddUnboxInstr(rep, new Value(boxed), is_checked); - } - - Definition* InvokeMathCFunction(MethodRecognizer::Kind recognized_kind, - ZoneGrowableArray<Value*>* args) { - return InvokeMathCFunctionHelper(recognized_kind, args); - } - - private: - Definition* InvokeMathCFunctionHelper(MethodRecognizer::Kind recognized_kind, - ZoneGrowableArray<Value*>* args) { - InvokeMathCFunctionInstr* invoke_math_c_function = - new InvokeMathCFunctionInstr(args, DeoptId::kNone, recognized_kind, - TokenPos()); - AddDefinition(invoke_math_c_function); - return invoke_math_c_function; - } - - FlowGraph* flow_graph_; - BlockEntryInstr* entry_; - Instruction* current_; - Environment* fall_through_env_; -}; - static Definition* PrepareIndexedOp(FlowGraph* flow_graph, BlockBuilder* builder, Definition* array, @@ -269,8 +158,8 @@ auto normal_entry = graph_entry->normal_entry(); BlockBuilder builder(flow_graph, normal_entry); - Definition* index = builder.AddParameter(1); - Definition* array = builder.AddParameter(2); + Definition* index = builder.AddParameter(0, /*with_frame=*/false); + Definition* array = builder.AddParameter(1, /*with_frame=*/false); index = PrepareIndexedOp(flow_graph, &builder, array, index, Slot::GetLengthFieldForArrayCid(array_cid)); @@ -336,7 +225,7 @@ UNREACHABLE(); break; } - builder.AddIntrinsicReturn(new Value(result)); + builder.AddReturn(new Value(result)); return true; } @@ -346,9 +235,9 @@ auto normal_entry = graph_entry->normal_entry(); BlockBuilder builder(flow_graph, normal_entry); - Definition* value = builder.AddParameter(1); - Definition* index = builder.AddParameter(2); - Definition* array = builder.AddParameter(3); + Definition* value = builder.AddParameter(0, /*with_frame=*/false); + Definition* index = builder.AddParameter(1, /*with_frame=*/false); + Definition* array = builder.AddParameter(2, /*with_frame=*/false); index = PrepareIndexedOp(flow_graph, &builder, array, index, Slot::GetLengthFieldForArrayCid(array_cid)); @@ -434,7 +323,7 @@ array_cid, kAlignedAccess, DeoptId::kNone, builder.TokenPos())); // Return null. Definition* null_def = builder.AddNullDefinition(); - builder.AddIntrinsicReturn(new Value(null_def)); + builder.AddReturn(new Value(null_def)); return true; } @@ -549,8 +438,8 @@ auto normal_entry = graph_entry->normal_entry(); BlockBuilder builder(flow_graph, normal_entry); - Definition* index = builder.AddParameter(1); - Definition* str = builder.AddParameter(2); + Definition* index = builder.AddParameter(0, /*with_frame=*/false); + Definition* str = builder.AddParameter(1, /*with_frame=*/false); index = PrepareIndexedOp(flow_graph, &builder, str, index, Slot::String_length()); @@ -567,7 +456,7 @@ Definition* result = builder.AddDefinition(new LoadIndexedInstr( new Value(str), new Value(index), Instance::ElementSizeFor(cid), cid, kAlignedAccess, DeoptId::kNone, builder.TokenPos())); - builder.AddIntrinsicReturn(new Value(result)); + builder.AddReturn(new Value(result)); return true; } @@ -599,8 +488,8 @@ auto normal_entry = graph_entry->normal_entry(); BlockBuilder builder(flow_graph, normal_entry); - Definition* right = builder.AddParameter(1); - Definition* left = builder.AddParameter(2); + Definition* right = builder.AddParameter(0, /*with_frame=*/false); + Definition* left = builder.AddParameter(1, /*with_frame=*/false); Cids* value_check = Cids::CreateMonomorphic(zone, cid); // Check argument. Receiver (left) is known to be a Float32x4. @@ -617,7 +506,7 @@ new Value(right_simd), DeoptId::kNone)); Definition* result = builder.AddDefinition(BoxInstr::Create(rep, new Value(unboxed_result))); - builder.AddIntrinsicReturn(new Value(result)); + builder.AddReturn(new Value(result)); return true; } @@ -643,7 +532,7 @@ auto normal_entry = graph_entry->normal_entry(); BlockBuilder builder(flow_graph, normal_entry); - Definition* receiver = builder.AddParameter(1); + Definition* receiver = builder.AddParameter(0, /*with_frame=*/false); Definition* unboxed_receiver = builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(receiver), @@ -654,7 +543,7 @@ Definition* result = builder.AddDefinition( BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result))); - builder.AddIntrinsicReturn(new Value(result)); + builder.AddReturn(new Value(result)); return true; } @@ -683,11 +572,11 @@ auto normal_entry = graph_entry->normal_entry(); BlockBuilder builder(flow_graph, normal_entry); - Definition* array = builder.AddParameter(1); + Definition* array = builder.AddParameter(0, /*with_frame=*/false); Definition* length = builder.AddDefinition( new LoadFieldInstr(new Value(array), field, builder.TokenPos())); - builder.AddIntrinsicReturn(new Value(length)); + builder.AddReturn(new Value(length)); return true; } @@ -724,13 +613,13 @@ auto normal_entry = graph_entry->normal_entry(); BlockBuilder builder(flow_graph, normal_entry); - Definition* array = builder.AddParameter(1); + Definition* array = builder.AddParameter(0, /*with_frame=*/false); Definition* backing_store = builder.AddDefinition(new LoadFieldInstr( new Value(array), Slot::GrowableObjectArray_data(), builder.TokenPos())); Definition* capacity = builder.AddDefinition(new LoadFieldInstr( new Value(backing_store), Slot::Array_length(), builder.TokenPos())); - builder.AddIntrinsicReturn(new Value(capacity)); + builder.AddReturn(new Value(capacity)); return true; } @@ -739,8 +628,8 @@ auto normal_entry = graph_entry->normal_entry(); BlockBuilder builder(flow_graph, normal_entry); - Definition* index = builder.AddParameter(1); - Definition* growable_array = builder.AddParameter(2); + Definition* index = builder.AddParameter(0, /*with_frame=*/false); + Definition* growable_array = builder.AddParameter(1, /*with_frame=*/false); index = PrepareIndexedOp(flow_graph, &builder, growable_array, index, Slot::GrowableObjectArray_length()); @@ -752,7 +641,7 @@ new Value(backing_store), new Value(index), Instance::ElementSizeFor(kArrayCid), // index scale kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos())); - builder.AddIntrinsicReturn(new Value(result)); + builder.AddReturn(new Value(result)); return true; } @@ -770,9 +659,9 @@ auto normal_entry = graph_entry->normal_entry(); BlockBuilder builder(flow_graph, normal_entry); - Definition* value = builder.AddParameter(1); - Definition* index = builder.AddParameter(2); - Definition* array = builder.AddParameter(3); + Definition* value = builder.AddParameter(0, /*with_frame=*/false); + Definition* index = builder.AddParameter(1, /*with_frame=*/false); + Definition* array = builder.AddParameter(2, /*with_frame=*/false); index = PrepareIndexedOp(flow_graph, &builder, array, index, Slot::Array_length()); @@ -783,7 +672,7 @@ kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos())); // Return null. Definition* null_def = builder.AddNullDefinition(); - builder.AddIntrinsicReturn(new Value(null_def)); + builder.AddReturn(new Value(null_def)); return true; } @@ -801,9 +690,9 @@ auto normal_entry = graph_entry->normal_entry(); BlockBuilder builder(flow_graph, normal_entry); - Definition* value = builder.AddParameter(1); - Definition* index = builder.AddParameter(2); - Definition* array = builder.AddParameter(3); + Definition* value = builder.AddParameter(0, /*with_frame=*/false); + Definition* index = builder.AddParameter(1, /*with_frame=*/false); + Definition* array = builder.AddParameter(2, /*with_frame=*/false); index = PrepareIndexedOp(flow_graph, &builder, array, index, Slot::GrowableObjectArray_length()); @@ -818,7 +707,7 @@ kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos())); // Return null. Definition* null_def = builder.AddNullDefinition(); - builder.AddIntrinsicReturn(new Value(null_def)); + builder.AddReturn(new Value(null_def)); return true; } @@ -827,8 +716,8 @@ auto normal_entry = graph_entry->normal_entry(); BlockBuilder builder(flow_graph, normal_entry); - Definition* data = builder.AddParameter(1); - Definition* growable_array = builder.AddParameter(2); + Definition* data = builder.AddParameter(0, /*with_frame=*/false); + Definition* growable_array = builder.AddParameter(1, /*with_frame=*/false); Zone* zone = flow_graph->zone(); Cids* value_check = Cids::CreateMonomorphic(zone, kArrayCid); @@ -840,7 +729,7 @@ new Value(data), kEmitStoreBarrier, builder.TokenPos())); // Return null. Definition* null_def = builder.AddNullDefinition(); - builder.AddIntrinsicReturn(new Value(null_def)); + builder.AddReturn(new Value(null_def)); return true; } @@ -849,8 +738,8 @@ auto normal_entry = graph_entry->normal_entry(); BlockBuilder builder(flow_graph, normal_entry); - Definition* length = builder.AddParameter(1); - Definition* growable_array = builder.AddParameter(2); + Definition* length = builder.AddParameter(0, /*with_frame=*/false); + Definition* growable_array = builder.AddParameter(1, /*with_frame=*/false); builder.AddInstruction( new CheckSmiInstr(new Value(length), DeoptId::kNone, builder.TokenPos())); @@ -858,7 +747,7 @@ Slot::GrowableObjectArray_length(), new Value(growable_array), new Value(length), kNoStoreBarrier, builder.TokenPos())); Definition* null_def = builder.AddNullDefinition(); - builder.AddIntrinsicReturn(new Value(null_def)); + builder.AddReturn(new Value(null_def)); return true; } @@ -870,7 +759,7 @@ auto normal_entry = graph_entry->normal_entry(); BlockBuilder builder(flow_graph, normal_entry); - Definition* receiver = builder.AddParameter(1); + Definition* receiver = builder.AddParameter(0, /*with_frame=*/false); Definition* unboxed_value = builder.AddUnboxInstr(kUnboxedDouble, new Value(receiver), /* is_checked = */ true); @@ -878,7 +767,7 @@ Token::kNEGATE, new Value(unboxed_value), DeoptId::kNone)); Definition* result = builder.AddDefinition( BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result))); - builder.AddIntrinsicReturn(new Value(result)); + builder.AddReturn(new Value(result)); return true; } @@ -892,19 +781,21 @@ new ZoneGrowableArray<Value*>(num_parameters); for (intptr_t i = 0; i < num_parameters; i++) { - const intptr_t parameter_index = (num_parameters - i); - Definition* value = builder->AddParameter(parameter_index); + const intptr_t parameter_index = (num_parameters - i - 1); + Definition* value = + builder->AddParameter(parameter_index, /*with_frame=*/false); Definition* unboxed_value = builder->AddUnboxInstr(kUnboxedDouble, value, /* is_checked = */ false); args->Add(new Value(unboxed_value)); } - Definition* unboxed_result = builder->InvokeMathCFunction(kind, args); - + Definition* unboxed_result = + builder->AddDefinition(new InvokeMathCFunctionInstr( + args, DeoptId::kNone, kind, builder->TokenPos())); Definition* result = builder->AddDefinition( BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result))); - builder->AddIntrinsicReturn(new Value(result)); + builder->AddReturn(new Value(result)); return true; }
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc index b7afea4..412e6b0 100644 --- a/runtime/vm/compiler/jit/compiler.cc +++ b/runtime/vm/compiler/jit/compiler.cc
@@ -271,6 +271,14 @@ // so do not optimize the function. Bump usage counter down to avoid // repeatedly entering the runtime for an optimization attempt. function.SetUsageCounter(0); + + // If the optimization counter = 1, the unoptimized code will come back here + // immediately, causing an infinite compilation loop. The compiler raises + // the threshold for functions with breakpoints, so we drop the unoptimized + // to force it to be recompiled. + if (thread->isolate()->CanOptimizeImmediately()) { + function.ClearCode(); + } return false; } #endif @@ -361,7 +369,7 @@ RawCode* FinalizeCompilation(Assembler* assembler, FlowGraphCompiler* graph_compiler, FlowGraph* flow_graph); - void CheckIfBackgroundCompilerIsBeingStopped(); + void CheckIfBackgroundCompilerIsBeingStopped(bool optimizing_compiler); ParsedFunction* parsed_function_; const bool optimized_; @@ -556,12 +564,22 @@ return code.raw(); } -void CompileParsedFunctionHelper::CheckIfBackgroundCompilerIsBeingStopped() { +void CompileParsedFunctionHelper::CheckIfBackgroundCompilerIsBeingStopped( + bool optimizing_compiler) { ASSERT(Compiler::IsBackgroundCompilation()); - if (!isolate()->background_compiler()->is_running()) { - // The background compiler is being stopped. - Compiler::AbortBackgroundCompilation( - DeoptId::kNone, "Background compilation is being stopped"); + if (optimizing_compiler) { + if (!isolate()->optimizing_background_compiler()->is_running()) { + // The background compiler is being stopped. + Compiler::AbortBackgroundCompilation( + DeoptId::kNone, "Optimizing Background compilation is being stopped"); + } + } else { + if (FLAG_enable_interpreter && + !isolate()->background_compiler()->is_running()) { + // The background compiler is being stopped. + Compiler::AbortBackgroundCompilation( + DeoptId::kNone, "Background compilation is being stopped"); + } } } @@ -708,12 +726,12 @@ // changes code page access permissions (makes them temporary not // executable). { - CheckIfBackgroundCompilerIsBeingStopped(); + CheckIfBackgroundCompilerIsBeingStopped(optimized()); SafepointOperationScope safepoint_scope(thread()); // Do not Garbage collect during this stage and instead allow the // heap to grow. NoHeapGrowthControlScope no_growth_control; - CheckIfBackgroundCompilerIsBeingStopped(); + CheckIfBackgroundCompilerIsBeingStopped(optimized()); *result = FinalizeCompilation(&assembler, &graph_compiler, flow_graph); } @@ -757,18 +775,18 @@ if (FLAG_trace_bailout) { THR_Print("%s\n", error.ToErrorCString()); } + if (!Compiler::IsBackgroundCompilation() && error.IsLanguageError() && + (LanguageError::Cast(error).kind() == Report::kBailout)) { + // If is is not a background compilation, discard the error if it was + // not a real error, but just a bailout. If we're it a background + // compilation this will be dealt with in the caller. + } else { + // Otherwise, continue propagating unless we will try again. + thread()->set_sticky_error(error); + } done = true; } - if (!Compiler::IsBackgroundCompilation() && error.IsLanguageError() && - (LanguageError::Cast(error).kind() == Report::kBailout)) { - // If is is not a background compilation, discard the error if it was - // not a real error, but just a bailout. If we're it a background - // compilation this will be dealt with in the caller. - } else { - // Otherwise, continue propagating. - thread()->set_sticky_error(error); - } } } return result->raw(); @@ -1474,7 +1492,7 @@ } } -void BackgroundCompiler::CompileOptimized(const Function& function) { +void BackgroundCompiler::Compile(const Function& function) { ASSERT(Thread::Current()->IsMutatorThread()); // TODO(srdjan): Checking different strategy for collecting garbage // accumulated by background compiler. @@ -1516,18 +1534,6 @@ ASSERT(thread->IsMutatorThread()); ASSERT(!thread->IsAtSafepoint()); - // Finalize NoSuchMethodError, _Mint; occasionally needed in optimized - // compilation. - Class& cls = Class::Handle( - thread->zone(), Library::LookupCoreClass(Symbols::NoSuchMethodError())); - ASSERT(!cls.IsNull()); - Error& error = Error::Handle(thread->zone(), cls.EnsureIsFinalized(thread)); - ASSERT(error.IsNull()); - cls = Library::LookupCoreClass(Symbols::_Mint()); - ASSERT(!cls.IsNull()); - error = cls.EnsureIsFinalized(thread); - ASSERT(error.IsNull()); - MonitorLocker ml(done_monitor_); if (running_ || !done_) return; running_ = true; @@ -1653,7 +1659,7 @@ UNREACHABLE(); } -void BackgroundCompiler::CompileOptimized(const Function& function) { +void BackgroundCompiler::Compile(const Function& function) { UNREACHABLE(); }
diff --git a/runtime/vm/compiler/jit/compiler.h b/runtime/vm/compiler/jit/compiler.h index eef93a8..c7e6412 100644 --- a/runtime/vm/compiler/jit/compiler.h +++ b/runtime/vm/compiler/jit/compiler.h
@@ -157,46 +157,57 @@ static void Start(Isolate* isolate) { ASSERT(Thread::Current()->IsMutatorThread()); - if (isolate->background_compiler() != NULL) { + if (FLAG_enable_interpreter && isolate->background_compiler() != NULL) { isolate->background_compiler()->Start(); } + if (isolate->optimizing_background_compiler() != NULL) { + isolate->optimizing_background_compiler()->Start(); + } } static void Stop(Isolate* isolate) { ASSERT(Thread::Current()->IsMutatorThread()); - if (isolate->background_compiler() != NULL) { + if (FLAG_enable_interpreter && isolate->background_compiler() != NULL) { isolate->background_compiler()->Stop(); } + if (isolate->optimizing_background_compiler() != NULL) { + isolate->optimizing_background_compiler()->Stop(); + } } static void Enable(Isolate* isolate) { ASSERT(Thread::Current()->IsMutatorThread()); - if (isolate->background_compiler() != NULL) { + if (FLAG_enable_interpreter && isolate->background_compiler() != NULL) { isolate->background_compiler()->Enable(); } + if (isolate->optimizing_background_compiler() != NULL) { + isolate->optimizing_background_compiler()->Enable(); + } } static void Disable(Isolate* isolate) { ASSERT(Thread::Current()->IsMutatorThread()); - if (isolate->background_compiler() != NULL) { + if (FLAG_enable_interpreter && isolate->background_compiler() != NULL) { isolate->background_compiler()->Disable(); } - } - static bool IsDisabled(Isolate* isolate) { - ASSERT(Thread::Current()->IsMutatorThread()); - if (isolate->background_compiler() != NULL) { - return isolate->background_compiler()->IsDisabled(); + if (isolate->optimizing_background_compiler() != NULL) { + isolate->optimizing_background_compiler()->Disable(); } - return false; } - static bool IsRunning(Isolate* isolate) { + static bool IsDisabled(Isolate* isolate, bool optimizing_compiler) { ASSERT(Thread::Current()->IsMutatorThread()); - if (isolate->background_compiler() != NULL) { - return isolate->background_compiler()->IsRunning(); + if (optimizing_compiler) { + if (isolate->optimizing_background_compiler() != NULL) { + return isolate->optimizing_background_compiler()->IsDisabled(); + } + } else { + if (FLAG_enable_interpreter && isolate->background_compiler() != NULL) { + return isolate->background_compiler()->IsDisabled(); + } } return false; } - // Call to optimize a function in the background, enters the function in the - // compilation queue. - void CompileOptimized(const Function& function); + // Call to compile (unoptimized or optimized) a function in the background, + // enters the function in the compilation queue. + void Compile(const Function& function); void VisitPointers(ObjectPointerVisitor* visitor);
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc index 9020925..ae05577 100644 --- a/runtime/vm/compiler/runtime_api.cc +++ b/runtime/vm/compiler/runtime_api.cc
@@ -348,8 +348,8 @@ return dart::ICData::entries_offset(); } -word ICData::static_receiver_type_offset() { - return dart::ICData::static_receiver_type_offset(); +word ICData::receivers_static_type_offset() { + return dart::ICData::receivers_static_type_offset(); } word ICData::state_bits_offset() {
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h index 1036a98..825bbb1 100644 --- a/runtime/vm/compiler/runtime_api.h +++ b/runtime/vm/compiler/runtime_api.h
@@ -411,7 +411,7 @@ static word owner_offset(); static word arguments_descriptor_offset(); static word entries_offset(); - static word static_receiver_type_offset(); + static word receivers_static_type_offset(); static word state_bits_offset(); static word CodeIndexFor(word num_args);
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc index d8f41bd..ce9321b 100644 --- a/runtime/vm/compiler/stub_code_compiler_arm.cc +++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -14,7 +14,7 @@ #include "vm/code_entry_kind.h" #include "vm/compiler/assembler/assembler.h" #include "vm/compiler/backend/locations.h" -#include "vm/constants_arm.h" +#include "vm/constants.h" #include "vm/instructions.h" #include "vm/static_type_exactness_state.h" #include "vm/tags.h"
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc index 6ff109c..6b0d490 100644 --- a/runtime/vm/compiler/stub_code_compiler_arm64.cc +++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -14,7 +14,7 @@ #include "vm/code_entry_kind.h" #include "vm/compiler/assembler/assembler.h" #include "vm/compiler/backend/locations.h" -#include "vm/constants_arm64.h" +#include "vm/constants.h" #include "vm/instructions.h" #include "vm/static_type_exactness_state.h" #include "vm/tags.h"
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc index 5b366b3..86f75d6 100644 --- a/runtime/vm/compiler/stub_code_compiler_ia32.cc +++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -14,7 +14,7 @@ #include "vm/code_entry_kind.h" #include "vm/compiler/assembler/assembler.h" #include "vm/compiler/backend/locations.h" -#include "vm/constants_ia32.h" +#include "vm/constants.h" #include "vm/instructions.h" #include "vm/static_type_exactness_state.h" #include "vm/tags.h"
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc index ccc30b5..2c5dd0a 100644 --- a/runtime/vm/compiler/stub_code_compiler_x64.cc +++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -13,7 +13,7 @@ #include "vm/class_id.h" #include "vm/code_entry_kind.h" #include "vm/compiler/assembler/assembler.h" -#include "vm/constants_x64.h" +#include "vm/constants.h" #include "vm/instructions.h" #include "vm/static_type_exactness_state.h" #include "vm/tags.h" @@ -2017,10 +2017,10 @@ __ j(EQUAL, &call_target_function_through_unchecked_entry); // Check trivial exactness. - // Note: RawICData::static_receiver_type_ is guaranteed to be not null + // Note: RawICData::receivers_static_type_ is guaranteed to be not null // because we only emit calls to this stub when it is not null. __ movq(RCX, - FieldAddress(RBX, target::ICData::static_receiver_type_offset())); + FieldAddress(RBX, target::ICData::receivers_static_type_offset())); __ movq(RCX, FieldAddress(RCX, target::Type::arguments_offset())); // RAX contains an offset to type arguments in words as a smi, // hence TIMES_4. RDX is guaranteed to be non-smi because it is expected to
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc index 02a4ed1..d10c8c4 100644 --- a/runtime/vm/compiler_test.cc +++ b/runtime/vm/compiler_test.cc
@@ -37,12 +37,13 @@ " // A.foo();\n" " }\n" "}\n"; - String& url = String::Handle(String::New("dart-test:CompileFunction")); - String& source = String::Handle(String::New(kScriptChars)); - Script& script = - Script::Handle(Script::New(url, source, RawScript::kScriptTag)); - Library& lib = Library::Handle(Library::CoreLibrary()); - EXPECT(CompilerTest::TestCompileScript(lib, script)); + Dart_Handle library; + { + TransitionVMToNative transition(thread); + library = TestCase::LoadTestScript(kScriptChars, NULL); + } + const Library& lib = + Library::Handle(Library::RawCast(Api::UnwrapHandle(library))); EXPECT(ClassFinalizer::ProcessPendingClasses()); Class& cls = Class::Handle(lib.LookupClass(String::Handle(Symbols::New(thread, "A")))); @@ -68,19 +69,19 @@ function_source.ToCString()); } -ISOLATE_UNIT_TEST_CASE(CompileFunctionOnHelperThread) { +ISOLATE_UNIT_TEST_CASE(OptimizeCompileFunctionOnHelperThread) { // Create a simple function and compile it without optimization. const char* kScriptChars = "class A {\n" " static foo() { return 42; }\n" "}\n"; - String& url = - String::Handle(String::New("dart-test:CompileFunctionOnHelperThread")); - String& source = String::Handle(String::New(kScriptChars)); - Script& script = - Script::Handle(Script::New(url, source, RawScript::kScriptTag)); - Library& lib = Library::Handle(Library::CoreLibrary()); - EXPECT(CompilerTest::TestCompileScript(lib, script)); + Dart_Handle library; + { + TransitionVMToNative transition(thread); + library = TestCase::LoadTestScript(kScriptChars, NULL); + } + const Library& lib = + Library::Handle(Library::RawCast(Api::UnwrapHandle(library))); EXPECT(ClassFinalizer::ProcessPendingClasses()); Class& cls = Class::Handle(lib.LookupClass(String::Handle(Symbols::New(thread, "A")))); @@ -98,7 +99,7 @@ #endif Isolate* isolate = thread->isolate(); BackgroundCompiler::Start(isolate); - isolate->background_compiler()->CompileOptimized(func); + isolate->optimizing_background_compiler()->Compile(func); Monitor* m = new Monitor(); { MonitorLocker ml(m); @@ -110,6 +111,50 @@ BackgroundCompiler::Stop(isolate); } +ISOLATE_UNIT_TEST_CASE(CompileFunctionOnHelperThread) { + // Create a simple function and compile it without optimization. + const char* kScriptChars = + "class A {\n" + " static foo() { return 42; }\n" + "}\n"; + Dart_Handle library; + { + TransitionVMToNative transition(thread); + library = TestCase::LoadTestScript(kScriptChars, NULL); + } + const Library& lib = + Library::Handle(Library::RawCast(Api::UnwrapHandle(library))); + EXPECT(ClassFinalizer::ProcessPendingClasses()); + Class& cls = + Class::Handle(lib.LookupClass(String::Handle(Symbols::New(thread, "A")))); + EXPECT(!cls.IsNull()); + String& function_foo_name = String::Handle(String::New("foo")); + Function& func = + Function::Handle(cls.LookupStaticFunction(function_foo_name)); + EXPECT(!func.HasCode()); + if (!FLAG_enable_interpreter) { + CompilerTest::TestCompileFunction(func); + EXPECT(func.HasCode()); + return; + } +#if !defined(PRODUCT) + // Constant in product mode. + FLAG_background_compilation = true; +#endif + Isolate* isolate = thread->isolate(); + BackgroundCompiler::Start(isolate); + isolate->background_compiler()->Compile(func); + Monitor* m = new Monitor(); + { + MonitorLocker ml(m); + while (!func.HasCode()) { + ml.WaitWithSafepointCheck(thread, 1); + } + } + delete m; + BackgroundCompiler::Stop(isolate); +} + ISOLATE_UNIT_TEST_CASE(RegenerateAllocStubs) { const char* kScriptChars = "class A {\n"
diff --git a/runtime/vm/constants.h b/runtime/vm/constants.h index c6412d2..90137d3 100644 --- a/runtime/vm/constants.h +++ b/runtime/vm/constants.h
@@ -19,4 +19,50 @@ #error Unknown architecture. #endif +#if defined(HOST_ARCH_IA32) +#include "vm/constants_ia32.h" +#elif defined(HOST_ARCH_X64) +#include "vm/constants_x64.h" +#elif defined(HOST_ARCH_ARM) +#include "vm/constants_arm.h" +#elif defined(HOST_ARCH_ARM64) +#include "vm/constants_arm64.h" +#else +#error Unknown host architecture. +#endif + +namespace dart { + +#if defined(TARGET_ARCH_IA32) +using namespace arch_ia32; // NOLINT +#elif defined(TARGET_ARCH_X64) +using namespace arch_x64; // NOLINT +#elif defined(TARGET_ARCH_ARM) +using namespace arch_arm; // NOLINT +#elif defined(TARGET_ARCH_ARM64) +using namespace arch_arm64; // NOLINT +#elif defined(TARGET_ARCH_DBC) +// DBC is defined in namespace dart already. +#else +#error Unknown architecture. +#endif + +namespace host { + +#if defined(HOST_ARCH_IA32) +using namespace arch_ia32; // NOLINT +#elif defined(HOST_ARCH_X64) +using namespace arch_x64; // NOLINT +#elif defined(HOST_ARCH_ARM) +using namespace arch_arm; // NOLINT +#elif defined(HOST_ARCH_ARM64) +using namespace arch_arm64; // NOLINT +#else +#error Unknown host architecture. +#endif + +} // namespace host + +} // namespace dart + #endif // RUNTIME_VM_CONSTANTS_H_
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h index 4e272c5..fe2ffcc 100644 --- a/runtime/vm/constants_arm.h +++ b/runtime/vm/constants_arm.h
@@ -5,10 +5,14 @@ #ifndef RUNTIME_VM_CONSTANTS_ARM_H_ #define RUNTIME_VM_CONSTANTS_ARM_H_ +#ifndef RUNTIME_VM_CONSTANTS_H_ +#error Do not include constants_arm.h directly; use constants.h instead. +#endif + #include "platform/assert.h" #include "platform/globals.h" -namespace dart { +namespace arch_arm { // We support both VFPv3-D16 and VFPv3-D32 profiles, but currently only one at // a time. @@ -609,14 +613,14 @@ inline float ImmFloatField() const { uint32_t imm32 = (Bit(19) << 31) | (((1 << 5) - Bit(18)) << 25) | (Bits(16, 2) << 23) | (Bits(0, 4) << 19); - return bit_cast<float, uint32_t>(imm32); + return ::dart::bit_cast<float, uint32_t>(imm32); } // Field used in VFP double immediate move instruction inline double ImmDoubleField() const { uint64_t imm64 = (Bit(19) * (1LL << 63)) | (((1LL << 8) - Bit(18)) << 54) | (Bits(16, 2) * (1LL << 52)) | (Bits(0, 4) * (1LL << 48)); - return bit_cast<double, uint64_t>(imm64); + return ::dart::bit_cast<double, uint64_t>(imm64); } inline Register DivRdField() const { @@ -757,13 +761,13 @@ // reference to an instruction is to convert a pointer. There is no way // to allocate or create instances of class Instr. // Use the At(pc) function to create references to Instr. - static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); } + static Instr* At(::dart::uword pc) { return reinterpret_cast<Instr*>(pc); } private: DISALLOW_ALLOCATION(); DISALLOW_IMPLICIT_CONSTRUCTORS(Instr); }; -} // namespace dart +} // namespace arch_arm #endif // RUNTIME_VM_CONSTANTS_ARM_H_
diff --git a/runtime/vm/constants_arm64.cc b/runtime/vm/constants_arm64.cc index 0714ae3..9938d7c 100644 --- a/runtime/vm/constants_arm64.cc +++ b/runtime/vm/constants_arm64.cc
@@ -2,11 +2,10 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -#if defined(TARGET_ARCH_ARM64) - +#define RUNTIME_VM_CONSTANTS_H_ // To work around include guard. #include "vm/constants_arm64.h" -namespace dart { +namespace arch_arm64 { const Register CallingConventions::ArgumentRegisters[] = { R0, R1, R2, R3, R4, R5, R6, R7, @@ -16,6 +15,4 @@ V0, V1, V2, V3, V4, V5, V6, V7, }; -} // namespace dart - -#endif +} // namespace arch_arm64
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h index fa592e1..8dfabc8 100644 --- a/runtime/vm/constants_arm64.h +++ b/runtime/vm/constants_arm64.h
@@ -5,9 +5,13 @@ #ifndef RUNTIME_VM_CONSTANTS_ARM64_H_ #define RUNTIME_VM_CONSTANTS_ARM64_H_ +#ifndef RUNTIME_VM_CONSTANTS_H_ +#error Do not include constants_arm64.h directly; use constants.h instead. +#endif + #include "platform/assert.h" -namespace dart { +namespace arch_arm64 { enum Register { R0 = 0, @@ -107,7 +111,7 @@ // Register aliases. const Register TMP = R16; // Used as scratch register by assembler. const Register TMP2 = R17; -const Register PP = R27; // Caches object pool pointer in generated code. +const Register PP = R27; // Caches object pool pointer in generated code. const Register CODE_REG = R24; const Register FPREG = FP; // Frame pointer register. const Register SPREG = R15; // Stack pointer register. @@ -397,10 +401,7 @@ SystemFixed = CompareBranchFixed | B31 | B30 | B24, HINT = SystemFixed | B17 | B16 | B13 | B4 | B3 | B2 | B1 | B0, CLREX = SystemFixed | B17 | B16 | B13 | B12 | B11 | B10 | B9 | B8 | B6 | B4 | - B3 | - B2 | - B1 | - B0, + B3 | B2 | B1 | B0, }; // C3.2.5 @@ -1186,13 +1187,13 @@ // reference to an instruction is to convert a pointer. There is no way // to allocate or create instances of class Instr. // Use the At(pc) function to create references to Instr. - static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); } + static Instr* At(::dart::uword pc) { return reinterpret_cast<Instr*>(pc); } private: DISALLOW_ALLOCATION(); DISALLOW_IMPLICIT_CONSTRUCTORS(Instr); }; -} // namespace dart +} // namespace arch_arm64 #endif // RUNTIME_VM_CONSTANTS_ARM64_H_
diff --git a/runtime/vm/constants_ia32.cc b/runtime/vm/constants_ia32.cc index 62c3f6a..a12af82 100644 --- a/runtime/vm/constants_ia32.cc +++ b/runtime/vm/constants_ia32.cc
@@ -2,11 +2,10 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -#if defined(TARGET_ARCH_IA32) - +#define RUNTIME_VM_CONSTANTS_H_ // To work around include guard. #include "vm/constants_ia32.h" -namespace dart { +namespace arch_ia32 { // Although 'kArgumentRegisters' and 'kFpuArgumentRegisters' are both 0, we have // to give these arrays at least one element to appease MSVC. @@ -16,6 +15,4 @@ const FpuRegister CallingConventions::FpuArgumentRegisters[] = { static_cast<FpuRegister>(0)}; -} // namespace dart - -#endif +} // namespace arch_ia32
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h index 24e3783..16eeb4e 100644 --- a/runtime/vm/constants_ia32.h +++ b/runtime/vm/constants_ia32.h
@@ -5,9 +5,13 @@ #ifndef RUNTIME_VM_CONSTANTS_IA32_H_ #define RUNTIME_VM_CONSTANTS_IA32_H_ +#ifndef RUNTIME_VM_CONSTANTS_H_ +#error Do not include constants_ia32.h directly; use constants.h instead. +#endif + #include "platform/assert.h" -namespace dart { +namespace arch_ia32 { enum Register { EAX = 0, @@ -88,7 +92,7 @@ TIMES_4 = 2, TIMES_8 = 3, TIMES_16 = 4, - TIMES_HALF_WORD_SIZE = kWordSizeLog2 - 1 + TIMES_HALF_WORD_SIZE = ::dart::kWordSizeLog2 - 1 }; class Instr { @@ -107,7 +111,7 @@ // reference to an instruction is to convert a pointer. There is no way // to allocate or create instances of class Instr. // Use the At(pc) function to create references to Instr. - static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); } + static Instr* At(::dart::uword pc) { return reinterpret_cast<Instr*>(pc); } private: DISALLOW_ALLOCATION(); @@ -142,6 +146,6 @@ static constexpr Register kSecondNonArgumentRegister = ECX; }; -} // namespace dart +} // namespace arch_ia32 #endif // RUNTIME_VM_CONSTANTS_IA32_H_
diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h index 7128a46..d3b0f35 100644 --- a/runtime/vm/constants_kbc.h +++ b/runtime/vm/constants_kbc.h
@@ -389,6 +389,10 @@ // Receiver and argument should have static type int. // Check SP[-1] and SP[0] for null; push SP[-1] <op> SP[0] ? true : false. // +// - AllocateClosure D +// +// Allocate closure object for closure function ConstantPool[D]. +// // BYTECODE LIST FORMAT // // KernelBytecode list below is specified using the following format: @@ -485,6 +489,7 @@ V(CompareIntGe, 0, ___, ___, ___) \ V(CompareIntLe, 0, ___, ___, ___) \ V(DirectCall, A_D, num, num, ___) \ + V(AllocateClosure, D, lit, ___, ___) \ // These bytecodes are only generated within the VM. Reassinging their // opcodes is not a breaking change. @@ -505,11 +510,11 @@ // Magic value of bytecode files. static const intptr_t kMagicValue = 0x44424332; // 'DBC2' // Minimum bytecode format version supported by VM. - static const intptr_t kMinSupportedBytecodeFormatVersion = 1; + static const intptr_t kMinSupportedBytecodeFormatVersion = 2; // Maximum bytecode format version supported by VM. // The range of supported versions should include version produced by bytecode // generator (currentBytecodeFormatVersion in pkg/vm/lib/bytecode/dbc.dart). - static const intptr_t kMaxSupportedBytecodeFormatVersion = 3; + static const intptr_t kMaxSupportedBytecodeFormatVersion = 4; enum Opcode { #define DECLARE_BYTECODE(name, encoding, op1, op2, op3) k##name,
diff --git a/runtime/vm/constants_x64.cc b/runtime/vm/constants_x64.cc index 3f38d9d..8d80a33 100644 --- a/runtime/vm/constants_x64.cc +++ b/runtime/vm/constants_x64.cc
@@ -2,11 +2,10 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -#if defined(TARGET_ARCH_X64) - +#define RUNTIME_VM_CONSTANTS_H_ // To work around include guard. #include "vm/constants_x64.h" -namespace dart { +namespace arch_x64 { #if defined(_WIN64) const Register CallingConventions::ArgumentRegisters[] = { @@ -26,6 +25,4 @@ XmmRegister::XMM4, XmmRegister::XMM5, XmmRegister::XMM6, XmmRegister::XMM7}; #endif -} // namespace dart - -#endif +} // namespace arch_x64
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h index 3e8d0070..3d37645 100644 --- a/runtime/vm/constants_x64.h +++ b/runtime/vm/constants_x64.h
@@ -5,10 +5,14 @@ #ifndef RUNTIME_VM_CONSTANTS_X64_H_ #define RUNTIME_VM_CONSTANTS_X64_H_ +#ifndef RUNTIME_VM_CONSTANTS_H_ +#error Do not include constants_x64.h directly; use constants.h instead. +#endif + #include "platform/assert.h" #include "platform/globals.h" -namespace dart { +namespace arch_x64 { enum Register { RAX = 0, @@ -140,7 +144,7 @@ TIMES_4 = 2, TIMES_8 = 3, TIMES_16 = 4, - TIMES_HALF_WORD_SIZE = kWordSizeLog2 - 1 + TIMES_HALF_WORD_SIZE = ::dart::kWordSizeLog2 - 1 }; #define R(reg) (1 << (reg)) @@ -166,7 +170,7 @@ // same time? (Windows no, rest yes) static const bool kArgumentIntRegXorFpuReg = true; - static const intptr_t kShadowSpaceBytes = 4 * kWordSize; + static const intptr_t kShadowSpaceBytes = 4 * ::dart::kWordSize; static const intptr_t kVolatileCpuRegisters = R(RAX) | R(RCX) | R(RDX) | R(R8) | R(R9) | R(R10) | R(R11); @@ -268,7 +272,7 @@ // reference to an instruction is to convert a pointer. There is no way // to allocate or create instances of class Instr. // Use the At(pc) function to create references to Instr. - static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); } + static Instr* At(::dart::uword pc) { return reinterpret_cast<Instr*>(pc); } private: DISALLOW_ALLOCATION(); @@ -280,6 +284,6 @@ // becomes important to us. const int MAX_NOP_SIZE = 8; -} // namespace dart +} // namespace arch_x64 #endif // RUNTIME_VM_CONSTANTS_X64_H_
diff --git a/runtime/vm/cpu_ia32.cc b/runtime/vm/cpu_ia32.cc index 08cfc5e..82ab263 100644 --- a/runtime/vm/cpu_ia32.cc +++ b/runtime/vm/cpu_ia32.cc
@@ -9,7 +9,7 @@ #include "vm/cpu_ia32.h" #include "vm/compiler/assembler/assembler.h" -#include "vm/constants_ia32.h" +#include "vm/constants.h" #include "vm/cpuinfo.h" #include "vm/heap/heap.h" #include "vm/isolate.h"
diff --git a/runtime/vm/cpu_x64.cc b/runtime/vm/cpu_x64.cc index 553e9cd..a4a17f1 100644 --- a/runtime/vm/cpu_x64.cc +++ b/runtime/vm/cpu_x64.cc
@@ -9,7 +9,7 @@ #include "vm/cpu_x64.h" #include "vm/compiler/assembler/assembler.h" -#include "vm/constants_x64.h" +#include "vm/constants.h" #include "vm/cpuinfo.h" #include "vm/heap/heap.h" #include "vm/isolate.h"
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc index d1354ca..ffb115e 100644 --- a/runtime/vm/dart.cc +++ b/runtime/vm/dart.cc
@@ -759,6 +759,10 @@ buffer.AddString(FLAG_causal_async_stacks ? " causal_async_stacks" : " no-causal_async_stacks"); + buffer.AddString((FLAG_enable_interpreter || FLAG_use_bytecode_compiler) + ? " bytecode" + : " no-bytecode"); + // Generated code must match the host architecture and ABI. #if defined(TARGET_ARCH_ARM) #if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc index 683a636..b1f2ce4 100644 --- a/runtime/vm/dart_api_impl.cc +++ b/runtime/vm/dart_api_impl.cc
@@ -806,12 +806,13 @@ return Api::NewHandle(T, UnhandledException::New(obj, stacktrace)); } -DART_EXPORT Dart_Handle Dart_PropagateError(Dart_Handle handle) { +DART_EXPORT void Dart_PropagateError(Dart_Handle handle) { Thread* thread = Thread::Current(); + CHECK_ISOLATE(thread->isolate()); TransitionNativeToVM transition(thread); const Object& obj = Object::Handle(thread->zone(), Api::UnwrapHandle(handle)); if (!obj.IsError()) { - return Api::NewError( + FATAL1( "%s expects argument 'handle' to be an error handle. " "Did you forget to check Dart_IsError first?", CURRENT_FUNC); @@ -819,7 +820,8 @@ if (thread->top_exit_frame_info() == 0) { // There are no dart frames on the stack so it would be illegal to // propagate an error here. - return Api::NewError("No Dart frames on stack, cannot propagate error."); + FATAL1("No Dart frames on stack, cannot propagate error: %s", + Error::Cast(obj).ToErrorCString()); } // Unwind all the API scopes till the exit frame before propagating. const Error* error; @@ -837,16 +839,6 @@ } Exceptions::PropagateError(*error); UNREACHABLE(); - return Api::NewError("Cannot reach here. Internal error."); -} - -DART_EXPORT void _Dart_ReportErrorHandle(const char* file, - int line, - const char* handle, - const char* message) { - fprintf(stderr, "%s:%d: error handle: '%s':\n '%s'\n", file, line, handle, - message); - OS::Abort(); } DART_EXPORT Dart_Handle Dart_ToString(Dart_Handle object) { @@ -1045,7 +1037,7 @@ #if !defined(PRODUCT) #define VM_METRIC_API(type, variable, name, unit) \ DART_EXPORT int64_t Dart_VM##variable##Metric() { \ - return vm_metric_##variable##_.value(); \ + return vm_metric_##variable.value(); \ } VM_METRIC_LIST(VM_METRIC_API); #undef VM_METRIC_API
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc index b4ad32a..406901a 100644 --- a/runtime/vm/dart_api_impl_test.cc +++ b/runtime/vm/dart_api_impl_test.cc
@@ -571,8 +571,7 @@ EXPECT_VALID(result); // We do not expect to reach here. UNREACHABLE(); } else { - result = Dart_PropagateError(result); - EXPECT_VALID(result); // We do not expect to reach here. + Dart_PropagateError(result); UNREACHABLE(); } } @@ -5375,7 +5374,7 @@ Dart_Handle instance; // Create a test library and Load up a test script in it. // The test library must have a dart: url so it can import dart:_internal. - Dart_Handle lib = TestCase::LoadCoreTestScript(kScriptChars, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); Dart_Handle type = Dart_GetType(lib, NewString("TestClass"), 0, NULL); EXPECT_VALID(type);
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc index 52064e7..3759e0f 100644 --- a/runtime/vm/debugger.cc +++ b/runtime/vm/debugger.cc
@@ -1407,34 +1407,28 @@ ContextLevel()); } -void ActivationFrame::PrintToJSONObject(JSONObject* jsobj, bool full) { +void ActivationFrame::PrintToJSONObject(JSONObject* jsobj) { if (kind_ == kRegular) { - PrintToJSONObjectRegular(jsobj, full); + PrintToJSONObjectRegular(jsobj); } else if (kind_ == kAsyncCausal) { - PrintToJSONObjectAsyncCausal(jsobj, full); + PrintToJSONObjectAsyncCausal(jsobj); } else if (kind_ == kAsyncSuspensionMarker) { - PrintToJSONObjectAsyncSuspensionMarker(jsobj, full); + PrintToJSONObjectAsyncSuspensionMarker(jsobj); } else if (kind_ == kAsyncActivation) { - PrintToJSONObjectAsyncActivation(jsobj, full); + PrintToJSONObjectAsyncActivation(jsobj); } else { UNIMPLEMENTED(); } } -void ActivationFrame::PrintToJSONObjectRegular(JSONObject* jsobj, bool full) { +void ActivationFrame::PrintToJSONObjectRegular(JSONObject* jsobj) { const Script& script = Script::Handle(SourceScript()); jsobj->AddProperty("type", "Frame"); jsobj->AddProperty("kind", KindToCString(kind_)); const TokenPosition pos = TokenPos().SourcePosition(); jsobj->AddLocation(script, pos); - jsobj->AddProperty("function", function(), !full); + jsobj->AddProperty("function", function()); jsobj->AddProperty("code", code()); - if (full) { - // TODO(cutch): The old "full" script usage no longer fits - // in the world where we pass the script as part of the - // location. - jsobj->AddProperty("script", script, !full); - } { JSONArray jsvars(jsobj, "vars"); const int num_vars = NumLocalVariables(); @@ -1455,7 +1449,7 @@ jsvar.AddProperty("type", "BoundVariable"); var_name = String::ScrubName(var_name); jsvar.AddProperty("name", var_name.ToCString()); - jsvar.AddProperty("value", var_value, !full); + jsvar.AddProperty("value", var_value); // Where was the variable declared? jsvar.AddProperty("declarationTokenPos", declaration_token_pos); // When the variable becomes visible to the scope. @@ -1467,45 +1461,31 @@ } } -void ActivationFrame::PrintToJSONObjectAsyncCausal(JSONObject* jsobj, - bool full) { +void ActivationFrame::PrintToJSONObjectAsyncCausal(JSONObject* jsobj) { jsobj->AddProperty("type", "Frame"); jsobj->AddProperty("kind", KindToCString(kind_)); const Script& script = Script::Handle(SourceScript()); const TokenPosition pos = TokenPos().SourcePosition(); jsobj->AddLocation(script, pos); - jsobj->AddProperty("function", function(), !full); + jsobj->AddProperty("function", function()); jsobj->AddProperty("code", code()); - if (full) { - // TODO(cutch): The old "full" script usage no longer fits - // in the world where we pass the script as part of the - // location. - jsobj->AddProperty("script", script, !full); - } } -void ActivationFrame::PrintToJSONObjectAsyncSuspensionMarker(JSONObject* jsobj, - bool full) { +void ActivationFrame::PrintToJSONObjectAsyncSuspensionMarker( + JSONObject* jsobj) { jsobj->AddProperty("type", "Frame"); jsobj->AddProperty("kind", KindToCString(kind_)); jsobj->AddProperty("marker", "AsynchronousSuspension"); } -void ActivationFrame::PrintToJSONObjectAsyncActivation(JSONObject* jsobj, - bool full) { +void ActivationFrame::PrintToJSONObjectAsyncActivation(JSONObject* jsobj) { jsobj->AddProperty("type", "Frame"); jsobj->AddProperty("kind", KindToCString(kind_)); const Script& script = Script::Handle(SourceScript()); const TokenPosition pos = TokenPos().SourcePosition(); jsobj->AddLocation(script, pos); - jsobj->AddProperty("function", function(), !full); + jsobj->AddProperty("function", function()); jsobj->AddProperty("code", code()); - if (full) { - // TODO(cutch): The old "full" script usage no longer fits - // in the world where we pass the script as part of the - // location. - jsobj->AddProperty("script", script, !full); - } } static bool IsFunctionVisible(const Function& function) {
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h index 011dcca..d15fbb9 100644 --- a/runtime/vm/debugger.h +++ b/runtime/vm/debugger.h
@@ -338,10 +338,7 @@ const Array& type_definitions, const TypeArguments& type_arguments); - // Print the activation frame into |jsobj|. if |full| is false, script - // and local variable objects are only references. if |full| is true, - // the complete script, function, and, local variable objects are included. - void PrintToJSONObject(JSONObject* jsobj, bool full = false); + void PrintToJSONObject(JSONObject* jsobj); RawObject* GetAsyncAwaiter(); RawObject* GetCausalStack(); @@ -349,10 +346,10 @@ bool HandlesException(const Instance& exc_obj); private: - void PrintToJSONObjectRegular(JSONObject* jsobj, bool full); - void PrintToJSONObjectAsyncCausal(JSONObject* jsobj, bool full); - void PrintToJSONObjectAsyncSuspensionMarker(JSONObject* jsobj, bool full); - void PrintToJSONObjectAsyncActivation(JSONObject* jsobj, bool full); + void PrintToJSONObjectRegular(JSONObject* jsobj); + void PrintToJSONObjectAsyncCausal(JSONObject* jsobj); + void PrintToJSONObjectAsyncSuspensionMarker(JSONObject* jsobj); + void PrintToJSONObjectAsyncActivation(JSONObject* jsobj); void PrintContextMismatchError(intptr_t ctx_slot, intptr_t frame_ctx_level, intptr_t var_ctx_level);
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h index edd0226..d7b662d 100644 --- a/runtime/vm/flag_list.h +++ b/runtime/vm/flag_list.h
@@ -57,8 +57,6 @@ "Debugger support async functions.") \ P(background_compilation, bool, USING_MULTICORE, \ "Run optimizing compilation in background") \ - R(background_compilation_stop_alot, false, bool, false, \ - "Stress test system: stop background compiler often.") \ P(causal_async_stacks, bool, !USING_PRODUCT, "Improved async stacks") \ P(collect_code, bool, true, "Attempt to GC infrequently used code.") \ P(collect_dynamic_function_names, bool, true, \ @@ -127,6 +125,9 @@ "Initial size of new gen semi space in MB") \ P(optimization_counter_threshold, int, 30000, \ "Function's usage-counter value before it is optimized, -1 means never") \ + R(randomize_optimization_counter, false, bool, false, \ + "Randomize optimization counter thresholds on a per-function basis (for " \ + "testing).") \ P(optimization_level, int, 2, \ "Optimization level: 1 (favor size), 2 (default), 3 (favor speed)") \ P(old_gen_heap_size, int, kDefaultMaxOldGenHeapSize, \
diff --git a/runtime/vm/frame_layout.h b/runtime/vm/frame_layout.h index 53ddcc7..3242353 100644 --- a/runtime/vm/frame_layout.h +++ b/runtime/vm/frame_layout.h
@@ -23,9 +23,13 @@ // The offset (in words) from FP to the last fixed object. int last_fixed_object_from_fp; - // The offset (in words) from FP to the first local. + // The offset (in words) from FP to the slot past the last parameter. int param_end_from_fp; + // The offset (in words) from SP on entry (before frame is setup) to + // the last parameter. + int last_param_from_entry_sp; + // The offset (in words) from FP to the first local. int first_local_from_fp;
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc index 785f8fb..c8e8af9 100644 --- a/runtime/vm/instructions_arm.cc +++ b/runtime/vm/instructions_arm.cc
@@ -9,7 +9,7 @@ #include "vm/instructions_arm.h" #include "vm/compiler/assembler/assembler.h" -#include "vm/constants_arm.h" +#include "vm/constants.h" #include "vm/cpu.h" #include "vm/object.h" #include "vm/reverse_pc_lookup_cache.h"
diff --git a/runtime/vm/instructions_arm.h b/runtime/vm/instructions_arm.h index 37b7cef..d3e1cdb 100644 --- a/runtime/vm/instructions_arm.h +++ b/runtime/vm/instructions_arm.h
@@ -12,7 +12,7 @@ #include "vm/allocation.h" #include "vm/compiler/assembler/assembler.h" -#include "vm/constants_arm.h" +#include "vm/constants.h" #include "vm/native_function.h" namespace dart {
diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc index ea9a118..d34d7a7 100644 --- a/runtime/vm/instructions_arm64.cc +++ b/runtime/vm/instructions_arm64.cc
@@ -9,7 +9,7 @@ #include "vm/instructions_arm64.h" #include "vm/compiler/assembler/assembler.h" -#include "vm/constants_arm64.h" +#include "vm/constants.h" #include "vm/cpu.h" #include "vm/object.h" #include "vm/reverse_pc_lookup_cache.h"
diff --git a/runtime/vm/instructions_arm64.h b/runtime/vm/instructions_arm64.h index c78cee3..8550643 100644 --- a/runtime/vm/instructions_arm64.h +++ b/runtime/vm/instructions_arm64.h
@@ -12,7 +12,7 @@ #include "vm/allocation.h" #include "vm/compiler/assembler/assembler.h" -#include "vm/constants_arm64.h" +#include "vm/constants.h" #include "vm/native_function.h" namespace dart {
diff --git a/runtime/vm/instructions_x64.cc b/runtime/vm/instructions_x64.cc index 70ed255..7c0e336 100644 --- a/runtime/vm/instructions_x64.cc +++ b/runtime/vm/instructions_x64.cc
@@ -9,7 +9,7 @@ #include "vm/instructions.h" #include "vm/instructions_x64.h" -#include "vm/constants_x64.h" +#include "vm/constants.h" #include "vm/cpu.h" #include "vm/object.h"
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc index 746e199..c36b640 100644 --- a/runtime/vm/interpreter.cc +++ b/runtime/vm/interpreter.cc
@@ -209,6 +209,11 @@ // Everything matches. return false; } + + DART_FORCE_INLINE static bool IsFinalized(RawClass* cls) { + return Class::ClassFinalizedBits::decode(cls->ptr()->state_bits_) == + RawClass::kFinalized; + } }; DART_FORCE_INLINE static uint32_t* SavedCallerPC(RawObject** FP) { @@ -222,6 +227,21 @@ return function; } +DART_FORCE_INLINE static RawObject* InitializeHeader(uword addr, + intptr_t class_id, + intptr_t instance_size) { + uint32_t tags = 0; + tags = RawObject::ClassIdTag::update(class_id, tags); + tags = RawObject::SizeTag::update(instance_size, tags); + tags = RawObject::OldBit::update(false, tags); + tags = RawObject::OldAndNotMarkedBit::update(false, tags); + tags = RawObject::OldAndNotRememberedBit::update(false, tags); + tags = RawObject::NewBit::update(true, tags); + // Also writes zero in the hash_ field. + *reinterpret_cast<uword*>(addr + Object::tags_offset()) = tags; + return RawObject::FromAddr(addr); +} + void LookupCache::Clear() { for (intptr_t i = 0; i < kNumEntries; i++) { entries_[i].receiver_cid = kIllegalCid; @@ -432,17 +452,32 @@ frame[1] = Bytecode::null(); frame[2] = reinterpret_cast<RawObject*>(pc); frame[3] = reinterpret_cast<RawObject*>(base); - fp_ = frame + kKBCDartFrameFixedSize; - thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_)); + + RawObject** exit_fp = frame + kKBCDartFrameFixedSize; + thread->set_top_exit_frame_info(reinterpret_cast<uword>(exit_fp)); + fp_ = exit_fp; + #if defined(DEBUG) if (IsTracingExecution()) { THR_Print("%" Pu64 " ", icount_); THR_Print("Exiting interpreter 0x%" Px " at fp_ 0x%" Px "\n", - reinterpret_cast<uword>(this), reinterpret_cast<uword>(fp_)); + reinterpret_cast<uword>(this), reinterpret_cast<uword>(exit_fp)); } #endif } +void Interpreter::Unexit(Thread* thread) { +#if !defined(PRODUCT) + // For the profiler. + RawObject** exit_fp = + reinterpret_cast<RawObject**>(thread->top_exit_frame_info()); + ASSERT(exit_fp != 0); + pc_ = SavedCallerPC(exit_fp); + fp_ = SavedCallerFP(exit_fp); +#endif + thread->set_top_exit_frame_info(0); +} + // Calling into runtime may trigger garbage collection and relocate objects, // so all RawObject* pointers become outdated and should not be used across // runtime calls. @@ -458,7 +493,7 @@ thread->set_vm_tag(reinterpret_cast<uword>(drt)); drt(args); thread->set_vm_tag(VMTag::kDartInterpretedTagId); - thread->set_top_exit_frame_info(0); + interpreter->Unexit(thread); return true; } else { return false; @@ -475,7 +510,7 @@ thread->set_vm_tag(reinterpret_cast<uword>(function)); wrapper(args, function); thread->set_vm_tag(VMTag::kDartInterpretedTagId); - thread->set_top_exit_frame_info(0); + interpreter->Unexit(thread); return true; } else { return false; @@ -522,9 +557,9 @@ #else result = entrypoint(code, argdesc_, call_base, thread); #endif - thread->set_top_exit_frame_info(0); ASSERT(thread->vm_tag() == VMTag::kDartInterpretedTagId); ASSERT(thread->execution_state() == Thread::kThreadInGenerated); + Unexit(thread); } else { return false; } @@ -553,10 +588,10 @@ if (RawObject::IsErrorClassId(result_cid)) { // Unwind to entry frame. fp_ = *FP; - pc_ = reinterpret_cast<uword>(SavedCallerPC(fp_)); + pc_ = SavedCallerPC(fp_); while (!IsEntryFrameMarker(pc_)) { fp_ = SavedCallerFP(fp_); - pc_ = reinterpret_cast<uword>(SavedCallerPC(fp_)); + pc_ = SavedCallerPC(fp_); } // Pop entry frame. fp_ = SavedCallerFP(fp_); @@ -810,9 +845,9 @@ callee_fp[kKBCSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP); pp_ = bytecode->ptr()->object_pool_; *pc = reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_); - pc_ = reinterpret_cast<uword>(*pc); // For the profiler. + NOT_IN_PRODUCT(pc_ = *pc); // For the profiler. *FP = callee_fp; - fp_ = callee_fp; // For the profiler. + NOT_IN_PRODUCT(fp_ = callee_fp); // For the profiler. *SP = *FP - 1; return true; } @@ -886,7 +921,10 @@ Exit(thread, *FP, top + 5, *pc); NativeArguments native_args(thread, 3, /* argv */ top + 1, /* result */ top + 4); - DRT_InterpretedInterfaceCallMissHandler(native_args); + if (!InvokeRuntime(thread, this, DRT_InterpretedInterfaceCallMissHandler, + native_args)) { + return false; + } target = static_cast<RawFunction*>(top[4]); target_name = static_cast<RawString*>(top[2]); @@ -1091,9 +1129,9 @@ #define HANDLE_EXCEPTION \ do { \ - FP = reinterpret_cast<RawObject**>(fp_); \ - pc = reinterpret_cast<uint32_t*>(pc_); \ - if (IsEntryFrameMarker(reinterpret_cast<uword>(pc))) { \ + FP = fp_; \ + pc = pc_; \ + if (IsEntryFrameMarker(pc)) { \ pp_ = reinterpret_cast<RawObjectPool*>(fp_[kKBCSavedPpSlotFromEntryFp]); \ argdesc_ = \ reinterpret_cast<RawArray*>(fp_[kKBCSavedArgDescSlotFromEntryFp]); \ @@ -1119,9 +1157,9 @@ #define HANDLE_EXCEPTION \ do { \ - FP = reinterpret_cast<RawObject**>(fp_); \ - pc = reinterpret_cast<uint32_t*>(pc_); \ - if (IsEntryFrameMarker(reinterpret_cast<uword>(pc))) { \ + FP = fp_; \ + pc = pc_; \ + if (IsEntryFrameMarker(pc)) { \ pp_ = reinterpret_cast<RawObjectPool*>(fp_[kKBCSavedPpSlotFromEntryFp]); \ argdesc_ = \ reinterpret_cast<RawArray*>(fp_[kKBCSavedArgDescSlotFromEntryFp]); \ @@ -1140,7 +1178,6 @@ #define HANDLE_RETURN \ do { \ pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_; \ - fp_ = FP; /* For the profiler. */ \ } while (0) // Runtime call helpers: handle invocation and potential exception after return. @@ -1178,7 +1215,7 @@ #define BOX_INT64_RESULT(result) \ if (LIKELY(Smi::IsValid(result))) { \ SP[0] = Smi::New(static_cast<intptr_t>(result)); \ - } else if (!AllocateInt64Box(thread, result, pc, FP, SP)) { \ + } else if (!AllocateMint(thread, result, pc, FP, SP)) { \ HANDLE_EXCEPTION; \ } \ ASSERT(Integer::GetInt64Value(RAW_CAST(Integer, SP[0])) == result); @@ -1274,26 +1311,22 @@ arguments.raw_ptr()->data(), thread); } -// Allocate _Mint box for the given int64_t value and puts it into SP[0]. +// Allocate a _Mint for the given int64_t value and puts it into SP[0]. // Returns false on exception. -DART_NOINLINE bool Interpreter::AllocateInt64Box(Thread* thread, - int64_t value, - uint32_t* pc, - RawObject** FP, - RawObject** SP) { +DART_NOINLINE bool Interpreter::AllocateMint(Thread* thread, + int64_t value, + uint32_t* pc, + RawObject** FP, + RawObject** SP) { ASSERT(!Smi::IsValid(value)); const intptr_t instance_size = Mint::InstanceSize(); - const uword start = - thread->heap()->new_space()->TryAllocateInTLAB(thread, instance_size); - if (LIKELY(start != 0)) { - uword tags = 0; - tags = RawObject::ClassIdTag::update(kMintCid, tags); - tags = RawObject::SizeTag::update(instance_size, tags); - tags = RawObject::NewBit::update(true, tags); - // Also writes zero in the hash_ field. - *reinterpret_cast<uword*>(start + Mint::tags_offset()) = tags; - *reinterpret_cast<int64_t*>(start + Mint::value_offset()) = value; - SP[0] = reinterpret_cast<RawObject*>(start + kHeapObjectTag); + const uword start = thread->top(); + if (LIKELY((start + instance_size) < thread->end())) { + thread->set_top(start + instance_size); + RawMint* result = + Mint::RawCast(InitializeHeader(start, kMintCid, instance_size)); + result->ptr()->value_ = value; + SP[0] = result; return true; } else { SP[0] = 0; // Space for the result. @@ -1309,110 +1342,132 @@ } } -// Allocate _Double box for the given double value and puts it into SP[0]. +// Allocate a _Double for the given double value and put it into SP[0]. // Returns false on exception. -DART_NOINLINE bool Interpreter::AllocateDoubleBox(Thread* thread, - double value, +DART_NOINLINE bool Interpreter::AllocateDouble(Thread* thread, + double value, + uint32_t* pc, + RawObject** FP, + RawObject** SP) { + const intptr_t instance_size = Double::InstanceSize(); + const uword start = thread->top(); + if (LIKELY((start + instance_size) < thread->end())) { + thread->set_top(start + instance_size); + RawDouble* result = + Double::RawCast(InitializeHeader(start, kDoubleCid, instance_size)); + result->ptr()->value_ = value; + SP[0] = result; + return true; + } else { + SP[0] = 0; // Space for the result. + SP[1] = thread->isolate()->object_store()->double_class(); + SP[2] = Object::null(); // Type arguments. + Exit(thread, FP, SP + 3, pc); + NativeArguments args(thread, 2, SP + 1, SP); + if (!InvokeRuntime(thread, this, DRT_AllocateObject, args)) { + return false; + } + Double::RawCast(SP[0])->ptr()->value_ = value; + return true; + } +} + +// Allocate a _Float32x4 for the given simd value and put it into SP[0]. +// Returns false on exception. +DART_NOINLINE bool Interpreter::AllocateFloat32x4(Thread* thread, + simd128_value_t value, uint32_t* pc, RawObject** FP, RawObject** SP) { - const intptr_t instance_size = Double::InstanceSize(); - const uword start = - thread->heap()->new_space()->TryAllocateInTLAB(thread, instance_size); - if (LIKELY(start != 0)) { - uword tags = 0; - tags = RawObject::ClassIdTag::update(kDoubleCid, tags); - tags = RawObject::SizeTag::update(instance_size, tags); - tags = RawObject::NewBit::update(true, tags); - // Also writes zero in the hash_ field. - *reinterpret_cast<uword*>(start + Double::tags_offset()) = tags; - *reinterpret_cast<double*>(start + Double::value_offset()) = value; - SP[0] = reinterpret_cast<RawObject*>(start + kHeapObjectTag); - return true; - } else { - SP[0] = 0; // Space for the result. - SP[1] = thread->isolate()->object_store()->double_class(); // Class object. - SP[2] = Object::null(); // Type arguments. - Exit(thread, FP, SP + 3, pc); - NativeArguments args(thread, 2, SP + 1, SP); - if (!InvokeRuntime(thread, this, DRT_AllocateObject, args)) { - return false; - } - reinterpret_cast<RawDouble*>(SP[0])->ptr()->value_ = value; - return true; - } -} - -// Allocate _Float32x4 box for the given simd value and puts it into SP[0]. -// Returns false on exception. -DART_NOINLINE bool Interpreter::AllocateFloat32x4Box(Thread* thread, - simd128_value_t value, - uint32_t* pc, - RawObject** FP, - RawObject** SP) { const intptr_t instance_size = Float32x4::InstanceSize(); - const uword start = - thread->heap()->new_space()->TryAllocateInTLAB(thread, instance_size); - if (LIKELY(start != 0)) { - uword tags = 0; - tags = RawObject::ClassIdTag::update(kFloat32x4Cid, tags); - tags = RawObject::SizeTag::update(instance_size, tags); - tags = RawObject::NewBit::update(true, tags); - // Also writes zero in the hash_ field. - *reinterpret_cast<uword*>(start + Float32x4::tags_offset()) = tags; - SP[0] = reinterpret_cast<RawObject*>(start + kHeapObjectTag); - value.writeTo(reinterpret_cast<RawFloat32x4*>(SP[0])->ptr()->value_); + const uword start = thread->top(); + if (LIKELY((start + instance_size) < thread->end())) { + thread->set_top(start + instance_size); + RawFloat32x4* result = Float32x4::RawCast( + InitializeHeader(start, kFloat32x4Cid, instance_size)); + value.writeTo(result->ptr()->value_); + SP[0] = result; return true; } else { SP[0] = 0; // Space for the result. - SP[1] = - thread->isolate()->object_store()->float32x4_class(); // Class object. + SP[1] = thread->isolate()->object_store()->float32x4_class(); SP[2] = Object::null(); // Type arguments. Exit(thread, FP, SP + 3, pc); NativeArguments args(thread, 2, SP + 1, SP); if (!InvokeRuntime(thread, this, DRT_AllocateObject, args)) { return false; } - value.writeTo(reinterpret_cast<RawFloat32x4*>(SP[0])->ptr()->value_); + value.writeTo(Float32x4::RawCast(SP[0])->ptr()->value_); return true; } } -// Allocate _Float64x2 box for the given simd value and puts it into SP[0]. +// Allocate _Float64x2 box for the given simd value and put it into SP[0]. // Returns false on exception. -DART_NOINLINE bool Interpreter::AllocateFloat64x2Box(Thread* thread, - simd128_value_t value, - uint32_t* pc, - RawObject** FP, - RawObject** SP) { +DART_NOINLINE bool Interpreter::AllocateFloat64x2(Thread* thread, + simd128_value_t value, + uint32_t* pc, + RawObject** FP, + RawObject** SP) { const intptr_t instance_size = Float64x2::InstanceSize(); - const uword start = - thread->heap()->new_space()->TryAllocateInTLAB(thread, instance_size); - if (LIKELY(start != 0)) { - uword tags = 0; - tags = RawObject::ClassIdTag::update(kFloat64x2Cid, tags); - tags = RawObject::SizeTag::update(instance_size, tags); - tags = RawObject::NewBit::update(true, tags); - // Also writes zero in the hash_ field. - *reinterpret_cast<uword*>(start + Float64x2::tags_offset()) = tags; - SP[0] = reinterpret_cast<RawObject*>(start + kHeapObjectTag); - value.writeTo(reinterpret_cast<RawFloat64x2*>(SP[0])->ptr()->value_); + const uword start = thread->top(); + if (LIKELY((start + instance_size) < thread->end())) { + thread->set_top(start + instance_size); + RawFloat64x2* result = Float64x2::RawCast( + InitializeHeader(start, kFloat64x2Cid, instance_size)); + value.writeTo(result->ptr()->value_); + SP[0] = result; return true; } else { SP[0] = 0; // Space for the result. - SP[1] = - thread->isolate()->object_store()->float64x2_class(); // Class object. + SP[1] = thread->isolate()->object_store()->float64x2_class(); SP[2] = Object::null(); // Type arguments. Exit(thread, FP, SP + 3, pc); NativeArguments args(thread, 2, SP + 1, SP); if (!InvokeRuntime(thread, this, DRT_AllocateObject, args)) { return false; } - value.writeTo(reinterpret_cast<RawFloat32x4*>(SP[0])->ptr()->value_); + value.writeTo(Float64x2::RawCast(SP[0])->ptr()->value_); return true; } } +// Allocate a _List with the given type arguments and length and put it into +// SP[0]. Returns false on exception. +bool Interpreter::AllocateArray(Thread* thread, + RawTypeArguments* type_args, + RawObject* length_object, + uint32_t* pc, + RawObject** FP, + RawObject** SP) { + if (LIKELY(!length_object->IsHeapObject())) { + const intptr_t length = Smi::Value(Smi::RawCast(length_object)); + if (LIKELY((0 <= length) && (length <= Array::kMaxElements))) { + const intptr_t instance_size = Array::InstanceSize(length); + const uword start = thread->top(); + if (LIKELY((start + instance_size) < thread->end())) { + thread->set_top(start + instance_size); + RawArray* result = + Array::RawCast(InitializeHeader(start, kArrayCid, instance_size)); + result->ptr()->type_arguments_ = type_args; + result->ptr()->length_ = Smi::New(length); + for (intptr_t i = 0; i < length; i++) { + result->ptr()->data()[i] = Object::null(); + } + SP[0] = result; + return true; + } + } + } + + SP[0] = 0; // Space for the result; + SP[1] = length_object; + SP[2] = type_args; + Exit(thread, FP, SP + 3, pc); + NativeArguments args(thread, 2, SP + 1, SP); + return InvokeRuntime(thread, this, DRT_AllocateArray, args); +} + RawObject* Interpreter::Call(RawFunction* function, RawArray* argdesc, intptr_t argc, @@ -1494,8 +1549,8 @@ // Ready to start executing bytecode. Load entry point and corresponding // object pool. pc = reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_); - pc_ = reinterpret_cast<uword>(pc); // For the profiler. - fp_ = FP; // For the profiler. + NOT_IN_PRODUCT(pc_ = pc); // For the profiler. + NOT_IN_PRODUCT(fp_ = FP); // For the profiler. pp_ = bytecode->ptr()->object_pool_; // Save current VM tag and mark thread as executing Dart code. For the @@ -1988,7 +2043,8 @@ RawObject** call_top = SP + 1; InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP)); - RawString* target_name = static_cast<RawString*>(LOAD_CONSTANT(kidx)); + RawString* target_name = + static_cast<RawFunction*>(LOAD_CONSTANT(kidx))->ptr()->name_; argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx + 1)); if (!InterfaceCall(thread, target_name, call_base, call_top, &pc, &FP, &SP)) { @@ -2092,12 +2148,12 @@ // : new _GrowableList<E>(0); // } if (InterpreterHelpers::ArgDescPosCount(argdesc_) == 2) { - SP[1] = SP[0]; // length - SP[2] = SP[-1]; // type - Exit(thread, FP, SP + 3, pc); - NativeArguments native_args(thread, 2, SP + 1, SP - 1); - INVOKE_RUNTIME(DRT_AllocateArray, native_args); - SP -= 1; // Result is in SP - 1. + RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]); + RawObject* length = SP[0]; + SP--; + if (!AllocateArray(thread, type_args, length, pc, FP, SP)) { + HANDLE_EXCEPTION; + } } else { ASSERT(InterpreterHelpers::ArgDescPosCount(argdesc_) == 1); // SP[-1] is type. @@ -2115,12 +2171,12 @@ } } break; case MethodRecognizer::kObjectArrayAllocate: { - SP[1] = SP[0]; // length - SP[2] = SP[-1]; // type - Exit(thread, FP, SP + 3, pc); - NativeArguments native_args(thread, 2, SP + 1, SP - 1); - INVOKE_RUNTIME(DRT_AllocateArray, native_args); - SP -= 1; // Result is in SP - 1. + RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]); + RawObject* length = SP[0]; + SP--; + if (!AllocateArray(thread, type_args, length, pc, FP, SP)) { + HANDLE_EXCEPTION; + } } break; case MethodRecognizer::kLinkedHashMap_getIndex: { RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]); @@ -2224,20 +2280,23 @@ result = *SP; // Restore caller PC. pc = SavedCallerPC(FP); - pc_ = reinterpret_cast<uword>(pc); // For the profiler. // Check if it is a fake PC marking the entry frame. - if (IsEntryFrameMarker(reinterpret_cast<uword>(pc))) { + if (IsEntryFrameMarker(pc)) { // Pop entry frame. - fp_ = SavedCallerFP(FP); + RawObject** entry_fp = SavedCallerFP(FP); // Restore exit frame info saved in entry frame. - pp_ = reinterpret_cast<RawObjectPool*>(fp_[kKBCSavedPpSlotFromEntryFp]); - argdesc_ = - reinterpret_cast<RawArray*>(fp_[kKBCSavedArgDescSlotFromEntryFp]); - uword exit_fp = reinterpret_cast<uword>(fp_[kKBCExitLinkSlotFromEntryFp]); + pp_ = reinterpret_cast<RawObjectPool*>( + entry_fp[kKBCSavedPpSlotFromEntryFp]); + argdesc_ = reinterpret_cast<RawArray*>( + entry_fp[kKBCSavedArgDescSlotFromEntryFp]); + uword exit_fp = + reinterpret_cast<uword>(entry_fp[kKBCExitLinkSlotFromEntryFp]); thread->set_top_exit_frame_info(exit_fp); thread->set_top_resource(top_resource); thread->set_vm_tag(vm_tag); + fp_ = entry_fp; + NOT_IN_PRODUCT(pc_ = pc); // For the profiler. #if defined(DEBUG) if (IsTracingExecution()) { THR_Print("%" Pu64 " ", icount_); @@ -2262,7 +2321,8 @@ // Restore SP, FP and PP. Push result and dispatch. SP = FrameArguments(FP, argc); FP = SavedCallerFP(FP); - fp_ = FP; // For the profiler. + NOT_IN_PRODUCT(fp_ = FP); // For the profiler. + NOT_IN_PRODUCT(pc_ = pc); // For the profiler. pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_; *SP = result; DISPATCH(); @@ -2315,7 +2375,7 @@ double raw_value = Double::RawCast(value)->ptr()->value_; ASSERT(*(reinterpret_cast<RawDouble**>(instance->ptr()) + offset_in_words) == null_value); // Initializing store. - if (!AllocateDoubleBox(thread, raw_value, pc, FP, SP)) { + if (!AllocateDouble(thread, raw_value, pc, FP, SP)) { HANDLE_EXCEPTION; } RawDouble* box = Double::RawCast(SP[0]); @@ -2328,7 +2388,7 @@ raw_value.readFrom(Float32x4::RawCast(value)->ptr()->value_); ASSERT(*(reinterpret_cast<RawFloat32x4**>(instance->ptr()) + offset_in_words) == null_value); // Initializing store. - if (!AllocateFloat32x4Box(thread, raw_value, pc, FP, SP)) { + if (!AllocateFloat32x4(thread, raw_value, pc, FP, SP)) { HANDLE_EXCEPTION; } RawFloat32x4* box = Float32x4::RawCast(SP[0]); @@ -2341,7 +2401,7 @@ raw_value.readFrom(Float64x2::RawCast(value)->ptr()->value_); ASSERT(*(reinterpret_cast<RawFloat64x2**>(instance->ptr()) + offset_in_words) == null_value); // Initializing store. - if (!AllocateFloat64x2Box(thread, raw_value, pc, FP, SP)) { + if (!AllocateFloat64x2(thread, raw_value, pc, FP, SP)) { HANDLE_EXCEPTION; } RawFloat64x2* box = Float64x2::RawCast(SP[0]); @@ -2436,17 +2496,32 @@ DISPATCH(); } - // TODO(vegorov) allocation bytecodes can benefit from the new-space - // allocation fast-path that does not transition into the runtime system. { BYTECODE(AllocateContext, A_D); const uint16_t num_context_variables = rD; { - *++SP = 0; - SP[1] = Smi::New(num_context_variables); - Exit(thread, FP, SP + 2, pc); - NativeArguments args(thread, 1, SP + 1, SP); - INVOKE_RUNTIME(DRT_AllocateContext, args); + const intptr_t instance_size = + Context::InstanceSize(num_context_variables); + ASSERT(Utils::IsAligned(instance_size, kObjectAlignment)); + const uword start = thread->top(); + if (LIKELY((start + instance_size) < thread->end())) { + thread->set_top(start + instance_size); + RawContext* result = Context::RawCast( + InitializeHeader(start, kContextCid, instance_size)); + result->ptr()->num_variables_ = num_context_variables; + result->ptr()->parent_ = static_cast<RawContext*>(null_value); + for (intptr_t offset = sizeof(RawContext); offset < instance_size; + offset += kWordSize) { + *reinterpret_cast<RawObject**>(start + offset) = null_value; + } + *++SP = result; + } else { + *++SP = 0; + SP[1] = Smi::New(num_context_variables); + Exit(thread, FP, SP + 2, pc); + NativeArguments args(thread, 1, SP + 1, SP); + INVOKE_RUNTIME(DRT_AllocateContext, args); + } } DISPATCH(); } @@ -2464,9 +2539,27 @@ { BYTECODE(Allocate, A_D); - SP[1] = 0; // Space for the result. - SP[2] = LOAD_CONSTANT(rD); // Class object. - SP[3] = null_value; // Type arguments. + RawClass* cls = Class::RawCast(LOAD_CONSTANT(rD)); + if (LIKELY(InterpreterHelpers::IsFinalized(cls))) { + const intptr_t class_id = cls->ptr()->id_; + const intptr_t instance_size = cls->ptr()->instance_size_in_words_ + << kWordSizeLog2; + const uword start = thread->top(); + if (LIKELY((start + instance_size) < thread->end())) { + thread->set_top(start + instance_size); + RawObject* result = InitializeHeader(start, class_id, instance_size); + for (intptr_t offset = sizeof(RawInstance); offset < instance_size; + offset += kWordSize) { + *reinterpret_cast<RawObject**>(start + offset) = null_value; + } + *++SP = result; + DISPATCH(); + } + } + + SP[1] = 0; // Space for the result. + SP[2] = cls; // Class object. + SP[3] = null_value; // Type arguments. Exit(thread, FP, SP + 4, pc); NativeArguments args(thread, 2, SP + 2, SP + 1); INVOKE_RUNTIME(DRT_AllocateObject, args); @@ -2476,8 +2569,30 @@ { BYTECODE(AllocateT, 0); - SP[1] = SP[-0]; // Class object. - SP[2] = SP[-1]; // Type arguments + RawClass* cls = Class::RawCast(SP[0]); + RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]); + if (LIKELY(InterpreterHelpers::IsFinalized(cls))) { + const intptr_t class_id = cls->ptr()->id_; + const intptr_t instance_size = cls->ptr()->instance_size_in_words_ + << kWordSizeLog2; + const uword start = thread->top(); + if (LIKELY((start + instance_size) < thread->end())) { + thread->set_top(start + instance_size); + RawObject* result = InitializeHeader(start, class_id, instance_size); + for (intptr_t offset = sizeof(RawInstance); offset < instance_size; + offset += kWordSize) { + *reinterpret_cast<RawObject**>(start + offset) = null_value; + } + const intptr_t type_args_offset = + cls->ptr()->type_arguments_field_offset_in_words_ << kWordSizeLog2; + *reinterpret_cast<RawObject**>(start + type_args_offset) = type_args; + *--SP = result; + DISPATCH(); + } + } + + SP[1] = cls; + SP[2] = type_args; Exit(thread, FP, SP + 3, pc); NativeArguments args(thread, 2, SP + 1, SP - 1); INVOKE_RUNTIME(DRT_AllocateObject, args); @@ -2487,12 +2602,12 @@ { BYTECODE(CreateArrayTOS, 0); - SP[1] = SP[-0]; // Length. - SP[2] = SP[-1]; // Type. - Exit(thread, FP, SP + 3, pc); - NativeArguments args(thread, 2, SP + 1, SP - 1); - INVOKE_RUNTIME(DRT_AllocateArray, args); - SP -= 1; + RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]); + RawObject* length = SP[0]; + SP--; + if (!AllocateArray(thread, type_args, length, pc, FP, SP)) { + HANDLE_EXCEPTION; + } DISPATCH(); } @@ -2856,6 +2971,32 @@ } { + BYTECODE(AllocateClosure, A_D); + const intptr_t instance_size = Closure::InstanceSize(); + const uword start = thread->top(); + if (LIKELY((start + instance_size) < thread->end())) { + thread->set_top(start + instance_size); + RawClosure* result = + Closure::RawCast(InitializeHeader(start, kClosureCid, instance_size)); + for (intptr_t offset = sizeof(RawInstance); offset < instance_size; + offset += kWordSize) { + *reinterpret_cast<RawObject**>(start + offset) = null_value; + } + SP[1] = result; + ++SP; + } else { + SP[1] = 0; // Space for the result. + SP[2] = thread->isolate()->object_store()->closure_class(); + SP[3] = null_value; // Type arguments. + Exit(thread, FP, SP + 4, pc); + NativeArguments args(thread, 2, SP + 2, SP + 1); + INVOKE_RUNTIME(DRT_AllocateObject, args); + ++SP; + } + DISPATCH(); + } + + { BYTECODE(Trap, 0); UNIMPLEMENTED(); DISPATCH(); @@ -2863,9 +3004,22 @@ { BYTECODE(VMInternal_ImplicitGetter, 0); + + RawFunction* function = FrameFunction(FP); + int32_t counter = ++(function->ptr()->usage_counter_); + if (UNLIKELY(FLAG_compilation_counter_threshold >= 0 && + counter >= FLAG_compilation_counter_threshold && + !Function::HasCode(function))) { + SP[1] = 0; // Unused code result. + SP[2] = function; + Exit(thread, FP, SP + 3, pc); + NativeArguments native_args(thread, 1, SP + 2, SP + 1); + INVOKE_RUNTIME(DRT_OptimizeInvokedFunction, native_args); + function = FrameFunction(FP); + } + // Field object is cached in function's data_. - RawField* field = - reinterpret_cast<RawField*>(FrameFunction(FP)->ptr()->data_); + RawField* field = reinterpret_cast<RawField*>(function->ptr()->data_); intptr_t offset_in_words = Smi::Value(field->ptr()->value_.offset_); const intptr_t kArgc = 1; @@ -2882,22 +3036,22 @@ classid_t guarded_cid = field->ptr()->guarded_cid_; if (unboxing && (guarded_cid == kDoubleCid)) { double raw_value = Double::RawCast(value)->ptr()->value_; - // AllocateDoubleBox places result at SP[0] - if (!AllocateDoubleBox(thread, raw_value, pc, FP, SP)) { + // AllocateDouble places result at SP[0] + if (!AllocateDouble(thread, raw_value, pc, FP, SP)) { HANDLE_EXCEPTION; } } else if (unboxing && (guarded_cid == kFloat32x4Cid)) { simd128_value_t raw_value; raw_value.readFrom(Float32x4::RawCast(value)->ptr()->value_); - // AllocateFloat32x4Box places result at SP[0] - if (!AllocateFloat32x4Box(thread, raw_value, pc, FP, SP)) { + // AllocateFloat32x4 places result at SP[0] + if (!AllocateFloat32x4(thread, raw_value, pc, FP, SP)) { HANDLE_EXCEPTION; } } else if (unboxing && (guarded_cid == kFloat64x2Cid)) { simd128_value_t raw_value; raw_value.readFrom(Float64x2::RawCast(value)->ptr()->value_); - // AllocateFloat64x2Box places result at SP[0] - if (!AllocateFloat64x2Box(thread, raw_value, pc, FP, SP)) { + // AllocateFloat64x2 places result at SP[0] + if (!AllocateFloat64x2(thread, raw_value, pc, FP, SP)) { HANDLE_EXCEPTION; } } @@ -2907,9 +3061,22 @@ { BYTECODE(VMInternal_ImplicitSetter, 0); + + RawFunction* function = FrameFunction(FP); + int32_t counter = ++(function->ptr()->usage_counter_); + if (UNLIKELY(FLAG_compilation_counter_threshold >= 0 && + counter >= FLAG_compilation_counter_threshold && + !Function::HasCode(function))) { + SP[1] = 0; // Unused code result. + SP[2] = function; + Exit(thread, FP, SP + 3, pc); + NativeArguments native_args(thread, 1, SP + 2, SP + 1); + INVOKE_RUNTIME(DRT_OptimizeInvokedFunction, native_args); + function = FrameFunction(FP); + } + // Field object is cached in function's data_. - RawField* field = - reinterpret_cast<RawField*>(FrameFunction(FP)->ptr()->data_); + RawField* field = reinterpret_cast<RawField*>(function->ptr()->data_); intptr_t offset_in_words = Smi::Value(field->ptr()->value_.offset_); const intptr_t kArgc = 2; RawInstance* instance = @@ -3039,8 +3206,7 @@ // Restore caller context as we are going to throw NoSuchMethod. pc = SavedCallerPC(FP); - const bool has_dart_caller = - !IsEntryFrameMarker(reinterpret_cast<uword>(pc)); + const bool has_dart_caller = !IsEntryFrameMarker(pc); const intptr_t argc = has_dart_caller ? KernelBytecode::DecodeArgc(pc[-1]) : (reinterpret_cast<uword>(pc) >> 2); const intptr_t type_args_len = @@ -3050,7 +3216,7 @@ SP = FrameArguments(FP, 0); RawObject** args = SP - argc; FP = SavedCallerFP(FP); - fp_ = FP; // For the profiler. + NOT_IN_PRODUCT(fp_ = FP); // For the profiler. if (has_dart_caller) { pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_; } @@ -3159,9 +3325,9 @@ thread->set_active_stacktrace(Object::null_object()); special_[KernelBytecode::kExceptionSpecialIndex] = raw_exception; special_[KernelBytecode::kStackTraceSpecialIndex] = raw_stacktrace; - pc_ = thread->resume_pc(); + pc_ = reinterpret_cast<uint32_t*>(thread->resume_pc()); } else { - pc_ = pc; + pc_ = reinterpret_cast<uint32_t*>(pc); } // Set the tag.
diff --git a/runtime/vm/interpreter.h b/runtime/vm/interpreter.h index effc48a..165a6d7 100644 --- a/runtime/vm/interpreter.h +++ b/runtime/vm/interpreter.h
@@ -26,6 +26,7 @@ class RawFunction; class RawString; class RawSubtypeTestCache; +class RawTypeArguments; class ObjectPointerVisitor; class LookupCache : public ValueObject { @@ -93,7 +94,9 @@ } // Identify an entry frame by looking at its pc marker value. - static bool IsEntryFrameMarker(uword pc) { return (pc & 2) != 0; } + static bool IsEntryFrameMarker(uint32_t* pc) { + return (reinterpret_cast<uword>(pc) & 2) != 0; + } RawObject* Call(const Function& function, const Array& arguments_descriptor, @@ -110,7 +113,9 @@ uword get_sp() const { return reinterpret_cast<uword>(fp_); } // Yes, fp_. uword get_fp() const { return reinterpret_cast<uword>(fp_); } - uword get_pc() const { return pc_; } + uword get_pc() const { return reinterpret_cast<uword>(pc_); } + + void Unexit(Thread* thread); void VisitObjectPointers(ObjectPointerVisitor* visitor); void MajorGC() { lookup_cache_.Clear(); } @@ -121,8 +126,8 @@ uword overflow_stack_limit_; uword stack_limit_; - RawObject** fp_; - uword pc_; + RawObject** volatile fp_; + uint32_t* volatile pc_; DEBUG_ONLY(uint64_t icount_;) InterpreterSetjmpBuffer* last_setjmp_buffer_; @@ -205,26 +210,32 @@ RawObject** args, RawSubtypeTestCache* cache); - bool AllocateInt64Box(Thread* thread, - int64_t value, - uint32_t* pc, - RawObject** FP, - RawObject** SP); - bool AllocateDoubleBox(Thread* thread, - double value, + bool AllocateMint(Thread* thread, + int64_t value, + uint32_t* pc, + RawObject** FP, + RawObject** SP); + bool AllocateDouble(Thread* thread, + double value, + uint32_t* pc, + RawObject** FP, + RawObject** SP); + bool AllocateFloat32x4(Thread* thread, + simd128_value_t value, uint32_t* pc, RawObject** FP, RawObject** SP); - bool AllocateFloat32x4Box(Thread* thread, - simd128_value_t value, - uint32_t* pc, - RawObject** FP, - RawObject** SP); - bool AllocateFloat64x2Box(Thread* thread, - simd128_value_t value, - uint32_t* pc, - RawObject** FP, - RawObject** SP); + bool AllocateFloat64x2(Thread* thread, + simd128_value_t value, + uint32_t* pc, + RawObject** FP, + RawObject** SP); + bool AllocateArray(Thread* thread, + RawTypeArguments* type_args, + RawObject* length, + uint32_t* pc, + RawObject** FP, + RawObject** SP); #if defined(DEBUG) // Returns true if tracing of executed instructions is enabled.
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc index b99c204..49caa27 100644 --- a/runtime/vm/isolate.cc +++ b/runtime/vm/isolate.cc
@@ -866,6 +866,7 @@ heap_(NULL), isolate_flags_(0), background_compiler_(NULL), + optimizing_background_compiler_(NULL), #if !defined(PRODUCT) debugger_(NULL), last_resume_timestamp_(OS::GetCurrentTimeMillis()), @@ -951,7 +952,11 @@ " See dartbug.com/30524 for more information.\n"); } - NOT_IN_PRECOMPILED(background_compiler_ = new BackgroundCompiler(this)); + if (FLAG_enable_interpreter) { + NOT_IN_PRECOMPILED(background_compiler_ = new BackgroundCompiler(this)); + } + NOT_IN_PRECOMPILED(optimizing_background_compiler_ = + new BackgroundCompiler(this)); } #undef REUSABLE_HANDLE_SCOPE_INIT @@ -966,8 +971,13 @@ delete reverse_pc_lookup_cache_; reverse_pc_lookup_cache_ = nullptr; - delete background_compiler_; - background_compiler_ = NULL; + if (FLAG_enable_interpreter) { + delete background_compiler_; + background_compiler_ = NULL; + } + + delete optimizing_background_compiler_; + optimizing_background_compiler_ = NULL; #if !defined(PRODUCT) delete debugger_; @@ -1862,8 +1872,12 @@ void Isolate::Shutdown() { ASSERT(this == Isolate::Current()); BackgroundCompiler::Stop(this); - delete background_compiler_; - background_compiler_ = NULL; + if (FLAG_enable_interpreter) { + delete background_compiler_; + background_compiler_ = NULL; + } + delete optimizing_background_compiler_; + optimizing_background_compiler_ = NULL; #if defined(DEBUG) if (heap_ != NULL && FLAG_verify_on_transition) { @@ -1986,6 +2000,9 @@ if (background_compiler() != NULL) { background_compiler()->VisitPointers(visitor); } + if (optimizing_background_compiler() != NULL) { + optimizing_background_compiler()->VisitPointers(visitor); + } #if !defined(PRODUCT) // Visit objects in the debugger.
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h index c4dd373..584eeae 100644 --- a/runtime/vm/isolate.h +++ b/runtime/vm/isolate.h
@@ -479,6 +479,10 @@ return background_compiler_; } + BackgroundCompiler* optimizing_background_compiler() const { + return optimizing_background_compiler_; + } + #if !defined(PRODUCT) void UpdateLastAllocationProfileAccumulatorResetTimestamp() { last_allocationprofile_accumulator_reset_timestamp_ = @@ -697,6 +701,13 @@ return FLAG_use_strong_mode_types && !unsafe_trust_strong_mode_types(); } + // Whether it's possible for unoptimized code to optimize immediately on entry + // (can happen with random or very low optimization counter thresholds) + bool CanOptimizeImmediately() const { + return FLAG_optimization_counter_threshold < 2 || + FLAG_randomize_optimization_counter; + } + bool should_load_vmservice() const { return ShouldLoadVmServiceBit::decode(isolate_flags_); } @@ -909,9 +920,12 @@ uint32_t isolate_flags_; - // Background compilation. + // Unoptimized background compilation. BackgroundCompiler* background_compiler_; + // Optimized background compilation. + BackgroundCompiler* optimizing_background_compiler_; + // Fields that aren't needed in a product build go here with boolean flags at // the top. #if !defined(PRODUCT)
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc index 381a50b..76e8e9d 100644 --- a/runtime/vm/isolate_reload.cc +++ b/runtime/vm/isolate_reload.cc
@@ -1890,151 +1890,34 @@ // new ones. } -class MarkFunctionsForRecompilation : public ObjectVisitor { +class InvalidationCollector : public ObjectVisitor { public: - MarkFunctionsForRecompilation(Isolate* isolate, - IsolateReloadContext* reload_context, - Zone* zone) - : ObjectVisitor(), - handle_(Object::Handle(zone)), - owning_class_(Class::Handle(zone)), - owning_lib_(Library::Handle(zone)), - code_(Code::Handle(zone)), - bytecode_(Bytecode::Handle(zone)), - reload_context_(reload_context), - zone_(zone) {} + InvalidationCollector(Zone* zone, + GrowableArray<const Function*>* functions, + GrowableArray<const KernelProgramInfo*>* kernel_infos) + : zone_(zone), functions_(functions), kernel_infos_(kernel_infos) {} + virtual ~InvalidationCollector() {} virtual void VisitObject(RawObject* obj) { if (obj->IsPseudoObject()) { - // Cannot even be wrapped in handles. - return; + return; // Cannot be wrapped in handles. } - handle_ = obj; - if (handle_.IsFunction()) { - const Function& func = Function::Cast(handle_); - if (func.IsSignatureFunction()) { - return; - } - - // Switch to unoptimized code or the lazy compilation stub. - func.SwitchToLazyCompiledUnoptimizedCode(); - - // Grab the current code. - code_ = func.CurrentCode(); - ASSERT(!code_.IsNull()); - bytecode_ = func.bytecode(); - const bool clear_code = IsFromDirtyLibrary(func); - const bool stub_code = code_.IsStubCode(); - - // Zero edge counters. - func.ZeroEdgeCounters(); - - if (!stub_code || !bytecode_.IsNull()) { - if (clear_code) { - VTIR_Print("Marking %s for recompilation, clearing code\n", - func.ToCString()); - ClearAllCode(func); - } else { - if (!stub_code) { - PreserveUnoptimizedCode(); - } - if (!bytecode_.IsNull()) { - PreserveBytecode(); - } - } - } - - // Clear counters. - func.set_usage_counter(0); - func.set_deoptimization_counter(0); - func.set_optimized_instruction_count(0); - func.set_optimized_call_site_count(0); + const Object& handle = Object::Handle(zone_, obj); + if (handle.IsFunction()) { + functions_->Add(&Function::Cast(handle)); + } else if (handle.IsKernelProgramInfo()) { + kernel_infos_->Add(&KernelProgramInfo::Cast(handle)); } } private: - void ClearAllCode(const Function& func) { - // Null out the ICData array and code. - func.ClearICDataArray(); - func.ClearCode(); - func.SetWasCompiled(false); - } - - void PreserveUnoptimizedCode() { - ASSERT(!code_.IsNull()); - // We are preserving the unoptimized code, fill all ICData arrays with - // the sentinel values so that we have no stale type feedback. - code_.ResetICDatas(zone_); - } - - void PreserveBytecode() { - ASSERT(!bytecode_.IsNull()); - // We are preserving the bytecode, fill all ICData arrays with - // the sentinel values so that we have no stale type feedback. - bytecode_.ResetICDatas(zone_); - } - - bool IsFromDirtyLibrary(const Function& func) { - owning_class_ = func.Owner(); - owning_lib_ = owning_class_.library(); - return reload_context_->IsDirty(owning_lib_); - } - - Object& handle_; - Class& owning_class_; - Library& owning_lib_; - Code& code_; - Bytecode& bytecode_; - IsolateReloadContext* reload_context_; - Zone* zone_; + Zone* const zone_; + GrowableArray<const Function*>* const functions_; + GrowableArray<const KernelProgramInfo*>* const kernel_infos_; }; typedef UnorderedHashMap<SmiTraits> IntHashMap; -class InvalidateKernelInfoCaches : public ObjectVisitor { - public: - explicit InvalidateKernelInfoCaches(Zone* zone) - : ObjectVisitor(), - handle_(Object::Handle(zone)), - data_(Array::Handle(zone)), - key_(Object::Handle(zone)), - value_(Smi::Handle(zone)) {} - - virtual void VisitObject(RawObject* obj) { - if (obj->IsPseudoObject()) { - // Cannot even be wrapped in handles. - return; - } - handle_ = obj; - if (!handle_.IsKernelProgramInfo()) { - return; - } - const KernelProgramInfo& info = KernelProgramInfo::Cast(handle_); - // Clear the libraries cache. - { - data_ ^= info.libraries_cache(); - ASSERT(!data_.IsNull()); - IntHashMap table(&key_, &value_, &data_); - table.Clear(); - info.set_libraries_cache(table.Release()); - } - // Clear the classes cache. - { - data_ ^= info.classes_cache(); - ASSERT(!data_.IsNull()); - IntHashMap table(&key_, &value_, &data_); - table.Clear(); - info.set_classes_cache(table.Release()); - } - } - - private: - Object& handle_; - Array& data_; - Object& key_; - Smi& value_; -}; - void IsolateReloadContext::RunInvalidationVisitors() { TIMELINE_SCOPE(MarkAllFunctionsForRecompilation); TIR_Print("---- RUNNING INVALIDATION HEAP VISITORS\n"); @@ -2042,15 +1925,92 @@ StackZone stack_zone(thread); Zone* zone = stack_zone.GetZone(); - HeapIterationScope iteration(thread); - GrowableArray<ObjectVisitor*> arr(zone, 2); - ExtensibleObjectVisitor visitor(&arr); - MarkFunctionsForRecompilation function_visitor(isolate_, this, zone); - InvalidateKernelInfoCaches kernel_info_visitor(zone); + GrowableArray<const Function*> functions(4 * KB); + GrowableArray<const KernelProgramInfo*> kernel_infos(KB); - visitor.Add(&function_visitor); - visitor.Add(&kernel_info_visitor); - iteration.IterateObjects(&visitor); + { + HeapIterationScope iteration(thread); + InvalidationCollector visitor(zone, &functions, &kernel_infos); + iteration.IterateObjects(&visitor); + } + + Array& data = Array::Handle(zone); + Object& key = Object::Handle(zone); + Smi& value = Smi::Handle(zone); + for (intptr_t i = 0; i < kernel_infos.length(); i++) { + const KernelProgramInfo& info = *kernel_infos[i]; + // Clear the libraries cache. + { + data ^= info.libraries_cache(); + ASSERT(!data.IsNull()); + IntHashMap table(&key, &value, &data); + table.Clear(); + info.set_libraries_cache(table.Release()); + } + // Clear the classes cache. + { + data ^= info.classes_cache(); + ASSERT(!data.IsNull()); + IntHashMap table(&key, &value, &data); + table.Clear(); + info.set_classes_cache(table.Release()); + } + } + + Class& owning_class = Class::Handle(zone); + Library& owning_lib = Library::Handle(zone); + Code& code = Code::Handle(zone); + Bytecode& bytecode = Bytecode::Handle(zone); + for (intptr_t i = 0; i < functions.length(); i++) { + const Function& func = *functions[i]; + if (func.IsSignatureFunction()) { + continue; + } + + // Switch to unoptimized code or the lazy compilation stub. + func.SwitchToLazyCompiledUnoptimizedCode(); + + // Grab the current code. + code = func.CurrentCode(); + ASSERT(!code.IsNull()); + bytecode = func.bytecode(); + + owning_class = func.Owner(); + owning_lib = owning_class.library(); + const bool clear_code = IsDirty(owning_lib); + const bool stub_code = code.IsStubCode(); + + // Zero edge counters. + func.ZeroEdgeCounters(); + + if (!stub_code || !bytecode.IsNull()) { + if (clear_code) { + VTIR_Print("Marking %s for recompilation, clearing code\n", + func.ToCString()); + // Null out the ICData array and code. + func.ClearICDataArray(); + func.ClearCode(); + func.SetWasCompiled(false); + } else { + if (!stub_code) { + // We are preserving the unoptimized code, fill all ICData arrays with + // the sentinel values so that we have no stale type feedback. + code.ResetICDatas(zone); + } + if (!bytecode.IsNull()) { + // We are preserving the bytecode, fill all ICData arrays with + // the sentinel values so that we have no stale type feedback. + bytecode.ResetICDatas(zone); + } + } + } + + // Clear counters. + func.set_usage_counter(0); + func.set_deoptimization_counter(0); + func.set_optimized_instruction_count(0); + func.set_optimized_call_site_count(0); + } } void IsolateReloadContext::InvalidateWorld() {
diff --git a/runtime/vm/isolate_test.cc b/runtime/vm/isolate_test.cc index a9d3a85..b019598c 100644 --- a/runtime/vm/isolate_test.cc +++ b/runtime/vm/isolate_test.cc
@@ -43,30 +43,30 @@ // Necessary because asynchronous errors use "print" to print their // stack trace. Dart_Handle url = NewString("dart:_internal"); - DART_CHECK_VALID(url); + EXPECT_VALID(url); Dart_Handle internal_lib = Dart_LookupLibrary(url); - DART_CHECK_VALID(internal_lib); + EXPECT_VALID(internal_lib); Dart_Handle print = Dart_GetField(test_lib, NewString("_nullPrintClosure")); Dart_Handle result = Dart_SetField(internal_lib, NewString("_printClosure"), print); - DART_CHECK_VALID(result); + EXPECT_VALID(result); // Setup the 'scheduleImmediate' closure. url = NewString("dart:isolate"); - DART_CHECK_VALID(url); + EXPECT_VALID(url); Dart_Handle isolate_lib = Dart_LookupLibrary(url); - DART_CHECK_VALID(isolate_lib); + EXPECT_VALID(isolate_lib); Dart_Handle schedule_immediate_closure = Dart_Invoke( isolate_lib, NewString("_getIsolateScheduleImmediateClosure"), 0, NULL); Dart_Handle args[1]; args[0] = schedule_immediate_closure; url = NewString("dart:async"); - DART_CHECK_VALID(url); + EXPECT_VALID(url); Dart_Handle async_lib = Dart_LookupLibrary(url); - DART_CHECK_VALID(async_lib); - DART_CHECK_VALID(Dart_Invoke( - async_lib, NewString("_setScheduleImmediateClosure"), 1, args)); + EXPECT_VALID(async_lib); + EXPECT_VALID(Dart_Invoke(async_lib, NewString("_setScheduleImmediateClosure"), + 1, args)); result = Dart_Invoke(test_lib, NewString("testMain"), 0, NULL); EXPECT_VALID(result);
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h index ab22ff4..96c4986 100644 --- a/runtime/vm/kernel_binary.h +++ b/runtime/vm/kernel_binary.h
@@ -20,7 +20,7 @@ // Both version numbers are inclusive. static const uint32_t kMinSupportedKernelFormatVersion = 18; -static const uint32_t kMaxSupportedKernelFormatVersion = 22; +static const uint32_t kMaxSupportedKernelFormatVersion = 23; // Keep in sync with package:kernel/lib/binary/tag.dart #define KERNEL_TAG_LIST(V) \ @@ -65,6 +65,7 @@ V(ListConcatenation, 111) \ V(SetConcatenation, 112) \ V(MapConcatenation, 113) \ + V(InstanceCreation, 114) \ V(IsExpression, 37) \ V(AsExpression, 38) \ V(StringLiteral, 39) \
diff --git a/runtime/vm/malloc_hooks_arm.cc b/runtime/vm/malloc_hooks_arm.cc index 7e857e5..e344434 100644 --- a/runtime/vm/malloc_hooks_arm.cc +++ b/runtime/vm/malloc_hooks_arm.cc
@@ -10,7 +10,7 @@ namespace dart { -const intptr_t kSkipCount = 5; +const intptr_t kSkipCount = 4; } // namespace dart
diff --git a/runtime/vm/malloc_hooks_arm64.cc b/runtime/vm/malloc_hooks_arm64.cc index e50ea0b..d063748 100644 --- a/runtime/vm/malloc_hooks_arm64.cc +++ b/runtime/vm/malloc_hooks_arm64.cc
@@ -10,7 +10,7 @@ namespace dart { -const intptr_t kSkipCount = 5; +const intptr_t kSkipCount = 4; } // namespace dart
diff --git a/runtime/vm/malloc_hooks_ia32.cc b/runtime/vm/malloc_hooks_ia32.cc index 2b7a371..b056456 100644 --- a/runtime/vm/malloc_hooks_ia32.cc +++ b/runtime/vm/malloc_hooks_ia32.cc
@@ -11,9 +11,9 @@ namespace dart { #if defined(DEBUG) -const intptr_t kSkipCount = 6; -#elif !(defined(PRODUCT) || defined(DEBUG)) const intptr_t kSkipCount = 5; +#elif !(defined(PRODUCT) || defined(DEBUG)) +const intptr_t kSkipCount = 4; #endif } // namespace dart
diff --git a/runtime/vm/malloc_hooks_x64.cc b/runtime/vm/malloc_hooks_x64.cc index 2ec564b..25e2283 100644 --- a/runtime/vm/malloc_hooks_x64.cc +++ b/runtime/vm/malloc_hooks_x64.cc
@@ -11,9 +11,9 @@ namespace dart { #if defined(DEBUG) -const intptr_t kSkipCount = 6; -#elif !(defined(PRODUCT) || defined(DEBUG)) const intptr_t kSkipCount = 5; +#elif !(defined(PRODUCT) || defined(DEBUG)) +const intptr_t kSkipCount = 4; #endif } // namespace dart
diff --git a/runtime/vm/metrics.cc b/runtime/vm/metrics.cc index 99bc372..c20cfc7 100644 --- a/runtime/vm/metrics.cc +++ b/runtime/vm/metrics.cc
@@ -303,9 +303,14 @@ return Service::MaxRSS(); } +#define VM_METRIC_VARIABLE(type, variable, name, unit) \ + type vm_metric_##variable; +VM_METRIC_LIST(VM_METRIC_VARIABLE); +#undef VM_METRIC_VARIABLE + void Metric::Init() { #define VM_METRIC_INIT(type, variable, name, unit) \ - vm_metric_##variable##_.InitInstance(name, NULL, Metric::unit); + vm_metric_##variable.InitInstance(name, NULL, Metric::unit); VM_METRIC_LIST(VM_METRIC_INIT); #undef VM_METRIC_INIT } @@ -323,7 +328,7 @@ OS::PrintErr("\n"); } #define VM_METRIC_CLEANUP(type, variable, name, unit) \ - vm_metric_##variable##_.CleanupInstance(); + vm_metric_##variable.CleanupInstance(); VM_METRIC_LIST(VM_METRIC_CLEANUP); #undef VM_METRIC_CLEANUP }
diff --git a/runtime/vm/metrics.h b/runtime/vm/metrics.h index 75f0781..b54fc12 100644 --- a/runtime/vm/metrics.h +++ b/runtime/vm/metrics.h
@@ -182,7 +182,7 @@ #if !defined(PRODUCT) #define VM_METRIC_VARIABLE(type, variable, name, unit) \ - static type vm_metric_##variable##_; + extern type vm_metric_##variable; VM_METRIC_LIST(VM_METRIC_VARIABLE); #undef VM_METRIC_VARIABLE #endif // !defined(PRODUCT)
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index ac67816..0397d9c 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc
@@ -2588,6 +2588,10 @@ } void Class::set_type_parameters(const TypeArguments& value) const { + ASSERT((num_own_type_arguments() == kUnknownNumTypeArguments) || + is_prefinalized()); + ASSERT((num_type_arguments() == kUnknownNumTypeArguments) || + is_prefinalized()); StorePointer(&raw_ptr()->type_parameters_, value.raw()); } @@ -13146,14 +13150,24 @@ } #if !defined(DART_PRECOMPILED_RUNTIME) -void ICData::SetStaticReceiverType(const AbstractType& type) const { - StorePointer(&raw_ptr()->static_receiver_type_, type.raw()); +void ICData::SetReceiversStaticType(const AbstractType& type) const { + StorePointer(&raw_ptr()->receivers_static_type_, type.raw()); + +#if defined(TARGET_ARCH_X64) + if (!type.IsNull() && type.HasTypeClass() && (NumArgsTested() == 1) && + type.IsInstantiated()) { + const Class& cls = Class::Handle(type.type_class()); + if (cls.IsGeneric() && !cls.IsFutureOrClass()) { + set_tracking_exactness(true); + } + } +#endif // defined(TARGET_ARCH_X64) } #endif void ICData::ResetSwitchable(Zone* zone) const { ASSERT(NumArgsTested() == 1); - ASSERT(!IsTrackingExactness()); + ASSERT(!is_tracking_exactness()); set_entries(Array::Handle(zone, CachedEmptyICDataArray(1, false))); } @@ -13298,7 +13312,7 @@ } intptr_t ICData::TestEntryLength() const { - return TestEntryLengthFor(NumArgsTested(), IsTrackingExactness()); + return TestEntryLengthFor(NumArgsTested(), is_tracking_exactness()); } intptr_t ICData::Length() const { @@ -13535,7 +13549,7 @@ void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids, const Function& target, intptr_t count) const { - ASSERT(!IsTrackingExactness()); + ASSERT(!is_tracking_exactness()); ASSERT(!target.IsNull()); ASSERT((target.name() == target_name()) || ValidateInterceptor(target)); DEBUG_ASSERT(!HasCheck(class_ids)); @@ -13648,7 +13662,7 @@ if (Isolate::Current()->compilation_allowed()) { data.SetAt(data_pos + 1, target); data.SetAt(data_pos + 2, Smi::Handle(Smi::New(count))); - if (IsTrackingExactness()) { + if (is_tracking_exactness()) { data.SetAt(data_pos + 3, Smi::Handle(Smi::New(exactness.Encode()))); } } else { @@ -13666,7 +13680,7 @@ } StaticTypeExactnessState ICData::GetExactnessAt(intptr_t index) const { - if (!IsTrackingExactness()) { + if (!is_tracking_exactness()) { return StaticTypeExactnessState::NotTracking(); } const Array& data = Array::Handle(entries()); @@ -14086,7 +14100,7 @@ intptr_t deopt_id, intptr_t num_args_tested, RebindRule rebind_rule, - const AbstractType& static_receiver_type) { + const AbstractType& receivers_static_type) { ASSERT(!owner.IsNull()); ASSERT(!target_name.IsNull()); ASSERT(!arguments_descriptor.IsNull()); @@ -14107,7 +14121,7 @@ result.set_state_bits(0); result.set_rebind_rule(rebind_rule); result.SetNumArgsTested(num_args_tested); - NOT_IN_PRECOMPILED(result.SetStaticReceiverType(static_receiver_type)); + NOT_IN_PRECOMPILED(result.SetReceiversStaticType(receivers_static_type)); return result.raw(); } @@ -14136,15 +14150,15 @@ intptr_t deopt_id, intptr_t num_args_tested, RebindRule rebind_rule, - const AbstractType& static_receiver_type) { + const AbstractType& receivers_static_type) { Zone* zone = Thread::Current()->zone(); const ICData& result = ICData::Handle( zone, NewDescriptor(zone, owner, target_name, arguments_descriptor, deopt_id, - num_args_tested, rebind_rule, static_receiver_type)); + num_args_tested, rebind_rule, receivers_static_type)); result.set_entries(Array::Handle( zone, - CachedEmptyICDataArray(num_args_tested, result.IsTrackingExactness()))); + CachedEmptyICDataArray(num_args_tested, result.is_tracking_exactness()))); return result.raw(); } @@ -14154,7 +14168,7 @@ Function::Handle(from.Owner()), String::Handle(from.target_name()), Array::Handle(from.arguments_descriptor()), from.deopt_id(), num_args_tested, from.rebind_rule(), - AbstractType::Handle(from.StaticReceiverType()))); + AbstractType::Handle(from.receivers_static_type()))); // Copy deoptimization reasons. result.SetDeoptReasons(from.DeoptReasons()); return result.raw(); @@ -14162,12 +14176,13 @@ RawICData* ICData::Clone(const ICData& from) { Zone* zone = Thread::Current()->zone(); - const ICData& result = ICData::Handle(ICData::NewDescriptor( - zone, Function::Handle(zone, from.Owner()), - String::Handle(zone, from.target_name()), - Array::Handle(zone, from.arguments_descriptor()), from.deopt_id(), - from.NumArgsTested(), from.rebind_rule(), - AbstractType::Handle(from.StaticReceiverType()))); + const ICData& result = ICData::Handle( + zone, ICData::NewDescriptor( + zone, Function::Handle(zone, from.Owner()), + String::Handle(zone, from.target_name()), + Array::Handle(zone, from.arguments_descriptor()), + from.deopt_id(), from.NumArgsTested(), from.rebind_rule(), + AbstractType::Handle(zone, from.receivers_static_type()))); // Clone entry array. const Array& from_array = Array::Handle(zone, from.entries()); const intptr_t len = from_array.Length();
diff --git a/runtime/vm/object.h b/runtime/vm/object.h index dbdbe2c..a3a1aca 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h
@@ -1441,6 +1441,7 @@ friend class Instance; friend class Object; friend class Type; + friend class InterpreterHelpers; friend class Intrinsifier; friend class ClassFunctionVisitor; }; @@ -1588,15 +1589,20 @@ bool IsImmutable() const; #if !defined(DART_PRECOMPILED_RUNTIME) - RawAbstractType* StaticReceiverType() const { - return raw_ptr()->static_receiver_type_; + RawAbstractType* receivers_static_type() const { + return raw_ptr()->receivers_static_type_; } - void SetStaticReceiverType(const AbstractType& type) const; - bool IsTrackingExactness() const { - return StaticReceiverType() != Object::null(); + void SetReceiversStaticType(const AbstractType& type) const; + bool is_tracking_exactness() const { + return TrackingExactnessBit::decode(raw_ptr()->state_bits_); + } + void set_tracking_exactness(bool value) const { + StoreNonPointer( + &raw_ptr()->state_bits_, + TrackingExactnessBit::update(value, raw_ptr()->state_bits_)); } #else - bool IsTrackingExactness() const { return false; } + bool is_tracking_exactness() const { return false; } #endif void Reset(Zone* zone) const; @@ -1702,8 +1708,8 @@ static intptr_t owner_offset() { return OFFSET_OF(RawICData, owner_); } #if !defined(DART_PRECOMPILED_RUNTIME) - static intptr_t static_receiver_type_offset() { - return OFFSET_OF(RawICData, static_receiver_type_); + static intptr_t receivers_static_type_offset() { + return OFFSET_OF(RawICData, receivers_static_type_); } #endif @@ -1882,7 +1888,9 @@ enum { kNumArgsTestedPos = 0, kNumArgsTestedSize = 2, - kDeoptReasonPos = kNumArgsTestedPos + kNumArgsTestedSize, + kTrackingExactnessPos = kNumArgsTestedPos + kNumArgsTestedSize, + kTrackingExactnessSize = 1, + kDeoptReasonPos = kTrackingExactnessPos + kTrackingExactnessSize, kDeoptReasonSize = kLastRecordedDeoptReason + 1, kRebindRulePos = kDeoptReasonPos + kDeoptReasonSize, kRebindRuleSize = 3 @@ -1894,6 +1902,10 @@ uint32_t, kNumArgsTestedPos, kNumArgsTestedSize> {}; + class TrackingExactnessBit : public BitField<uint32_t, + bool, + kTrackingExactnessPos, + kTrackingExactnessSize> {}; class DeoptReasonBits : public BitField<uint32_t, uint32_t, ICData::kDeoptReasonPos, @@ -3409,7 +3421,7 @@ // Returns false if any value read from this field is guaranteed to be // not null. // Internally we is_nullable_ field contains either kNullCid (nullable) or - // any other value (non-nullable) instead of boolean. This is done to simplify + // kInvalidCid (non-nullable) instead of boolean. This is done to simplify // guarding sequence in the generated code. bool is_nullable() const { return raw_ptr()->is_nullable_ == kNullCid; } void set_is_nullable(bool val) const {
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc index ffd3cb9..31eb620 100644 --- a/runtime/vm/object_reload.cc +++ b/runtime/vm/object_reload.cc
@@ -45,7 +45,9 @@ ASSERT(saved_ic_datalength > 0); const Array& edge_counters_array = Array::Handle(Array::RawCast(saved_ic_data.At(0))); - ASSERT(!edge_counters_array.IsNull()); + if (edge_counters_array.IsNull()) { + return; + } // Fill edge counters array with zeros. const Smi& zero = Smi::Handle(Smi::New(0)); for (intptr_t i = 0; i < edge_counters_array.Length(); i++) { @@ -703,7 +705,7 @@ RebindRule rule = rebind_rule(); if (rule == kInstance) { const intptr_t num_args = NumArgsTested(); - const bool tracking_exactness = IsTrackingExactness(); + const bool tracking_exactness = is_tracking_exactness(); const intptr_t len = Length(); // We need at least one non-sentinel entry to require a check // for the smi fast path case.
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc index adde4dd..7eed0f3 100644 --- a/runtime/vm/profiler.cc +++ b/runtime/vm/profiler.cc
@@ -417,6 +417,7 @@ static void DumpStackFrame(intptr_t frame_index, uword pc, + uword fp, bool try_symbolize_dart_frames) { Thread* thread = Thread::Current(); if ((thread != NULL) && !thread->IsAtSafepoint() && @@ -430,7 +431,8 @@ code = Code::LookupCode(pc); // In current isolate. } if (!code.IsNull()) { - OS::PrintErr(" [0x%" Pp "] %s\n", pc, code.QualifiedName()); + OS::PrintErr(" pc 0x%" Pp " fp 0x%" Pp " %s\n", pc, fp, + code.QualifiedName()); return; } } @@ -438,12 +440,24 @@ uintptr_t start = 0; char* native_symbol_name = NativeSymbolResolver::LookupSymbolName(pc, &start); - if (native_symbol_name == NULL) { - OS::PrintErr(" [0x%" Pp "] Unknown symbol\n", pc); - } else { - OS::PrintErr(" [0x%" Pp "] %s\n", pc, native_symbol_name); + if (native_symbol_name != NULL) { + OS::PrintErr(" pc 0x%" Pp " fp 0x%" Pp " %s\n", pc, fp, + native_symbol_name); NativeSymbolResolver::FreeSymbolName(native_symbol_name); + return; } + + char* dso_name; + uword dso_base; + if (NativeSymbolResolver::LookupSharedObject(pc, &dso_base, &dso_name)) { + uword dso_offset = pc - dso_base; + OS::PrintErr(" pc 0x%" Pp " fp 0x%" Pp " %s+0x%" Px "\n", pc, fp, dso_name, + dso_offset); + NativeSymbolResolver::FreeSymbolName(dso_name); + return; + } + + OS::PrintErr(" pc 0x%" Pp " fp 0x%" Pp " Unknown symbol\n", pc, fp); } class ProfilerStackWalker : public ValueObject { @@ -469,14 +483,14 @@ } } - bool Append(uword pc) { + bool Append(uword pc, uword fp) { if (frames_skipped_ < skip_count_) { frames_skipped_++; return true; } if (sample_ == NULL) { - DumpStackFrame(frame_index_, pc, try_symbolize_dart_frames_); + DumpStackFrame(frame_index_, pc, fp, try_symbolize_dart_frames_); frame_index_++; total_frames_++; return true; @@ -632,7 +646,7 @@ in_interpreted_frame)); } - if (!Append(reinterpret_cast<uword>(pc_))) { + if (!Append(reinterpret_cast<uword>(pc_), reinterpret_cast<uword>(fp_))) { break; // Sample is full. } @@ -725,7 +739,7 @@ void walk() { const uword kMaxStep = VirtualMemory::PageSize(); - Append(original_pc_); + Append(original_pc_, original_fp_); uword* pc = reinterpret_cast<uword*>(original_pc_); uword* fp = reinterpret_cast<uword*>(original_fp_); @@ -747,10 +761,6 @@ } while (true) { - if (!Append(reinterpret_cast<uword>(pc))) { - return; - } - pc = CallerPC(fp); previous_fp = fp; fp = CallerFP(fp); @@ -794,6 +804,10 @@ // Move the lower bound up. lower_bound_ = reinterpret_cast<uword>(fp); + + if (!Append(reinterpret_cast<uword>(pc), reinterpret_cast<uword>(fp))) { + return; + } } }
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h index 2f68dbf..d5122fc7d 100644 --- a/runtime/vm/profiler.h +++ b/runtime/vm/profiler.h
@@ -80,8 +80,8 @@ // SampleThread is called from inside the signal handler and hence it is very // critical that the implementation of SampleThread does not do any of the // following: - // * Accessing TLS -- Because on Windows the callback will be running in a - // different thread. + // * Accessing TLS -- Because on Windows and Fuchsia the callback will be + // running in a different thread. // * Allocating memory -- Because this takes locks which may already be // held, resulting in a dead lock. // * Taking a lock -- See above.
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h index a6989f9..5f77d72 100644 --- a/runtime/vm/raw_object.h +++ b/runtime/vm/raw_object.h
@@ -1066,7 +1066,7 @@ TokenPosition end_token_pos_; classid_t guarded_cid_; classid_t is_nullable_; // kNullCid if field can contain null value and - // any other value otherwise. + // kInvalidCid otherwise. #if !defined(DART_PRECOMPILED_RUNTIME) typedef BitField<uint32_t, bool, 0, 1> IsDeclaredInBytecode; @@ -1701,10 +1701,8 @@ RawArray* entries_; // Contains class-ids, target and count. RawString* target_name_; // Name of target function. RawArray* args_descriptor_; // Arguments descriptor. - // Static type of the receiver. If it is set then we are performing - // exactness profiling for the receiver type. See StaticTypeExactnessState - // class for more information. - NOT_IN_PRECOMPILED(RawAbstractType* static_receiver_type_); + // Static type of the receiver, if instance call and available. + NOT_IN_PRECOMPILED(RawAbstractType* receivers_static_type_); RawObject* owner_; // Parent/calling function or original IC of cloned IC. VISIT_TO(RawObject*, owner_); RawObject** to_snapshot(Snapshot::Kind kind) {
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc index d4c12b1..bcc8277 100644 --- a/runtime/vm/runtime_entry.cc +++ b/runtime/vm/runtime_entry.cc
@@ -1142,14 +1142,14 @@ return target_function.raw(); } if (args.length() == 1) { - if (ic_data.IsTrackingExactness()) { + if (ic_data.is_tracking_exactness()) { #if !defined(DART_PRECOMPILED_RUNTIME) const auto& receiver = *args[0]; const auto state = receiver.IsNull() ? StaticTypeExactnessState::NotExact() : StaticTypeExactnessState::Compute( Type::Cast(AbstractType::Handle( - ic_data.StaticReceiverType())), + ic_data.receivers_static_type())), receiver); ic_data.AddReceiverCheck( receiver.GetClassId(), target_function, @@ -2144,6 +2144,9 @@ if ((!optimizing_compilation) || Compiler::CanOptimizeFunction(thread, function)) { if (FLAG_background_compilation) { + if (FLAG_enable_inlining_annotations) { + FATAL("Cannot enable inlining annotations and background compilation"); + } Field& field = Field::Handle(zone, isolate->GetDeoptimizingBoxedField()); while (!field.IsNull()) { if (FLAG_trace_optimization || FLAG_trace_field_guards) { @@ -2154,25 +2157,21 @@ // Get next field. field = isolate->GetDeoptimizingBoxedField(); } - } - // TODO(srdjan): Fix background compilation of regular expressions. - if (FLAG_background_compilation) { - if (FLAG_enable_inlining_annotations) { - FATAL("Cannot enable inlining annotations and background compilation"); - } - if (!BackgroundCompiler::IsDisabled(isolate) && + if (!BackgroundCompiler::IsDisabled(isolate, optimizing_compilation) && function.is_background_optimizable()) { - if (FLAG_background_compilation_stop_alot) { - BackgroundCompiler::Stop(isolate); - } - // Reduce the chance of triggering optimization while the function is - // being optimized in the background. INT_MIN should ensure that it - // takes long time to trigger optimization. + // Ensure background compiler is running, if not start it. + BackgroundCompiler::Start(isolate); + // Reduce the chance of triggering a compilation while the function is + // being compiled in the background. INT_MIN should ensure that it + // takes long time to trigger a compilation. // Note that the background compilation queue rejects duplicate entries. function.SetUsageCounter(INT_MIN); - BackgroundCompiler::Start(isolate); - isolate->background_compiler()->CompileOptimized(function); - + if (optimizing_compilation) { + isolate->optimizing_background_compiler()->Compile(function); + } else { + ASSERT(FLAG_enable_interpreter); + isolate->background_compiler()->Compile(function); + } // Continue in the same code. arguments.SetReturn(function); return;
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc index accf3f0..2aeb4a3 100644 --- a/runtime/vm/service.cc +++ b/runtime/vm/service.cc
@@ -1488,7 +1488,8 @@ } static const MethodParameter* get_stack_params[] = { - RUNNABLE_ISOLATE_PARAMETER, new BoolParameter("_full", false), NULL, + RUNNABLE_ISOLATE_PARAMETER, + NULL, }; static bool GetStack(Thread* thread, JSONStream* js) { @@ -1503,7 +1504,6 @@ DebuggerStackTrace* awaiter_stack = isolate->debugger()->AwaiterStackTrace(); // Do we want the complete script object and complete local variable objects? // This is true for dump requests. - const bool full = BoolParameter::Parse(js->LookupParam("_full"), false); JSONObject jsobj(js); jsobj.AddProperty("type", "Stack"); { @@ -1513,7 +1513,7 @@ for (intptr_t i = 0; i < num_frames; i++) { ActivationFrame* frame = stack->FrameAt(i); JSONObject jsobj(&jsarr); - frame->PrintToJSONObject(&jsobj, full); + frame->PrintToJSONObject(&jsobj); jsobj.AddProperty("index", i); } } @@ -1524,7 +1524,7 @@ for (intptr_t i = 0; i < num_frames; i++) { ActivationFrame* frame = async_causal_stack->FrameAt(i); JSONObject jsobj(&jsarr); - frame->PrintToJSONObject(&jsobj, full); + frame->PrintToJSONObject(&jsobj); jsobj.AddProperty("index", i); } } @@ -1535,7 +1535,7 @@ for (intptr_t i = 0; i < num_frames; i++) { ActivationFrame* frame = awaiter_stack->FrameAt(i); JSONObject jsobj(&jsarr); - frame->PrintToJSONObject(&jsobj, full); + frame->PrintToJSONObject(&jsobj); jsobj.AddProperty("index", i); } } @@ -1590,20 +1590,6 @@ return HandleCommonEcho(&jsobj, js); } -static bool DumpIdZone(Thread* thread, JSONStream* js) { - // TODO(johnmccutchan): Respect _idZone parameter passed to RPC. For now, - // always send the ObjectIdRing. - // - ObjectIdRing* ring = thread->isolate()->object_id_ring(); - ASSERT(ring != NULL); - // When printing the ObjectIdRing, force object id reuse policy. - RingServiceIdZone reuse_zone; - reuse_zone.Init(ring, ObjectIdRing::kReuseId); - js->set_id_zone(&reuse_zone); - ring->PrintJSON(js); - return true; -} - static bool Echo(Thread* thread, JSONStream* js) { JSONObject jsobj(js); return HandleCommonEcho(&jsobj, js); @@ -4841,7 +4827,6 @@ // clang-format off static const ServiceMethodDescriptor service_methods_[] = { - { "_dumpIdZone", DumpIdZone, NULL }, { "_echo", Echo, NULL }, { "_respondWithMalformedJson", RespondWithMalformedJson,
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md index 0040087..e3c2fd1 100644 --- a/runtime/vm/service/service.md +++ b/runtime/vm/service/service.md
@@ -1308,7 +1308,7 @@ // The isolate has encountered a Dart language error in the program. LanguageError, - // The isolate has encounted an internal error. These errors should be + // The isolate has encountered an internal error. These errors should be // reported as bugs. InternalError,
diff --git a/runtime/vm/service/service_dev.md b/runtime/vm/service/service_dev.md index a440425..dbfa952 100644 --- a/runtime/vm/service/service_dev.md +++ b/runtime/vm/service/service_dev.md
@@ -1308,7 +1308,7 @@ // The isolate has encountered a Dart language error in the program. LanguageError, - // The isolate has encounted an internal error. These errors should be + // The isolate has encountered an internal error. These errors should be // reported as bugs. InternalError,
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc index ec829b9..2cd0745 100644 --- a/runtime/vm/simulator_arm.cc +++ b/runtime/vm/simulator_arm.cc
@@ -15,7 +15,7 @@ #include "vm/compiler/assembler/assembler.h" #include "vm/compiler/assembler/disassembler.h" -#include "vm/constants_arm.h" +#include "vm/constants.h" #include "vm/cpu.h" #include "vm/native_arguments.h" #include "vm/os_thread.h"
diff --git a/runtime/vm/simulator_arm.h b/runtime/vm/simulator_arm.h index 406f7ce..8f269b2 100644 --- a/runtime/vm/simulator_arm.h +++ b/runtime/vm/simulator_arm.h
@@ -16,7 +16,7 @@ #error Do not include simulator_arm.h directly; use simulator.h. #endif -#include "vm/constants_arm.h" +#include "vm/constants.h" namespace dart {
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc index 0d9f446..c835793 100644 --- a/runtime/vm/simulator_arm64.cc +++ b/runtime/vm/simulator_arm64.cc
@@ -15,7 +15,7 @@ #include "vm/compiler/assembler/assembler.h" #include "vm/compiler/assembler/disassembler.h" -#include "vm/constants_arm64.h" +#include "vm/constants.h" #include "vm/native_arguments.h" #include "vm/os_thread.h" #include "vm/stack_frame.h"
diff --git a/runtime/vm/simulator_arm64.h b/runtime/vm/simulator_arm64.h index 43ae2ea..8a48451 100644 --- a/runtime/vm/simulator_arm64.h +++ b/runtime/vm/simulator_arm64.h
@@ -16,7 +16,7 @@ #error Do not include simulator_arm64.h directly; use simulator.h. #endif -#include "vm/constants_arm64.h" +#include "vm/constants.h" namespace dart {
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc index 2ca95a0..04f4e6a 100644 --- a/runtime/vm/snapshot_test.cc +++ b/runtime/vm/snapshot_test.cc
@@ -804,72 +804,6 @@ free(isolate_snapshot_data_buffer); } -VM_UNIT_TEST_CASE(FullSnapshot1) { - // This buffer has to be static for this to compile with Visual Studio. - // If it is not static compilation of this file with Visual Studio takes - // more than 30 minutes! - static const char kFullSnapshotScriptChars[] = { -#include "snapshot_test.dat" - }; - const char* kScriptChars = kFullSnapshotScriptChars; - - uint8_t* isolate_snapshot_data_buffer; - - // Start an Isolate, load a script and create a full snapshot. - Timer timer1(true, "Snapshot_test"); - timer1.Start(); - { - TestIsolateScope __test_isolate__; - - Thread* thread = Thread::Current(); - StackZone zone(thread); - HandleScope scope(thread); - - // Create a test library and Load up a test script in it. - Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); - EXPECT_VALID(Api::CheckAndFinalizePendingClasses(thread)); - timer1.Stop(); - OS::PrintErr("Without Snapshot: %" Pd64 "us\n", timer1.TotalElapsedTime()); - - // Write snapshot with object content. - { - TransitionNativeToVM transition(thread); - FullSnapshotWriter writer( - Snapshot::kFull, NULL, &isolate_snapshot_data_buffer, - &malloc_allocator, NULL, /*image_writer*/ nullptr); - writer.WriteFullSnapshot(); - } - - // Invoke a function which returns an object. - Dart_Handle cls = Dart_GetClass(lib, NewString("FieldsTest")); - Dart_Handle result = Dart_Invoke(cls, NewString("testMain"), 0, NULL); - EXPECT_VALID(result); - } - - // Now Create another isolate using the snapshot and execute a method - // from the script. - Timer timer2(true, "Snapshot_test"); - timer2.Start(); - TestCase::CreateTestIsolateFromSnapshot(isolate_snapshot_data_buffer); - { - Dart_EnterScope(); // Start a Dart API scope for invoking API functions. - timer2.Stop(); - OS::PrintErr("From Snapshot: %" Pd64 "us\n", timer2.TotalElapsedTime()); - - // Invoke a function which returns an object. - Dart_Handle cls = Dart_GetClass(TestCase::lib(), NewString("FieldsTest")); - Dart_Handle result = Dart_Invoke(cls, NewString("testMain"), 0, NULL); - if (Dart_IsError(result)) { - // Print the error. It is probably an unhandled exception. - fprintf(stderr, "%s\n", Dart_GetError(result)); - } - EXPECT_VALID(result); - Dart_ExitScope(); - } - Dart_ShutdownIsolate(); - free(isolate_snapshot_data_buffer); -} - // Helper function to call a top level Dart function and serialize the result. static Message* GetSerialized(Dart_Handle lib, const char* dart_function) { Dart_Handle result;
diff --git a/runtime/vm/snapshot_test.dart b/runtime/vm/snapshot_test.dart deleted file mode 100644 index a8e037d..0000000 --- a/runtime/vm/snapshot_test.dart +++ /dev/null
@@ -1,1552 +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:isolate'; -import 'dart:async'; - -class Expect { - static void equals(x, y) { - if (x != y) throw new ArgumentError('not equal'); - } -} - -class Fields { - Fields(int i, int j) - : fld1 = i, - fld2 = j, - fld5 = true {} - int fld1; - final int fld2; - static int fld3; - static const int fld4 = 10; - bool fld5; -} - -class FieldsTest { - static Fields testMain() { - Fields obj = new Fields(10, 20); - Expect.equals(10, obj.fld1); - Expect.equals(20, obj.fld2); - Expect.equals(10, Fields.fld4); - Expect.equals(true, obj.fld5); - return obj; - } -} -// Benchpress: A collection of micro-benchmarks. -// Ported from internal v8 benchmark suite. - -class Error { - static void error(String msg) { - throw msg; - } -} - -// F i b o n a c c i -class Fibonacci { - static int fib(int n) { - if (n <= 1) return 1; - return fib(n - 1) + fib(n - 2); - } -} - -class FibBenchmark extends BenchmarkBase { - const FibBenchmark() : super("Fibonacci"); - - void warmup() { - Fibonacci.fib(10); - } - - void exercise() { - // This value has been copied from benchpress.js, so that we can compare - // performance. - var result = Fibonacci.fib(20); - if (result != 10946) - Error.error("Wrong result: $result. Should be: 10946."); - } - - static void main() { - new FibBenchmark().report(); - } -} - -// L o o p -class Loop { - static int loop(int outerIterations) { - int sum = 0; - for (int i = 0; i < outerIterations; i++) { - for (int j = 0; j < 100; j++) { - sum++; - } - } - return sum; - } -} - -class LoopBenchmark extends BenchmarkBase { - const LoopBenchmark() : super("Loop"); - - void warmup() { - Loop.loop(10); - } - - void exercise() { - // This value has been copied from benchpress.js, so that we can compare - // performance. - var result = Loop.loop(200); - if (result != 20000) Error.error("Wrong result: $result. Should be: 20000"); - } - - static void main() { - new LoopBenchmark().report(); - } -} - -// T o w e r s -class TowersDisk { - final int size; - TowersDisk next; - - TowersDisk(size) - : this.size = size, - next = null {} -} - -class Towers { - List<TowersDisk> piles; - int movesDone; - Towers(int disks) - : piles = new List<TowersDisk>(3), - movesDone = 0 { - build(0, disks); - } - - void build(int pile, int disks) { - for (var i = disks - 1; i >= 0; i--) { - push(pile, new TowersDisk(i)); - } - } - - void push(int pile, TowersDisk disk) { - TowersDisk top = piles[pile]; - if ((top != null) && (disk.size >= top.size)) - Error.error("Cannot put a big disk on a smaller disk."); - disk.next = top; - piles[pile] = disk; - } - - TowersDisk pop(int pile) { - var top = piles[pile]; - if (top == null) - Error.error("Attempting to remove a disk from an empty pile."); - piles[pile] = top.next; - top.next = null; - return top; - } - - void moveTop(int from, int to) { - push(to, pop(from)); - movesDone++; - } - - void move(int from, int to, int disks) { - if (disks == 1) { - moveTop(from, to); - } else { - int other = 3 - from - to; - move(from, other, disks - 1); - moveTop(from, to); - move(other, to, disks - 1); - } - } -} - -class TowersBenchmark extends BenchmarkBase { - const TowersBenchmark() : super("Towers"); - - void warmup() { - new Towers(6).move(0, 1, 6); - } - - void exercise() { - // This value has been copied from benchpress.js, so that we can compare - // performance. - var towers = new Towers(13); - towers.move(0, 1, 13); - if (towers.movesDone != 8191) { - var moves = towers.movesDone; - Error.error("Error in result: $moves should be: 8191"); - } - } - - static void main() { - new TowersBenchmark().report(); - } -} - -// S i e v e -class SieveBenchmark extends BenchmarkBase { - const SieveBenchmark() : super("Sieve"); - - static int sieve(int size) { - int primeCount = 0; - List<bool> flags = new List<bool>(size + 1); - for (int i = 1; i < size; i++) flags[i] = true; - for (int i = 2; i < size; i++) { - if (flags[i]) { - primeCount++; - for (int k = i + 1; k <= size; k += i) flags[k - 1] = false; - } - } - return primeCount; - } - - void warmup() { - sieve(100); - } - - void exercise() { - // This value has been copied from benchpress.js, so that we can compare - // performance. - int result = sieve(1000); - if (result != 168) Error.error("Wrong result: $result should be: 168"); - } - - static void main() { - new SieveBenchmark().report(); - } -} - -// P e r m u t e -// The original benchmark uses one-based indexing. Even though arrays in JS and -// lists in dart are zero-based, we stay with one-based indexing -// (wasting one element). -class Permute { - int permuteCount; - Permute() {} - - void swap(int n, int k, List<int> list) { - int tmp = list[n]; - list[n] = list[k]; - list[k] = tmp; - } - - void doPermute(int n, List<int> list) { - permuteCount++; - if (n != 1) { - doPermute(n - 1, list); - for (int k = n - 1; k >= 1; k--) { - swap(n, k, list); - doPermute(n - 1, list); - swap(n, k, list); - } - } - } - - int permute(int size) { - permuteCount = 0; - List<int> list = new List<int>(size); - for (int i = 1; i < size; i++) list[i] = i - 1; - doPermute(size - 1, list); - return permuteCount; - } -} - -class PermuteBenchmark extends BenchmarkBase { - const PermuteBenchmark() : super("Permute"); - - void warmup() { - new Permute().permute(4); - } - - void exercise() { - // This value has been copied from benchpress.js, so that we can compare - // performance. - int result = new Permute().permute(8); - if (result != 8660) Error.error("Wrong result: $result should be: 8660"); - } - - static void main() { - new PermuteBenchmark().report(); - } -} - -// Q u e e n s -// The original benchmark uses one-based indexing. Even though arrays in JS and -// lists in dart are zero-based, we stay with one-based indexing -// (wasting one element). -class Queens { - static bool tryQueens( - int i, List<bool> a, List<bool> b, List<bool> c, List<int> x) { - int j = 0; - bool q = false; - while ((!q) && (j != 8)) { - j++; - q = false; - if (b[j] && a[i + j] && c[i - j + 7]) { - x[i] = j; - b[j] = false; - a[i + j] = false; - c[i - j + 7] = false; - if (i < 8) { - q = tryQueens(i + 1, a, b, c, x); - if (!q) { - b[j] = true; - a[i + j] = true; - c[i - j + 7] = true; - } - } else { - q = true; - } - } - } - return q; - } - - static void queens() { - List<bool> a = new List<bool>(9); - List<bool> b = new List<bool>(17); - List<bool> c = new List<bool>(15); - List<int> x = new List<int>(9); - b[1] = false; - for (int i = -7; i <= 16; i++) { - if ((i >= 1) && (i <= 8)) a[i] = true; - if (i >= 2) b[i] = true; - if (i <= 7) c[i + 7] = true; - } - - if (!tryQueens(1, b, a, c, x)) Error.error("Error in queens"); - } -} - -class QueensBenchmark extends BenchmarkBase { - const QueensBenchmark() : super("Queens"); - - void warmup() { - Queens.queens(); - } - - void exercise() { - Queens.queens(); - } - - static void main() { - new QueensBenchmark().report(); - } -} - -// R e c u r s e -class Recurse { - static int recurse(int n) { - if (n <= 0) return 1; - recurse(n - 1); - return recurse(n - 1); - } -} - -class RecurseBenchmark extends BenchmarkBase { - const RecurseBenchmark() : super("Recurse"); - - void warmup() { - Recurse.recurse(7); - } - - void exercise() { - // This value has been copied from benchpress.js, so that we can compare - // performance. - Recurse.recurse(13); - } - - static void main() { - new RecurseBenchmark().report(); - } -} - -// S u m -class SumBenchmark extends BenchmarkBase { - const SumBenchmark() : super("Sum"); - - static int sum(int start, int end) { - var sum = 0; - for (var i = start; i <= end; i++) sum += i; - return sum; - } - - void warmup() { - sum(1, 1000); - } - - void exercise() { - // This value has been copied from benchpress.js, so that we can compare - // performance. - int result = sum(1, 10000); - if (result != 50005000) - Error.error("Wrong result: $result should be 50005000"); - } - - static void main() { - new SumBenchmark().report(); - } -} - -// H e l p e r f u n c t i o n s f o r s o r t s -class Random { - static const int INITIAL_SEED = 74755; - int seed; - Random() : seed = INITIAL_SEED {} - - int random() { - seed = ((seed * 1309) + 13849) % 65536; - return seed; - } -} - -// -class SortData { - List<int> list; - int min; - int max; - - SortData(int length) { - Random r = new Random(); - list = new List<int>(length); - for (int i = 0; i < length; i++) list[i] = r.random(); - - int min, max; - min = max = list[0]; - for (int i = 0; i < length; i++) { - int e = list[i]; - if (e > max) max = e; - if (e < min) min = e; - } - - this.min = min; - this.max = max; - } - - void check() { - List<int> a = list; - int len = a.length; - if ((a[0] != min) || a[len - 1] != max) Error.error("List is not sorted"); - for (var i = 1; i < len; i++) { - if (a[i - 1] > a[i]) Error.error("List is not sorted"); - } - } -} - -// B u b b l e S o r t -class BubbleSort { - static void sort(List<int> a) { - int len = a.length; - for (int i = len - 2; i >= 0; i--) { - for (int j = 0; j <= i; j++) { - int c = a[j]; - int n = a[j + 1]; - if (c > n) { - a[j] = n; - a[j + 1] = c; - } - } - } - } -} - -class BubbleSortBenchmark extends BenchmarkBase { - const BubbleSortBenchmark() : super("BubbleSort"); - - void warmup() { - SortData data = new SortData(30); - BubbleSort.sort(data.list); - } - - void exercise() { - // This value has been copied from benchpress.js, so that we can compare - // performance. - SortData data = new SortData(130); - BubbleSort.sort(data.list); - data.check(); - } - - static void main() { - new BubbleSortBenchmark().report(); - } -} - -// Q u i c k S o r t -class QuickSort { - static void sort(List<int> a, int low, int high) { - int pivot = a[(low + high) >> 1]; - int i = low; - int j = high; - while (i <= j) { - while (a[i] < pivot) i++; - while (pivot < a[j]) j--; - if (i <= j) { - int tmp = a[i]; - a[i] = a[j]; - a[j] = tmp; - i++; - j--; - } - } - - if (low < j) sort(a, low, j); - if (i < high) sort(a, i, high); - } -} - -class QuickSortBenchmark extends BenchmarkBase { - const QuickSortBenchmark() : super("QuickSort"); - - void warmup() { - SortData data = new SortData(100); - QuickSort.sort(data.list, 0, data.list.length - 1); - } - - void exercise() { - // This value has been copied from benchpress.js, so that we can compare - // performance. - SortData data = new SortData(800); - QuickSort.sort(data.list, 0, data.list.length - 1); - data.check(); - } - - static void main() { - new QuickSortBenchmark().report(); - } -} - -// T r e e S o r t -class TreeNodePress { - int value; - TreeNodePress left; - TreeNodePress right; - - TreeNodePress(int n) : value = n {} - - void insert(int n) { - if (n < value) { - if (left == null) - left = new TreeNodePress(n); - else - left.insert(n); - } else { - if (right == null) - right = new TreeNodePress(n); - else - right.insert(n); - } - } - - void check() { - TreeNodePress left = this.left; - TreeNodePress right = this.right; - int value = this.value; - - return ((left == null) || ((left.value < value) && left.check())) && - ((right == null) || ((right.value >= value) && right.check())); - } -} - -class TreeSort { - static void sort(List<int> a) { - int len = a.length; - TreeNodePress tree = new TreeNodePress(a[0]); - for (var i = 1; i < len; i++) tree.insert(a[i]); - if (!tree.check()) Error.error("Invalid result, tree not sorted"); - } -} - -class TreeSortBenchmark extends BenchmarkBase { - const TreeSortBenchmark() : super("TreeSort"); - - void warmup() { - TreeSort.sort(new SortData(100).list); - } - - void exercise() { - // This value has been copied from benchpress.js, so that we can compare - // performance. - TreeSort.sort(new SortData(1000).list); - } -} - -// T a k -class TakBenchmark extends BenchmarkBase { - const TakBenchmark() : super("Tak"); - - static void tak(int x, int y, int z) { - if (y >= x) return z; - return tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y)); - } - - void warmup() { - tak(9, 6, 3); - } - - void exercise() { - // This value has been copied from benchpress.js, so that we can compare - // performance. - tak(18, 12, 6); - } - - static void main() { - new TakBenchmark().report(); - } -} - -// T a k l -class ListElement { - final int length; - final ListElement next; - - const ListElement(int length, ListElement next) - : this.length = length, - this.next = next; - - static ListElement makeList(int length) { - if (length == 0) return null; - return new ListElement(length, makeList(length - 1)); - } - - static bool isShorter(ListElement x, ListElement y) { - ListElement xTail = x; - ListElement yTail = y; - while (yTail != null) { - if (xTail == null) return true; - xTail = xTail.next; - yTail = yTail.next; - } - return false; - } -} - -class Takl { - static ListElement takl(ListElement x, ListElement y, ListElement z) { - if (ListElement.isShorter(y, x)) { - return takl(takl(x.next, y, z), takl(y.next, z, x), takl(z.next, x, y)); - } else { - return z; - } - } -} - -class TaklBenchmark extends BenchmarkBase { - const TaklBenchmark() : super("Takl"); - - void warmup() { - Takl.takl(ListElement.makeList(8), ListElement.makeList(4), - ListElement.makeList(3)); - } - - void exercise() { - // This value has been copied from benchpress.js, so that we can compare - // performance. - ListElement result = Takl.takl(ListElement.makeList(15), - ListElement.makeList(10), ListElement.makeList(6)); - if (result.length != 10) { - int len = result.length; - Error.error("Wrong result: $len should be: 10"); - } - } - - static void main() { - new TaklBenchmark().report(); - } -} - -// M a i n - -class BenchPress { - static void mainWithArgs(List<String> args) { - List<BenchmarkBase> benchmarks = [ - new BubbleSortBenchmark(), - new FibBenchmark(), - new LoopBenchmark(), - new PermuteBenchmark(), - new QueensBenchmark(), - new QuickSortBenchmark(), - new RecurseBenchmark(), - new SieveBenchmark(), - new SumBenchmark(), - new TakBenchmark(), - new TaklBenchmark(), - new TowersBenchmark(), - new TreeSortBenchmark(), - ]; - if (args.length > 0) { - String benchName = args[0]; - bool foundBenchmark = false; - benchmarks.forEach((bench) { - if (bench.name == benchName) { - foundBenchmark = true; - bench.report(); - } - }); - if (!foundBenchmark) { - Error.error("Benchmark not found: $benchName"); - } - return; - } - double logMean = 0.0; - benchmarks.forEach((bench) { - double benchScore = bench.measure(); - String name = bench.name; - print("$name: $benchScore"); - logMean += Math.log(benchScore); - }); - logMean = logMean / benchmarks.length; - double score = Math.pow(Math.E, logMean); - print("BenchPress (average): $score"); - } - - // TODO(floitsch): let main accept arguments from the command line. - static void main() { - mainWithArgs([]); - } -} - -class BenchmarkBase { - final String name; - - // Empty constructor. - const BenchmarkBase(String name) : this.name = name; - - // The benchmark code. - // This function is not used, if both [warmup] and [exercise] are overwritten. - void run() {} - - // Runs a short version of the benchmark. By default invokes [run] once. - void warmup() { - run(); - } - - // Exercises the benchmark. By default invokes [run] 10 times. - void exercise() { - for (int i = 0; i < 10; i++) { - run(); - } - } - - // Not measured setup code executed prior to the benchmark runs. - void setup() {} - - // Not measures teardown code executed after the benchmark runs. - void teardown() {} - - // Measures the score for this benchmark by executing it repeately until - // time minimum has been reached. - static double measureFor(Function f, int timeMinimum) { - int time = 0; - int iter = 0; - DateTime start = new DateTime.now(); - while (time < timeMinimum) { - f(); - time = (new DateTime.now().difference(start)).inMilliseconds; - iter++; - } - // Force double result by using a double constant. - return (1000.0 * iter) / time; - } - - // Measures the score for the benchmark and returns it. - double measure() { - setup(); - // Warmup for at least 100ms. Discard result. - measureFor(() { - this.warmup(); - }, -100); - // Run the benchmark for at least 2000ms. - double result = measureFor(() { - this.exercise(); - }, -2000); - teardown(); - return result; - } - - void report() { - double score = measure(); - print("name: $score"); - } -} - -class Logger { - static print(object) { - printobject(object); - } - - static printobject(obj) {} -} - -// -// Dromaeo ObjectString -// Adapted from Mozilla JavaScript performance test suite. -// Microtests of strings (concatenation, methods). - -class ObjectString extends BenchmarkBase { - const ObjectString() : super("Dromaeo.ObjectString"); - - static void main() { - new ObjectString().report(); - } - - static void print(String str) { - print(str); - } - - String getRandomString(int characters) { - var result = ""; - for (var i = 0; i < characters; i++) { - result += - Strings.createFromCodePoints([(25 * Math.random()).toInt() + 97]); - } - result += result; - result += result; - return result; - } - - void run() { - //JS Dromeaeo uses 16384 - final ITERATE1 = 384; - //JS Dromeaeo uses 80000 - final ITERATE2 = 80; - //JS Dromeaeo uses 5000 - final ITERATE3 = 50; - //JS Dromeaeo uses 5000 - final ITERATE4 = 1; - //JS Dromaeo uses 5000 - final ITERATE5 = 1000; - - var result; - var text = getRandomString(ITERATE1); - - ConcatStringBenchmark.test(ITERATE2); - ConcatStringFromCharCodeBenchmark.test(ITERATE2); - StringSplitBenchmark.test(text); - StringSplitOnCharBenchmark.test(text); - text += text; - CharAtBenchmark.test(text, ITERATE3); - NumberBenchmark.test(text, ITERATE3); - CodeUnitAtBenchmark.test(text, ITERATE3); - IndexOfBenchmark.test(text, ITERATE3); - LastIndexOfBenchmark.test(text, ITERATE3); - SliceBenchmark.test(text, ITERATE4); - SubstrBenchmark.test(text, ITERATE4); - SubstringBenchmark.test(text, ITERATE4); - ToLowerCaseBenchmark.test(text, ITERATE5); - ToUpperCaseBenchmark.test(text, ITERATE5); - ComparingBenchmark.test(text, ITERATE5); - } -} - -class ConcatStringBenchmark { - ConcatStringBenchmark() {} - - static String test(var iterations) { - var str = ""; - for (var i = 0; i < iterations; i++) { - str += "a"; - } - return str; - } -} - -class ConcatStringFromCharCodeBenchmark { - ConcatStringFromCharCodeBenchmark() {} - - static String test(var iterations) { - var str = ""; - for (var i = 0; i < (iterations / 2); i++) { - str += Strings.createFromCodePoints([97]); - } - return str; - } -} - -class StringSplitBenchmark { - StringSplitBenchmark() {} - - static List<String> test(String input) { - return input.split(""); - } -} - -class StringSplitOnCharBenchmark { - StringSplitOnCharBenchmark() {} - - static List<String> test(String input) { - String multiple = input; - multiple += multiple; - multiple += multiple; - multiple += multiple; - multiple += multiple; - return multiple.split("a"); - } -} - -class CharAtBenchmark { - CharAtBenchmark() {} - - static String test(String input, var iterations) { - var str; - for (var j = 0; j < iterations; j++) { - str = input[0]; - str = input[input.length - 1]; - str = input[150]; //set it to 15000 - str = input[120]; //set it to 12000 - } - return str; - } -} - -class NumberBenchmark { - NumberBenchmark() {} - - static String test(String input, var iterations) { - var str; - for (var j = 0; j < iterations; j++) { - str = input[0]; - str = input[input.length - 1]; - str = input[150]; //set it to 15000 - str = input[100]; //set it to 10000 - str = input[50]; //set it to 5000 - } - return str; - } -} - -class CodeUnitAtBenchmark { - CodeUnitAtBenchmark() {} - - static String test(String input, var iterations) { - var str; - for (var j = 0; j < iterations; j++) { - str = input.codeUnitAt(0); - str = input.codeUnitAt(input.length - 1); - str = input.codeUnitAt(150); //set it to 15000 - str = input.codeUnitAt(100); //set it to 10000 - str = input.codeUnitAt(50); //set it to 5000 - } - return str; - } -} - -class IndexOfBenchmark { - IndexOfBenchmark() {} - - static String test(String input, var iterations) { - var str; - for (var j = 0; j < iterations; j++) { - str = input.indexOf("a", 0); - str = input.indexOf("b", 0); - str = input.indexOf("c", 0); - str = input.indexOf("d", 0); - } - return str; - } -} - -class LastIndexOfBenchmark { - LastIndexOfBenchmark() {} - - static String test(String input, var iterations) { - var str; - for (var j = 0; j < iterations; j++) { - str = input.lastIndexOf("a", input.length - 1); - str = input.lastIndexOf("b", input.length - 1); - str = input.lastIndexOf("c", input.length - 1); - str = input.lastIndexOf("d", input.length - 1); - } - return str; - } -} - -class SliceBenchmark { - SliceBenchmark() {} - - static String test(String input, var iterations) { - var str; - for (var j = 0; j < iterations; j++) { - str = input.substring(0, input.length - 1); - str = input.substring(0, 5); - str = input.substring(input.length - 1, input.length - 1); - str = input.substring(input.length - 6, input.length - 1); - str = input.substring(150, 155); //set to 15000 and 15005 - str = input.substring(120, input.length - 1); //set to 12000 - } - return str; - } -} - -class SubstrBenchmark { - SubstrBenchmark() {} - - static String test(String input, var iterations) { - var str; - for (var j = 0; j < iterations; j++) { - str = input.substring(0, input.length - 1); - str = input.substring(0, 4); - str = input.substring(input.length - 1, input.length - 1); - str = input.substring(input.length - 6, input.length - 6); - str = input.substring(150, 154); //set to 15000 and 15005 - str = input.substring(120, 124); //set to 12000 - } - return str; - } -} - -class SubstringBenchmark { - SubstringBenchmark() {} - - static String test(String input, var iterations) { - var str; - for (var j = 0; j < iterations; j++) { - str = input.substring(0, input.length - 1); - str = input.substring(0, 4); - str = input.substring(input.length - 1, input.length - 1); - str = input.substring(input.length - 6, input.length - 2); - str = input.substring(150, 154); //set to 15000 and 15005 - str = input.substring(120, input.length - 2); //set to 12000 - } - return str; - } -} - -class ToLowerCaseBenchmark { - ToLowerCaseBenchmark() {} - - static String test(String input, var iterations) { - var str; - for (var j = 0; j < (iterations / 1000); j++) { - str = Ascii.toLowerCase(input); - } - return str; - } -} - -class ToUpperCaseBenchmark { - ToUpperCaseBenchmark() {} - - static String test(String input, var iterations) { - var str; - for (var j = 0; j < (iterations / 1000); j++) { - str = Ascii.toUpperCase(input); - } - return str; - } -} - -class ComparingBenchmark { - ComparingBenchmark() {} - - static bool test(String input, var iterations) { - var tmp = "a${input}a"; - var tmp2 = "a${input}a"; - var res; - for (var j = 0; j < (iterations / 1000); j++) { - res = (tmp.compareTo(tmp2) == 0); - res = (tmp.compareTo(tmp2) < 0); - res = (tmp.compareTo(tmp2) > 0); - } - return res; - } -} - -// Benchmarks basic message communication between two isolates. - -class Benchmark1 { - static const MESSAGES = 10000; - static const INIT_MESSAGE = 0; - static const TERMINATION_MESSAGE = -1; - static const WARMUP_TIME = 1000; - static const RUN_TIME = 1000; - static const RUNS = 5; - - static int run() { - return _run; - } - - static void add_result(var opsms) { - _run++; - _opsms += opsms; - } - - static void get_result() { - return _opsms / _run; - } - - static void init() { - _run = 0; - _opsms = 0.0; - } - - static void main() { - init(); - PingPongGame pingPongGame = new PingPongGame(); - } - - static var _run; - static var _opsms; -} - -class PingPongGame { - PingPongGame() - : _ping = new ReceivePort(), - _pingPort = _ping.toSendPort(), - _pong = null, - _warmedup = false, - _iterations = 0 { - SendPort _pong = spawnFunction(pong); - play(); - } - - void startRound() { - _iterations++; - _pong.send(Benchmark1.INIT_MESSAGE, _pingPort); - } - - void evaluateRound() { - int time = (new DateTime.now().difference(_start)).inMilliseconds; - if (!_warmedup && time < Benchmark1.WARMUP_TIME) { - startRound(); - } else if (!_warmedup) { - _warmedup = true; - _start = new DateTime.now(); - _iterations = 0; - startRound(); - } else if (_warmedup && time < Benchmark1.RUN_TIME) { - startRound(); - } else { - shutdown(); - Benchmark1.add_result((1.0 * _iterations * Benchmark1.MESSAGES) / time); - if (Benchmark1.run() < Benchmark1.RUNS) { - new PingPongGame(); - } else { - print("PingPong: ", Benchmark1.get_result()); - } - } - } - - void play() { - _ping.receive((int message, SendPort replyTo) { - if (message < Benchmark1.MESSAGES) { - _pong.send(++message, null); - } else { - evaluateRound(); - } - }); - _start = new DateTime.now(); - startRound(); - } - - void shutdown() { - _pong.send(Benchmark1.TERMINATION_MESSAGE, null); - _ping.close(); - } - - DateTime _start; - SendPort _pong; - SendPort _pingPort; - ReceivePort _ping; - bool _warmedup; - int _iterations; -} - -void pong() { - port.receive((message, SendPort replyTo) { - if (message == Benchmark1.INIT_MESSAGE) { - replyTo.send(message, null); - } else if (message == Benchmark1.TERMINATION_MESSAGE) { - port.close(); - } else { - replyTo.send(message, null); - } - }); -} - -class ManyGenericInstanceofTest { - static testMain() { - for (int i = 0; i < 5000; i++) { - GenericInstanceof.testMain(); - } - } -} - -// --------------------------------------------------------------------------- -// THE REST OF THIS FILE COULD BE AUTOGENERATED -// --------------------------------------------------------------------------- - -// --------------------------------------------------------------------------- -// tests/isolate/spawn_test.dart -// --------------------------------------------------------------------------- - -spawn_test_main() { - test("spawn a new isolate", () { - SendPort port = spawnFunction(entry); - port.call(42).then(expectAsync1((message) { - Expect.equals(42, message); - })); - }); -} - -void entry() { - port.receive((message, SendPort replyTo) { - Expect.equals(42, message); - replyTo.send(42, null); - port.close(); - }); -} - -// --------------------------------------------------------------------------- -// tests/isolate/isolate_negative_test.dart -// --------------------------------------------------------------------------- - -void isolate_negative_entry() { - port.receive((ignored, replyTo) { - replyTo.send("foo", null); - }); -} - -isolate_negative_test_main() { - test("ensure isolate code is executed", () { - SendPort port = spawnFunction(isolate_negative_entry); - port.call("foo").then(expectAsync1((message) { - Expect.equals(true, "Expected fail"); // <=-------- Should fail here. - })); - }); -} - -// --------------------------------------------------------------------------- -// tests/isolate/message_test.dart -// --------------------------------------------------------------------------- - -// --------------------------------------------------------------------------- -// Message passing test. -// --------------------------------------------------------------------------- - -class MessageTest { - static const List list1 = const ["Hello", "World", "Hello", 0xfffffffffff]; - static const List list2 = const [null, list1, list1, list1, list1]; - static const List list3 = const [list2, 2.0, true, false, 0xfffffffffff]; - static const Map map1 = const { - "a=1": 1, - "b=2": 2, - "c=3": 3, - }; - static const Map map2 = const { - "list1": list1, - "list2": list2, - "list3": list3, - }; - static const List list4 = const [map1, map2]; - static const List elms = const [ - list1, - list2, - list3, - list4, - ]; - - static void VerifyMap(Map expected, Map actual) { - Expect.equals(true, expected is Map); - Expect.equals(true, actual is Map); - Expect.equals(expected.length, actual.length); - testForEachMap(key, value) { - if (value is List) { - VerifyList(value, actual[key]); - } else { - Expect.equals(value, actual[key]); - } - } - - expected.forEach(testForEachMap); - } - - static void VerifyList(List expected, List actual) { - for (int i = 0; i < expected.length; i++) { - if (expected[i] is List) { - VerifyList(expected[i], actual[i]); - } else if (expected[i] is Map) { - VerifyMap(expected[i], actual[i]); - } else { - Expect.equals(expected[i], actual[i]); - } - } - } - - static void VerifyObject(int index, var actual) { - var expected = elms[index]; - Expect.equals(true, expected is List); - Expect.equals(true, actual is List); - Expect.equals(expected.length, actual.length); - VerifyList(expected, actual); - } -} - -pingPong() { - int count = 0; - port.receive((var message, SendPort replyTo) { - if (message == -1) { - port.close(); - replyTo.send(count, null); - } else { - // Check if the received object is correct. - if (count < MessageTest.elms.length) { - MessageTest.VerifyObject(count, message); - } - // Bounce the received object back so that the sender - // can make sure that the object matches. - replyTo.send(message, null); - count++; - } - }); -} - -message_test_main() { - test("send objects and receive them back", () { - SendPort remote = spawnFunction(pingPong); - // Send objects and receive them back. - for (int i = 0; i < MessageTest.elms.length; i++) { - var sentObject = MessageTest.elms[i]; - remote.call(sentObject).then(expectAsync1((var receivedObject) { - MessageTest.VerifyObject(i, receivedObject); - })); - } - - // Send recursive objects and receive them back. - List local_list1 = ["Hello", "World", "Hello", 0xffffffffff]; - List local_list2 = [null, local_list1, local_list1]; - List local_list3 = [local_list2, 2.0, true, false, 0xffffffffff]; - List sendObject = new List(5); - sendObject[0] = local_list1; - sendObject[1] = sendObject; - sendObject[2] = local_list2; - sendObject[3] = sendObject; - sendObject[4] = local_list3; - remote.call(sendObject).then((var replyObject) { - Expect.equals(true, sendObject is List); - Expect.equals(true, replyObject is List); - Expect.equals(sendObject.length, replyObject.length); - Expect.equals(true, identical(replyObject[1], replyObject)); - Expect.equals(true, identical(replyObject[3], replyObject)); - Expect.equals(true, identical(replyObject[0], replyObject[2][1])); - Expect.equals(true, identical(replyObject[0], replyObject[2][2])); - Expect.equals(true, identical(replyObject[2], replyObject[4][0])); - Expect.equals(true, identical(replyObject[0][0], replyObject[0][2])); - // TODO(alexmarkov): Revise this comment. - // Bigint literals are not canonicalized so do a == check. - Expect.equals(true, replyObject[0][3] == replyObject[4][4]); - }); - - // Shutdown the MessageServer. - remote.call(-1).then(expectAsync1((int message) { - Expect.equals(MessageTest.elms.length + 1, message); - })); - }); -} - -// --------------------------------------------------------------------------- -// tests/isolate/request_reply_test.dart -// --------------------------------------------------------------------------- - -void request_reply_entry() { - port.receive((message, SendPort replyTo) { - replyTo.send(message + 87); - port.close(); - }); -} - -void request_reply_main() { - test("call", () { - SendPort port = spawnFunction(request_reply_entry); - port.call(42).then(expectAsync1((message) { - Expect.equals(42 + 87, message); - })); - }); - - test("send", () { - SendPort port = spawnFunction(request_reply_entry); - ReceivePort reply = new ReceivePort(); - port.send(99, reply.toSendPort()); - reply.receive(expectAsync2((message, replyTo) { - Expect.equals(99 + 87, message); - reply.close(); - })); - }); -} - -// --------------------------------------------------------------------------- -// tests/isolate/count_test.dart -// --------------------------------------------------------------------------- - -void countMessages() { - int count = 0; - port.receive((int message, SendPort replyTo) { - if (message == -1) { - Expect.equals(10, count); - replyTo.send(-1, null); - port.close(); - return; - } - Expect.equals(count, message); - count++; - replyTo.send(message * 2, null); - }); -} - -void count_main() { - test("count 10 consecutive messages", () { - int count = 0; - SendPort remote = spawnFunction(countMessages); - ReceivePort local = new ReceivePort(); - SendPort reply = local.toSendPort(); - - local.receive(expectAsync2((int message, SendPort replyTo) { - if (message == -1) { - Expect.equals(11, count); - local.close(); - return; - } - - Expect.equals((count - 1) * 2, message); - remote.send(count++, reply); - if (count == 10) { - remote.send(-1, reply); - } - }, 11)); - remote.send(count++, reply); - }); -} - -// --------------------------------------------------------------------------- -// tests/isolate/mandel_isolate_test.dart -// --------------------------------------------------------------------------- - -const TERMINATION_MESSAGE = -1; -const N = 100; -const ISOLATES = 20; - -mandel_main() { - test("Render Mandelbrot in parallel", () { - final state = new MandelbrotState(); - state._validated.future.then(expectAsync1((result) { - expect(result, isTrue); - })); - for (int i = 0; i < Math.min(ISOLATES, N); i++) state.startClient(i); - }); -} - -class MandelbrotState { - MandelbrotState() { - _result = new List<List<int>>(N); - _lineProcessedBy = new List<LineProcessorClient>(N); - _sent = 0; - _missing = N; - _validated = new Completer<bool>(); - } - - void startClient(int id) { - assert(_sent < N); - final client = new LineProcessorClient(this, id); - client.processLine(_sent++); - } - - void notifyProcessedLine(LineProcessorClient client, int y, List<int> line) { - assert(_result[y] == null); - _result[y] = line; - _lineProcessedBy[y] = client; - - if (_sent != N) { - client.processLine(_sent++); - } else { - client.shutdown(); - } - - // If all lines have been computed, validate the result. - if (--_missing == 0) { - _printResult(); - _validateResult(); - } - } - - void _validateResult() { - // TODO(ngeoffray): Implement this. - _validated.complete(true); - } - - void _printResult() { - var output = new StringBuffer(); - for (int i = 0; i < _result.length; i++) { - List<int> line = _result[i]; - for (int j = 0; j < line.length; j++) { - if (line[j] < 10) output.write("0"); - output.write(line[j]); - } - output.write("\n"); - } - // print(output); - } - - List<List<int>> _result; - List<LineProcessorClient> _lineProcessedBy; - int _sent; - int _missing; - Completer<bool> _validated; -} - -class LineProcessorClient { - LineProcessorClient(MandelbrotState this._state, int this._id) { - _port = spawnFunction(processLines); - } - - void processLine(int y) { - _port.call(y).then((List<int> message) { - _state.notifyProcessedLine(this, y, message); - }); - } - - void shutdown() { - _port.send(TERMINATION_MESSAGE, null); - } - - MandelbrotState _state; - int _id; - SendPort _port; -} - -List<int> processLine(int y) { - double inverseN = 2.0 / N; - double Civ = y * inverseN - 1.0; - List<int> result = new List<int>(N); - for (int x = 0; x < N; x++) { - double Crv = x * inverseN - 1.5; - - double Zrv = Crv; - double Ziv = Civ; - - double Trv = Crv * Crv; - double Tiv = Civ * Civ; - - int i = 49; - do { - Ziv = (Zrv * Ziv) + (Zrv * Ziv) + Civ; - Zrv = Trv - Tiv + Crv; - - Trv = Zrv * Zrv; - Tiv = Ziv * Ziv; - } while (((Trv + Tiv) <= 4.0) && (--i > 0)); - - result[x] = i; - } - return result; -} - -void processLines() { - port.receive((message, SendPort replyTo) { - if (message == TERMINATION_MESSAGE) { - assert(replyTo == null); - port.close(); - } else { - replyTo.send(processLine(message), null); - } - }); -}
diff --git a/runtime/vm/snapshot_test_in.dat b/runtime/vm/snapshot_test_in.dat deleted file mode 100644 index 43cfc18..0000000 --- a/runtime/vm/snapshot_test_in.dat +++ /dev/null
@@ -1 +0,0 @@ -{{DART_SOURCE}}
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc index 8e6b4ec..ae8edb8 100644 --- a/runtime/vm/stack_frame.cc +++ b/runtime/vm/stack_frame.cc
@@ -29,6 +29,7 @@ /*.first_object_from_fp = */ -1, /*.last_fixed_object_from_fp = */ -1, /*.param_end_from_fp = */ -1, + /*.last_param_from_entry_sp = */ -1, /*.first_local_from_fp = */ -1, /*.dart_fixed_frame_size = */ -1, /*.saved_caller_pp_from_fp = */ -1, @@ -40,6 +41,7 @@ /*.first_object_from_fp = */ kFirstObjectSlotFromFp, /*.last_fixed_object_from_fp = */ kLastFixedObjectSlotFromFp, /*.param_end_from_fp = */ kParamEndSlotFromFp, + /*.last_param_from_entry_sp = */ kLastParamSlotFromEntrySp, /*.first_local_from_fp = */ kFirstLocalSlotFromFp, /*.dart_fixed_frame_size = */ kDartFrameFixedSize, /*.saved_caller_pp_from_fp = */ kSavedCallerPpSlotFromFp, @@ -51,6 +53,7 @@ /*.last_fixed_object_from_fp = */ kLastFixedObjectSlotFromFp + 2, // No saved CODE, PP slots /*.param_end_from_fp = */ kParamEndSlotFromFp, + /*.last_param_from_entry_sp = */ kLastParamSlotFromEntrySp, /*.first_local_from_fp =*/kFirstLocalSlotFromFp + 2, // No saved CODE, PP slots. /*.dart_fixed_frame_size =*/kDartFrameFixedSize -
diff --git a/runtime/vm/stack_frame_arm.h b/runtime/vm/stack_frame_arm.h index 1f27cf9..2b5dc3e 100644 --- a/runtime/vm/stack_frame_arm.h +++ b/runtime/vm/stack_frame_arm.h
@@ -42,6 +42,7 @@ static const int kSavedCallerPcSlotFromFp = 1; static const int kParamEndSlotFromFp = 1; // One slot past last parameter. static const int kCallerSpSlotFromFp = 2; +static const int kLastParamSlotFromEntrySp = 0; // Entry and exit frame layout. #if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
diff --git a/runtime/vm/stack_frame_arm64.h b/runtime/vm/stack_frame_arm64.h index 70000da..3b8c726 100644 --- a/runtime/vm/stack_frame_arm64.h +++ b/runtime/vm/stack_frame_arm64.h
@@ -42,6 +42,7 @@ static const int kParamEndSlotFromFp = 1; // One slot past last parameter. static const int kCallerSpSlotFromFp = 2; +static const int kLastParamSlotFromEntrySp = 0; // Entry and exit frame layout. static const int kExitLinkSlotFromEntryFp = -22;
diff --git a/runtime/vm/stack_frame_dbc.h b/runtime/vm/stack_frame_dbc.h index 475d9b7..632f68c 100644 --- a/runtime/vm/stack_frame_dbc.h +++ b/runtime/vm/stack_frame_dbc.h
@@ -55,6 +55,7 @@ // these indices during code generation in the backend. static const int kParamEndSlotFromFp = 4; // One slot past last parameter. static const int kFirstLocalSlotFromFp = -1; +static const int kLastParamSlotFromEntrySp = 0; // Should not be used on DBC. DART_FORCE_INLINE static intptr_t LocalVarIndex(intptr_t fp_offset, intptr_t var_index) {
diff --git a/runtime/vm/stack_frame_ia32.h b/runtime/vm/stack_frame_ia32.h index 2cfd1c4..b770cf7 100644 --- a/runtime/vm/stack_frame_ia32.h +++ b/runtime/vm/stack_frame_ia32.h
@@ -38,6 +38,7 @@ static const int kSavedCallerPcSlotFromFp = 1; static const int kParamEndSlotFromFp = 1; // One slot past last parameter. static const int kCallerSpSlotFromFp = 2; +static const int kLastParamSlotFromEntrySp = 1; // Skip return address. // No pool pointer on IA32 (indicated by aliasing saved fp). static const int kSavedCallerPpSlotFromFp = kSavedCallerFpSlotFromFp;
diff --git a/runtime/vm/stack_frame_x64.h b/runtime/vm/stack_frame_x64.h index 84d9652..00d0059 100644 --- a/runtime/vm/stack_frame_x64.h +++ b/runtime/vm/stack_frame_x64.h
@@ -43,6 +43,7 @@ static const int kParamEndSlotFromFp = 1; // One slot past last parameter. static const int kCallerSpSlotFromFp = 2; +static const int kLastParamSlotFromEntrySp = 1; // Skip return address. // Entry and exit frame layout. #if defined(_WIN64)
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc index 6b49fce..637d16f 100644 --- a/runtime/vm/stub_code.cc +++ b/runtime/vm/stub_code.cc
@@ -112,7 +112,7 @@ if (FLAG_enable_interpreter) { if (is_interpreted_frame) { // Recognize special marker set up by interpreter in entry frame. - return Interpreter::IsEntryFrameMarker(pc); + return Interpreter::IsEntryFrameMarker(reinterpret_cast<uint32_t*>(pc)); } { uword entry = StubCode::InvokeDartCodeFromBytecode().EntryPoint();
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h index 771116b..845d780 100644 --- a/runtime/vm/symbols.h +++ b/runtime/vm/symbols.h
@@ -209,6 +209,7 @@ V(LanguageError, "LanguageError") \ V(LeftShiftOperator, "<<") \ V(Length, "length") \ + V(GetLength, "get:length") \ V(LessEqualOperator, "<=") \ V(LibraryClass, "Library") \ V(LibraryPrefix, "LibraryPrefix") \
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h index 49d1ba8..5e771b0 100644 --- a/runtime/vm/thread.h +++ b/runtime/vm/thread.h
@@ -19,6 +19,7 @@ #include "vm/handles.h" #include "vm/heap/pointer_block.h" #include "vm/os_thread.h" +#include "vm/random.h" #include "vm/runtime_entry_list.h" #include "vm/thread_stack_resource.h" #include "vm/thread_state.h" @@ -771,6 +772,8 @@ void InitVMConstants(); + uint64_t GetRandomUInt64() { return thread_random_.NextUInt64(); } + #ifndef PRODUCT void PrintJSON(JSONStream* stream) const; #endif @@ -799,11 +802,11 @@ Heap* heap_; uword top_; uword end_; - uword top_exit_frame_info_; + uword volatile top_exit_frame_info_; StoreBufferBlock* store_buffer_block_; MarkingStackBlock* marking_stack_block_; MarkingStackBlock* deferred_marking_stack_block_; - uword vm_tag_; + uword volatile vm_tag_; RawStackTrace* async_stack_trace_; // Memory location dedicated for passing unboxed int64 values from // generated code to runtime. @@ -868,6 +871,8 @@ RawError* sticky_error_; + Random thread_random_; + // Reusable handles support. #define REUSABLE_HANDLE_FIELDS(object) object* object##_handle_; REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_FIELDS)
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc index 1a28815..23b42ee 100644 --- a/runtime/vm/unit_test.cc +++ b/runtime/vm/unit_test.cc
@@ -411,7 +411,7 @@ const char* resolved_url_chars = url_chars; if (IsPackageSchemeURL(url_chars)) { resolved_url = ResolvePackageUri(url_chars); - DART_CHECK_VALID(resolved_url); + EXPECT_VALID(resolved_url); if (Dart_IsError(Dart_StringToCString(resolved_url, &resolved_url_chars))) { return Dart_NewApiError("unable to convert resolved uri to string"); } @@ -429,8 +429,10 @@ } } -static intptr_t BuildSourceFilesArray(Dart_SourceFile** sourcefiles, - const char* script) { +static intptr_t BuildSourceFilesArray( + Dart_SourceFile** sourcefiles, + const char* script, + const char* script_url = RESOLVED_USER_TEST_URI) { ASSERT(sourcefiles != NULL); ASSERT(script != NULL); @@ -440,7 +442,7 @@ } *sourcefiles = new Dart_SourceFile[num_test_libs + 1]; - (*sourcefiles)[0].uri = RESOLVED_USER_TEST_URI; + (*sourcefiles)[0].uri = script_url; (*sourcefiles)[0].source = script; for (intptr_t i = 0; i < num_test_libs; ++i) { (*sourcefiles)[i + 1].uri = test_libs_->At(i).url; @@ -469,7 +471,7 @@ } #endif // ifndef PRODUCT Dart_SourceFile* sourcefiles = NULL; - intptr_t num_sources = BuildSourceFilesArray(&sourcefiles, script); + intptr_t num_sources = BuildSourceFilesArray(&sourcefiles, script, lib_url); Dart_Handle result = LoadTestScriptWithDFE(num_sources, sourcefiles, resolver, finalize_classes, true, allow_compile_errors); @@ -501,9 +503,9 @@ // TODO(32618): Kernel doesn't correctly represent the root library. lib = Dart_LookupLibrary(Dart_NewStringFromCString(sourcefiles[0].uri)); - DART_CHECK_VALID(lib); + EXPECT_VALID(lib); Dart_Handle result = Dart_SetRootLibrary(lib); - DART_CHECK_VALID(result); + EXPECT_VALID(result); Dart_SetNativeResolver(lib, resolver, NULL); return lib; @@ -534,7 +536,7 @@ Dart_Handle lib = Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size); - DART_CHECK_VALID(lib); + EXPECT_VALID(lib); // Ensure kernel buffer isn't leaked after test is run. AddToKernelBuffers(kernel_buffer); @@ -542,15 +544,15 @@ // BOGUS: Kernel doesn't correctly represent the root library. lib = Dart_LookupLibrary(Dart_NewStringFromCString( entry_script_uri != NULL ? entry_script_uri : sourcefiles[0].uri)); - DART_CHECK_VALID(lib); + EXPECT_VALID(lib); result = Dart_SetRootLibrary(lib); - DART_CHECK_VALID(result); + EXPECT_VALID(result); result = Dart_SetNativeResolver(lib, resolver, NULL); - DART_CHECK_VALID(result); + EXPECT_VALID(result); if (finalize) { result = Dart_FinalizeLoading(false); - DART_CHECK_VALID(result); + EXPECT_VALID(result); } return lib; } @@ -641,7 +643,7 @@ Dart_Handle TestCase::lib() { Dart_Handle url = NewString(TestCase::url()); Dart_Handle lib = Dart_LookupLibrary(url); - DART_CHECK_VALID(lib); + EXPECT_VALID(lib); ASSERT(Dart_IsLibrary(lib)); return lib; }
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h index e8f1391..c4855d2 100644 --- a/runtime/vm/unit_test.h +++ b/runtime/vm/unit_test.h
@@ -303,15 +303,16 @@ bool allow_compile_errors = false, const char* multiroot_filepaths = NULL, const char* multiroot_scheme = NULL); - static Dart_Handle LoadTestScript(const char* script, - Dart_NativeEntryResolver resolver, - const char* lib_uri = USER_TEST_URI, - bool finalize = true, - bool allow_compile_errors = false); + static Dart_Handle LoadTestScript( + const char* script, + Dart_NativeEntryResolver resolver, + const char* lib_uri = RESOLVED_USER_TEST_URI, + bool finalize = true, + bool allow_compile_errors = false); static Dart_Handle LoadTestScriptWithErrors( const char* script, Dart_NativeEntryResolver resolver = NULL, - const char* lib_uri = USER_TEST_URI, + const char* lib_uri = RESOLVED_USER_TEST_URI, bool finalize = true); static Dart_Handle LoadTestLibrary(const char* lib_uri, const char* script,
diff --git a/runtime/vm/visitor.h b/runtime/vm/visitor.h index a951b9a..4eac814 100644 --- a/runtime/vm/visitor.h +++ b/runtime/vm/visitor.h
@@ -66,27 +66,6 @@ DISALLOW_COPY_AND_ASSIGN(ObjectVisitor); }; -class ExtensibleObjectVisitor : public ObjectVisitor { - public: - explicit ExtensibleObjectVisitor(GrowableArray<ObjectVisitor*>* visitors) - : visitors_(visitors) {} - - virtual ~ExtensibleObjectVisitor() {} - - virtual void VisitObject(RawObject* obj) { - for (intptr_t i = 0; i < visitors_->length(); i++) { - visitors_->At(i)->VisitObject(obj); - } - } - - void Add(ObjectVisitor* visitor) { visitors_->Add(visitor); } - - private: - GrowableArray<ObjectVisitor*>* visitors_; - - DISALLOW_COPY_AND_ASSIGN(ExtensibleObjectVisitor); -}; - // An object finder visitor interface. class FindObjectVisitor { public:
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni index eadae4d..f4aa3ef 100644 --- a/runtime/vm/vm_sources.gni +++ b/runtime/vm/vm_sources.gni
@@ -46,8 +46,8 @@ "constants_arm64.cc", "constants_arm64.h", "constants_dbc.h", - "constants_ia32.h", "constants_ia32.cc", + "constants_ia32.h", "constants_kbc.h", "constants_x64.cc", "constants_x64.h",
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn index 50c2682..78cd365 100644 --- a/sdk/BUILD.gn +++ b/sdk/BUILD.gn
@@ -20,8 +20,10 @@ # Build a SDK with less stuff. It excludes dart2js, ddc, and web libraries. dart_platform_sdk = true - # Path to stripped dart binary relative to build output directory. + # Path to stripped dart binaries relative to build output directory. dart_stripped_binary = "dart" + dartaotruntime_stripped_binary = "dartaotruntime" + gen_snapshot_stripped_binary = "gen_snapshot" } # The directory layout of the SDK is as follows: @@ -30,11 +32,14 @@ # ....bin/ # ......dart or dart.exe (executable) # ......dart.lib (import library for VM native extensions on Windows) +# ......dartaotruntime or dartaotruntime.exe (executable) # ......dartdoc # ......dartfmt +# ......dart2aot # ......dart2js # ......dartanalyzer # ......dartdevc +# ......utils/gen_snapshot or utils/gen_snapshot.exe (executable) # ......pub # ......snapshots/ # ........analysis_server.dart.snapshot @@ -43,6 +48,7 @@ # ........dartdoc.dart.snapshot # ........dartfmt.dart.snapshot # ........dartdevc.dart.snapshot +# ........gen_kernel.dart.snapshot # ........kernel_worker.dart.snapshot # ........pub.dart.snapshot #.........resources/ @@ -341,6 +347,75 @@ } } +copy("copy_dartaotruntime") { + deps = [ + "../runtime/bin:dartaotruntime", + ] + dartaotruntime_out = get_label_info("../runtime/bin:dartaotruntime", "root_out_dir") + if (is_win) { + sources = [ + "$dartaotruntime_out/dartaotruntime.exe", + ] + } else { + sources = [ + "$dartaotruntime_out/$dartaotruntime_stripped_binary", + ] + } + if (is_win) { + sources += [ "$dartaotruntime_out/dartaotruntime.lib" ] + } + outputs = [ + "$root_out_dir/dart-sdk/bin/{{source_file_part}}", + ] +} + +copy("copy_gen_snapshot") { + deps = [ + "../runtime/bin:gen_snapshot", + ] + gen_snapshot_out = get_label_info("../runtime/bin:gen_snapshot", "root_out_dir") + if (is_win) { + sources = [ + "$gen_snapshot_out/gen_snapshot.exe", + ] + } else { + sources = [ + "$gen_snapshot_out/$gen_snapshot_stripped_binary", + ] + } + if (is_win) { + sources += [ "$gen_snapshot_out/gen_snapshot.lib" ] + } + outputs = [ + "$root_out_dir/dart-sdk/bin/utils/{{source_file_part}}", + ] +} + +copy("copy_dart2aot") { + ext = "" + if (is_win) { + ext = ".bat" + } + sources = [ + "bin/dart2aot$ext", + ] + outputs = [ + "$root_out_dir/dart-sdk/bin/{{source_file_part}}", + ] +} + +copy("copy_gen_kernel_snapshot") { + deps = [ + "../utils/gen_kernel", + ] + sources = [ + "$root_gen_dir/gen_kernel.dart.snapshot", + ] + outputs = [ + "$root_out_dir/dart-sdk/bin/snapshots/{{source_file_part}}", + ] +} + # A template for copying the things in _platform_sdk_scripts and # _full_sdk_scripts into bin/ template("copy_sdk_script") {
diff --git a/sdk/bin/dart2aot b/sdk/bin/dart2aot new file mode 100755 index 0000000..9390db6 --- /dev/null +++ b/sdk/bin/dart2aot
@@ -0,0 +1,111 @@ +#!/usr/bin/env bash +# Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +# for details. All rights reserved. Use of this source code is governed by a +# BSD-style license that can be found in the LICENSE file. + +# Script for generating AOT snapshot in two steps: +# - Compilation to kernel with additional AOT specific transformations. +# - Compilation of kernel into snapshot using gen_snapshot. + +# Parse incoming arguments and extract the value of --packages option if any +# was passed. Split options (--xyz) and non-options into two separate arrays. +# All options will be passed to gen_snapshot, while --packages will be +# passed to the CFE (Common Front-End). + +set -e + +OPTIONS=() +GEN_KERNEL_OPTIONS=() +PACKAGES= +BUILD_ELF=0 + +ARGV=() +for arg in "$@"; do + case $arg in + --packages=*) + PACKAGES="$arg" + ;; + --enable-asserts) + GEN_KERNEL_OPTIONS+=("$arg") + OPTIONS+=("$arg") + ;; + --tfa | \ + --no-tfa | \ + -D* ) + GEN_KERNEL_OPTIONS+=("$arg") + ;; + --build-elf) + BUILD_ELF=1 + ;; + --*) + OPTIONS+=("$arg") + ;; + *) + ARGV+=("$arg") + ;; + esac +done + +if [ "${#ARGV[@]}" -ne 2 ]; then + echo "Usage: $0 [options] <dart-source-file> <dart-aot-file>" + echo "" + echo "Dart AOT (ahead-of-time) compile Dart source code into native machine code." + exit 1 +fi + +SOURCE_FILE="${ARGV[0]}" +SNAPSHOT_FILE="${ARGV[1]}" + +if [ $BUILD_ELF -eq 1 ]; then + GEN_SNAPSHOT_OPTION="--snapshot-kind=app-aot-assembly" + GEN_SNAPSHOT_FILENAME="--assembly=${SNAPSHOT_FILE}.S" +else + GEN_SNAPSHOT_OPTION="--snapshot-kind=app-aot-blobs" + GEN_SNAPSHOT_FILENAME="--blobs_container_filename=${SNAPSHOT_FILE}" +fi + +function follow_links() { + file="$1" + while [ -h "$file" ]; do + # On Mac OS, readlink -f doesn't work. + file="$(readlink "$file")" + done + echo "$file" +} + +# Unlike $0, $BASH_SOURCE points to the absolute path of this file. +PROG_NAME="$(follow_links "$BASH_SOURCE")" + +# Handle the case where dart-sdk/bin has been symlinked to. +BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" + +SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)" + +DART="$BIN_DIR/dart" +GEN_SNAPSHOT="$BIN_DIR/utils/gen_snapshot" + +SNAPSHOT_DIR="$BIN_DIR/snapshots" +SNAPSHOT="$SNAPSHOT_DIR/gen_kernel.dart.snapshot" + +# Step 1: Generate Kernel binary from the input Dart source. +"$DART" \ + "${SNAPSHOT}" \ + --platform "${SDK_DIR}/lib/_internal/vm_platform_strong.dill" \ + --aot \ + -Ddart.vm.product=true \ + "${GEN_KERNEL_OPTIONS[@]}" \ + $PACKAGES \ + -o "$SNAPSHOT_FILE.dill" \ + "$SOURCE_FILE" + +# Step 2: Generate snapshot from the Kernel binary. +"$GEN_SNAPSHOT" \ + "$GEN_SNAPSHOT_OPTION" \ + "$GEN_SNAPSHOT_FILENAME" \ + "${OPTIONS[@]}" \ + "$SNAPSHOT_FILE.dill" + +# Step 3: Assemble the assembly file into an ELF object. +if [ $BUILD_ELF -eq 1 ]; then + gcc -shared -o "$SNAPSHOT_FILE" "${SNAPSHOT_FILE}.S" +fi
diff --git a/sdk/bin/dart2aot.bat b/sdk/bin/dart2aot.bat new file mode 100644 index 0000000..321e867 --- /dev/null +++ b/sdk/bin/dart2aot.bat
@@ -0,0 +1,58 @@ +@echo off +REM Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +REM for details. All rights reserved. Use of this source code is governed by a +REM BSD-style license that can be found in the LICENSE file. + +setlocal +rem Handle the case where dart-sdk/bin has been symlinked to. +set DIR_NAME_WITH_SLASH=%~dp0 +set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%% +call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR +rem Get rid of surrounding quotes. +for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi + +rem Get absolute full name for SDK_DIR. +for %%i in ("%BIN_DIR%\..\") do set SDK_DIR=%%~fi + +rem Remove trailing backslash if there is one +IF %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1% + +rem Get absolute full name for DART_ROOT. +for %%i in ("%SDK_DIR%\..\") do set DART_ROOT=%%~fi + +rem Remove trailing backslash if there is one +if %DART_ROOT:~-1%==\ set DART_ROOT=%DART_ROOT:~0,-1% + +set DART=%BIN_DIR%\dart.exe +set GEN_KERNEL=%BIN_DIR%\snapshots\gen_kernel.dart.snapshot +set VM_PLATFORM_STRONG=%SDK_DIR%\lib\_internal\vm_platform_strong.dill +set GEN_SNAPSHOT=%BIN_DIR%\utils\gen_snapshot.exe + +set SOURCE_FILE=%1 +set SNAPSHOT_FILE=%2 +set GEN_SNAPSHOT_OPTION=--snapshot-kind=app-aot-blobs +set GEN_SNAPSHOT_FILENAME=--blobs_container_filename=%SNAPSHOT_FILE% + +REM Step 1: Generate Kernel binary from the input Dart source. +%DART% %GEN_KERNEL% --platform %VM_PLATFORM_STRONG% --aot -Ddart.vm.product=true -o %SNAPSHOT_FILE%.dill %SOURCE_FILE% + +REM Step 2: Generate snapshot from the Kernel binary. +%GEN_SNAPSHOT% %GEN_SNAPSHOT_OPTION% %GEN_SNAPSHOT_FILENAME% %SNAPSHOT_FILE%.dill + +endlocal + +exit /b %errorlevel% + +:follow_links +setlocal +for %%i in (%1) do set result=%%~fi +set current= +for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^ + ^| %SystemRoot%\System32\find.exe "> %~n1 [" 2^>nul`) do ( + set current=%%i +) +if not "%current%"=="" call :follow_links "%current%", result +endlocal & set %~2=%result% +goto :eof + +:end
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart index 9ad339a..7205568 100644 --- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart +++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -2663,11 +2663,9 @@ /// and casts. We specialize each primitive type (eg int, bool), and use the /// compiler's convention to do is-checks on regular objects. boolConversionCheck(value) { - if (value is bool) return value; - // One of the following checks will always fail. - boolTypeCheck(value); - assert(value != null); - return false; + // The value from kernel should always be true, false, or null. + if (value == null) assertThrow('boolean expression must not be null'); + return value; } stringTypeCheck(value) {
diff --git a/sdk/lib/convert/base64.dart b/sdk/lib/convert/base64.dart index 1b31387..ce522be 100644 --- a/sdk/lib/convert/base64.dart +++ b/sdk/lib/convert/base64.dart
@@ -15,6 +15,9 @@ /// var encoded = base64.encode([0x62, 0x6c, 0xc3, 0xa5, 0x62, 0xc3, 0xa6, /// 0x72, 0x67, 0x72, 0xc3, 0xb8, 0x64]); /// var decoded = base64.decode("YmzDpWLDpnJncsO4ZAo="); +/// +/// The top-level [base64Encode] and [base64Decode] functions may be used +/// instead if a local variable shadows the [base64] constant. const Base64Codec base64 = Base64Codec(); /// A [base64url](https://tools.ietf.org/html/rfc4648) encoder and decoder. @@ -32,7 +35,8 @@ /// Encodes [bytes] using [base64](https://tools.ietf.org/html/rfc4648) encoding. /// -/// Shorthand for [base64.encode]. +/// Shorthand for [base64.encode]. Useful if a local variable shadows the global +/// [base64] constant. String base64Encode(List<int> bytes) => base64.encode(bytes); /// Encodes [bytes] using [base64url](https://tools.ietf.org/html/rfc4648) encoding. @@ -42,7 +46,8 @@ /// Decodes [base64](https://tools.ietf.org/html/rfc4648) or [base64url](https://tools.ietf.org/html/rfc4648) encoded bytes. /// -/// Shorthand for [base64.decode]. +/// Shorthand for [base64.decode]. Useful if a local variable shadows the +/// global [base64] constant. Uint8List base64Decode(String source) => base64.decode(source); // Constants used in more than one class.
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart index efd450d..5746e52 100644 --- a/sdk/lib/convert/json.dart +++ b/sdk/lib/convert/json.dart
@@ -59,6 +59,9 @@ /// /// var encoded = json.encode([1, 2, { "a": null }]); /// var decoded = json.decode('["foo", { "bar": 499 }]'); +/// +/// The top-level [jsonEncode] and [jsonDecode] functions may be used instead if +/// a local variable shadows the [json] constant. const JsonCodec json = JsonCodec(); /// Converts [value] to a JSON string. @@ -71,7 +74,8 @@ /// If [toEncodable] is omitted, it defaults to a function that returns the /// result of calling `.toJson()` on the unencodable object. /// -/// Shorthand for [json.encode]. +/// Shorthand for [json.encode]. Useful if a local variable shadows the global +/// [json] constant. String jsonEncode(Object object, {Object toEncodable(Object nonEncodable)}) => json.encode(object, toEncodable: toEncodable); @@ -84,7 +88,8 @@ /// /// The default [reviver] (when not provided) is the identity function. /// -/// Shorthand for [json.decode]. +/// Shorthand for [json.decode]. Useful if a local variable shadows the global +/// [json] constant. dynamic jsonDecode(String source, {Object reviver(Object key, Object value)}) => json.decode(source, reviver: reviver);
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart index 72db816..4237f28 100644 --- a/sdk/lib/vmservice/vmservice.dart +++ b/sdk/lib/vmservice/vmservice.dart
@@ -41,9 +41,6 @@ // The randomly generated auth token used to access the VM service. final String serviceAuthToken = _makeAuthToken(); -// TODO(johnmccutchan): Enable the auth token and drop the origin check. -final bool useAuthToken = const bool.fromEnvironment('DART_SERVICE_USE_AUTH'); - // This is for use by the embedder. It is a map from the isolateId to // anything implementing IsolateEmbedderData. When an isolate goes away, // the cleanup method will be invoked after being removed from the map. @@ -596,62 +593,6 @@ return encodeSuccess(message); } - Future<String> _getCrashDump(Message message) async { - var client = message.client; - final perIsolateRequests = [ - // ?isolateId=<isolate id> will be appended to each of these requests. - // Isolate information. - Uri.parse('getIsolate'), - // State of heap. - Uri.parse('_getAllocationProfile'), - // Call stack + local variables. - Uri.parse('getStack?_full=true'), - ]; - - // Snapshot of running isolates. - var isolates = runningIsolates.isolates.values.toList(); - - // Collect the mapping from request uris to responses. - var responses = {}; - - // Request VM. - var getVM = Uri.parse('getVM'); - var getVmResponse = - (await new Message.fromUri(client, getVM).sendToVM()).decodeJson(); - responses[getVM.toString()] = getVmResponse['result']; - - // Request command line flags. - var getFlagList = Uri.parse('getFlagList'); - var getFlagListResponse = - (await new Message.fromUri(client, getFlagList).sendToVM()) - .decodeJson(); - responses[getFlagList.toString()] = getFlagListResponse['result']; - - // Make requests to each isolate. - for (var isolate in isolates) { - for (var request in perIsolateRequests) { - var message = new Message.forIsolate(client, request, isolate); - // Decode the JSON and and insert it into the map. The map key - // is the request Uri. - var response = (await isolate.routeRequest(this, message)).decodeJson(); - responses[message.toUri().toString()] = response['result']; - } - // Dump the object id ring requests. - var message = - new Message.forIsolate(client, Uri.parse('_dumpIdZone'), isolate); - var response = (await isolate.routeRequest(this, message)).decodeJson(); - // Insert getObject requests into responses map. - for (var object in response['result']['objects']) { - final requestUri = - 'getObject&isolateId=${isolate.serviceId}?objectId=${object["id"]}'; - responses[requestUri] = object; - } - } - - // Encode the entire crash dump. - return encodeResult(message, responses); - } - Future<Response> routeRequest(VMService _, Message message) async { return new Response.from(await _routeRequestImpl(message)); } @@ -661,10 +602,6 @@ if (message.completed) { return await message.response; } - // TODO(turnidge): Update to json rpc. BEFORE SUBMIT. - if (message.method == '_getCrashDump') { - return await _getCrashDump(message); - } if (message.method == 'streamListen') { return await _streamListen(message); }
diff --git a/tests/co19_2/co19_2-analyzer.status b/tests/co19_2/co19_2-analyzer.status index 108c0ed..3126f6a 100644 --- a/tests/co19_2/co19_2-analyzer.status +++ b/tests/co19_2/co19_2-analyzer.status
@@ -10,6 +10,9 @@ Language/Classes/Abstract_Instance_Members/override_default_value_t05: MissingCompileTimeError # https://github.com/dart-lang/co19/issues/234 Language/Classes/Getters/type_object_t01: CompileTimeError # Issue 33995 Language/Classes/Getters/type_object_t02: CompileTimeError # Issue 33995 +Language/Classes/Instance_Methods/Operators/allowed_names_t01: CompileTimeError # triple shift +Language/Classes/Instance_Methods/Operators/allowed_names_t23: CompileTimeError # triple shift +Language/Classes/Instance_Methods/Operators/arity_1_t19: CompileTimeError # triple shift Language/Classes/Instance_Methods/override_different_default_values_t01: MissingCompileTimeError # https://github.com/dart-lang/co19/issues/234 Language/Classes/Instance_Methods/override_different_default_values_t02: MissingCompileTimeError # https://github.com/dart-lang/co19/issues/234 Language/Classes/Static_Methods/same_name_method_and_setter_t01: CompileTimeError # Invalid test, see #33237 @@ -17,8 +20,17 @@ Language/Enums/syntax_t08: CompileTimeError # Issue 33995 Language/Enums/syntax_t09: CompileTimeError # Issue 33995 Language/Errors_and_Warnings/static_warning_t01: CompileTimeError # issue #34319 +Language/Expressions/Assignment/Compound_Assignment/expression_assignment_t12: CompileTimeError # triple shift +Language/Expressions/Assignment/Compound_Assignment/indexed_expression_assignment_t12: CompileTimeError # triple shift +Language/Expressions/Assignment/Compound_Assignment/null_aware_compound_assignment_static_t12: CompileTimeError # triple shift +Language/Expressions/Assignment/Compound_Assignment/null_aware_compound_assignment_t12: CompileTimeError # triple shift +Language/Expressions/Assignment/Compound_Assignment/setter_assignment_t12: CompileTimeError # triple shift +Language/Expressions/Assignment/Compound_Assignment/variable_assignment_t12: CompileTimeError # triple shift +Language/Expressions/Bitwise_Expressions/syntax_t01: CompileTimeError # triple shift +Language/Expressions/Constants/bitwise_operators_t01: CompileTimeError # triple shift Language/Expressions/Constants/constant_list_t02: MissingCompileTimeError # Please triage this failure Language/Expressions/Constants/constant_map_t02: MissingCompileTimeError # Please triage this failure +Language/Expressions/Equality/syntax_t01: CompileTimeError # triple shift Language/Expressions/Function_Invocation/Unqualified_Invocation/function_expr_invocation_t05: CompileTimeError # Please triage this failure Language/Expressions/Function_Invocation/async_cleanup_t01: CompileTimeError # Issue 33995 Language/Expressions/Function_Invocation/async_cleanup_t02: CompileTimeError # Issue 33995 @@ -33,11 +45,24 @@ Language/Expressions/Instance_Creation/Const/parameterized_type_t01: CompileTimeError # Please triage this failure Language/Expressions/Instance_Creation/Const/parameterized_type_t02: CompileTimeError # Please triage this failure Language/Expressions/Instance_Creation/New/syntax_t04: MissingCompileTimeError # Please triage this failure +Language/Expressions/Instance_Creation/New/type_t08: CompileTimeError +Language/Expressions/Instance_Creation/New/type_t09: CompileTimeError Language/Expressions/Lists/constant_list_t01: CompileTimeError # Please triage this failure +Language/Expressions/Lists/syntax_t01: CompileTimeError # triple shift Language/Expressions/Maps/constant_map_t02: MissingCompileTimeError # Please triage this failure Language/Expressions/Maps/constant_map_type_t01: CompileTimeError # Please triage this failure +Language/Expressions/Maps/syntax_t01: CompileTimeError # triple shift +Language/Expressions/Relational_Expressions/syntax_t01: CompileTimeError # triple shift +Language/Expressions/Shift/allowed_characters_t02: CompileTimeError # triple shift +Language/Expressions/Shift/integer_t03: CompileTimeError # triple shift +Language/Expressions/Shift/syntax_t01: CompileTimeError # triple shift +Language/Expressions/Shift/syntax_t15: CompileTimeError # triple shift +Language/Expressions/Strings/String_Interpolation/syntax_t01: CompileTimeError # triple shift +Language/Expressions/Symbols/syntax_t02: CompileTimeError # triple shift +Language/Expressions/parentheses_t01: CompileTimeError # triple shift Language/Functions/generator_return_type_t02: MissingCompileTimeError # Issue 32192 Language/Functions/generator_return_type_t06: MissingCompileTimeError # Issue 32192 +Language/Functions/syntax_t03: CompileTimeError # triple shift Language/Generics/scope_t03: CompileTimeError # Please triage this failure Language/Generics/syntax_t02: CompileTimeError # Please triage this failure Language/Generics/syntax_t03: Crash # Issue 29388 @@ -60,6 +85,9 @@ Language/Mixins/declaring_constructor_t05: MissingCompileTimeError # Issue 24767 Language/Mixins/declaring_constructor_t06: MissingCompileTimeError # Issue 24767 Language/Overview/Privacy/private_and_public_t11: CompileTimeError +Language/Reference/Operator_Precedence/precedence_01_assignment_t14: CompileTimeError # triple shift +Language/Reference/Operator_Precedence/precedence_12_Shift_t04: CompileTimeError # triple shift +Language/Reference/Operator_Precedence/precedence_t05: CompileTimeError # triple shift Language/Statements/Continue/async_loops_t01: CompileTimeError # Issue 33995 Language/Statements/Continue/async_loops_t02: CompileTimeError # Issue 33995 Language/Statements/Continue/async_loops_t03: CompileTimeError # Issue 33995 @@ -72,6 +100,7 @@ Language/Statements/Continue/async_loops_t10: CompileTimeError # Issue 33995 Language/Statements/Continue/control_transfer_t08: CompileTimeError # Issue 33995 Language/Statements/Continue/control_transfer_t09: CompileTimeError # Issue 33995 +Language/Statements/Expression_Statements/syntax_t06: CompileTimeError # triple shift Language/Statements/Return/many_return_statements_t01: CompileTimeError # co19 issue 157 Language/Statements/Return/many_return_statements_t02: CompileTimeError # issue #34319 Language/Statements/Return/no_expression_function_t01: CompileTimeError # issue #34319
diff --git a/tests/co19_2/co19_2-dart2js.status b/tests/co19_2/co19_2-dart2js.status index aefe426..c4f2692 100644 --- a/tests/co19_2/co19_2-dart2js.status +++ b/tests/co19_2/co19_2-dart2js.status
@@ -2,9 +2,6 @@ # for details. All rights reserved. Use of this source code is governed by a # BSD-style license that can be found in the LICENSE file. -[ $compiler == dartdevk ] -LanguageFeatures/Control-flow-collections/*: Skip - [ $builder_tag != run_webgl_tests && $compiler == dart2js ] LayoutTests/fast/canvas/webgl*: Skip # Only run WebGL on special builders, issue 29961
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status index 2508fca..44a9352 100644 --- a/tests/co19_2/co19_2-kernel.status +++ b/tests/co19_2/co19_2-kernel.status
@@ -3,32 +3,7 @@ # BSD-style license that can be found in the LICENSE file. [ $compiler == dartk ] -LanguageFeatures/Control-flow-collections/*: Skip LanguageFeatures/Set-literals/syntax_compatibility_A01_t02: RuntimeError -LanguageFeatures/Spread-collections/ConstSpreads_A01_t01: CompileTimeError -LanguageFeatures/Spread-collections/ConstSpreads_A06_t01: CompileTimeError -LanguageFeatures/Spread-collections/ConstSpreads_A07_t01: CompileTimeError -LanguageFeatures/Spread-collections/ConstSpreads_A07_t02: CompileTimeError -LanguageFeatures/Spread-collections/DynamicSemantics_List_A01_t01: CompileTimeError -LanguageFeatures/Spread-collections/DynamicSemantics_List_A02_t01: CompileTimeError -LanguageFeatures/Spread-collections/DynamicSemantics_List_A02_t02: CompileTimeError -LanguageFeatures/Spread-collections/DynamicSemantics_List_A02_t03: CompileTimeError -LanguageFeatures/Spread-collections/DynamicSemantics_List_A02_t04: CompileTimeError -LanguageFeatures/Spread-collections/DynamicSemantics_Map_A02_t02: CompileTimeError -LanguageFeatures/Spread-collections/DynamicSemantics_Map_A02_t03: CompileTimeError -LanguageFeatures/Spread-collections/NullAware_A01_t01: CompileTimeError -LanguageFeatures/Spread-collections/NullAware_A01_t02: CompileTimeError -LanguageFeatures/Spread-collections/NullAware_A01_t03: CompileTimeError -LanguageFeatures/Spread-collections/NullAware_A01_t04: CompileTimeError -LanguageFeatures/Spread-collections/NullAware_A02_t01: CompileTimeError -LanguageFeatures/Spread-collections/StaticSemantic_A02_t01: CompileTimeError -LanguageFeatures/Spread-collections/StaticSemantic_A05_t01/none: CompileTimeError -LanguageFeatures/Spread-collections/StaticSemantic_A05_t02/none: CompileTimeError -LanguageFeatures/Spread-collections/Syntax_A01_t01: CompileTimeError -LanguageFeatures/Spread-collections/Syntax_A01_t02: CompileTimeError -LanguageFeatures/Spread-collections/Syntax_A01_t06: CompileTimeError -LanguageFeatures/Spread-collections/Syntax_A01_t07: CompileTimeError -LanguageFeatures/Spread-collections/Syntax_A02_t12: CompileTimeError [ $compiler == dartkp ] Language/Expressions/Instance_Creation/New/evaluation_t20: RuntimeError @@ -41,37 +16,7 @@ Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t09: RuntimeError Language/Types/Interface_Types/subtype_t03: RuntimeError Language/Types/Interface_Types/subtype_t26: RuntimeError -LanguageFeatures/Control-flow-collections/*: Skip LanguageFeatures/Set-literals/syntax_compatibility_A01_t02: RuntimeError -LanguageFeatures/Spread-collections/ConstSpreads_A01_t01: DartkCrash -LanguageFeatures/Spread-collections/ConstSpreads_A04_t01/02: MissingCompileTimeError -LanguageFeatures/Spread-collections/ConstSpreads_A04_t01/06: MissingCompileTimeError -LanguageFeatures/Spread-collections/ConstSpreads_A04_t01/07: MissingCompileTimeError -LanguageFeatures/Spread-collections/ConstSpreads_A04_t01/08: MissingCompileTimeError -LanguageFeatures/Spread-collections/ConstSpreads_A06_t01: DartkCrash -LanguageFeatures/Spread-collections/ConstSpreads_A07_t01: DartkCrash -LanguageFeatures/Spread-collections/ConstSpreads_A07_t02: DartkCrash -LanguageFeatures/Spread-collections/DynamicSemantics_List_A01_t01: CompileTimeError -LanguageFeatures/Spread-collections/DynamicSemantics_List_A02_t01: CompileTimeError -LanguageFeatures/Spread-collections/DynamicSemantics_List_A02_t02: CompileTimeError -LanguageFeatures/Spread-collections/DynamicSemantics_List_A02_t03: CompileTimeError -LanguageFeatures/Spread-collections/DynamicSemantics_List_A02_t04: CompileTimeError -LanguageFeatures/Spread-collections/DynamicSemantics_Map_A02_t02: CompileTimeError -LanguageFeatures/Spread-collections/DynamicSemantics_Map_A02_t03: CompileTimeError -LanguageFeatures/Spread-collections/NullAware_A01_t01: CompileTimeError -LanguageFeatures/Spread-collections/NullAware_A01_t02: CompileTimeError -LanguageFeatures/Spread-collections/NullAware_A01_t03: CompileTimeError -LanguageFeatures/Spread-collections/NullAware_A01_t04: CompileTimeError -LanguageFeatures/Spread-collections/NullAware_A02_t01: CompileTimeError -LanguageFeatures/Spread-collections/StaticSemantic_A02_t01: CompileTimeError -LanguageFeatures/Spread-collections/StaticSemantic_A05_t01/none: CompileTimeError -LanguageFeatures/Spread-collections/StaticSemantic_A05_t02/none: CompileTimeError -LanguageFeatures/Spread-collections/Syntax_A01_t01: CompileTimeError -LanguageFeatures/Spread-collections/Syntax_A01_t02: CompileTimeError -LanguageFeatures/Spread-collections/Syntax_A01_t05: CompileTimeError -LanguageFeatures/Spread-collections/Syntax_A01_t06: CompileTimeError -LanguageFeatures/Spread-collections/Syntax_A01_t07: CompileTimeError -LanguageFeatures/Spread-collections/Syntax_A02_t12: CompileTimeError LanguageFeatures/Subtyping/static/generated/left_bottom_global_variable_A02_t01: DartkCrash LanguageFeatures/Subtyping/static/generated/left_promoted_variable_global_variable_A02_t01: DartkCrash LibTest/collection/DoubleLinkedQueue/removeWhere_A02_t02: RuntimeError @@ -119,18 +64,7 @@ Language/Statements/For/syntax_t13: Crash # Assertion error: kernel_shadow_ast.dart: 'receiver == null': is not true. Language/Statements/For/syntax_t20: Crash # Assertion error: kernel_shadow_ast.dart: 'receiver == null': is not true. LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/none: CompileTimeError -LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/none: CompileTimeError -LanguageFeatures/Control-flow-collections/const_collections_A02_t02/01: MissingCompileTimeError -LanguageFeatures/Control-flow-collections/const_collections_A02_t02/03: MissingCompileTimeError -LanguageFeatures/Control-flow-collections/const_collections_A02_t02/04: MissingCompileTimeError -LanguageFeatures/Control-flow-collections/static_errors_A04_t01/01: MissingCompileTimeError -LanguageFeatures/Control-flow-collections/static_errors_A04_t01/02: MissingCompileTimeError -LanguageFeatures/Control-flow-collections/type_promotion_A01_t01: CompileTimeError -LanguageFeatures/Set-literals/disambiguating_A06_t01/03: MissingCompileTimeError -LanguageFeatures/Set-literals/disambiguating_A06_t01/06: MissingCompileTimeError -LanguageFeatures/Set-literals/disambiguating_A06_t01/07: MissingCompileTimeError -LanguageFeatures/Set-literals/type_inference_A01_t03: Crash -LanguageFeatures/Set-literals/type_inference_A01_t04: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/none: Crash LanguageFeatures/Set-literals/type_inference_A04_t02/02: MissingCompileTimeError LanguageFeatures/Set-literals/type_inference_A04_t02/03: MissingCompileTimeError LanguageFeatures/Set-literals/type_inference_A06_t02/03: MissingCompileTimeError @@ -323,9 +257,37 @@ Language/Types/Type_Aliases/syntax_t21: CompileTimeError LanguageFeatures/Constant-update-2018/EqualityOperator_A01_t09: MissingCompileTimeError LanguageFeatures/Constant-update-2018/EqualityOperator_A01_t10: MissingCompileTimeError -LanguageFeatures/Constant-update-2018/NewOperators_A01_t01: CompileTimeError -LanguageFeatures/Constant-update-2018/NewOperators_A01_t02: CompileTimeError -LanguageFeatures/Control-flow-collections/scoping_A01_t01: CompileTimeError # co19 test error. +LanguageFeatures/Constant-update-2018/NewOperators_A01_t01: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t02: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/01: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/02: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/03: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/04: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/05: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/06: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/none: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/01: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/02: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/03: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/04: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/none: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/01: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/02: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/03: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/04: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/05: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/06: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/none: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/01: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/02: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/03: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/04: Crash +LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/05: Crash +LanguageFeatures/Constant-update-2018/TypeTestOperator_A01_t01: CompileTimeError +LanguageFeatures/Control-flow-collections/type_inference_A09_t01: Crash +LanguageFeatures/Control-flow-collections/type_inference_A11_t01: CompileTimeError +LanguageFeatures/Control-flow-collections/type_inference_A13_t01: CompileTimeError +LanguageFeatures/Control-flow-collections/type_inference_A13_t02: CompileTimeError LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t01: Crash LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t02: CompileTimeError LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t03: Crash @@ -587,21 +549,7 @@ LanguageFeatures/Set-literals/constant_set_literals_A02_t03/03: MissingCompileTimeError LanguageFeatures/Set-literals/disambiguating_A02_t02: CompileTimeError LanguageFeatures/Set-literals/disambiguating_A02_t03: Crash -LanguageFeatures/Set-literals/disambiguating_A04_t02: Crash -LanguageFeatures/Set-literals/disambiguating_A05_t02: Crash -LanguageFeatures/Set-literals/disambiguating_A06_t01/02: Crash, MissingCompileTimeError -LanguageFeatures/Set-literals/disambiguating_A06_t01/04: MissingCompileTimeError -LanguageFeatures/Set-literals/disambiguating_A06_t01/05: MissingCompileTimeError -LanguageFeatures/Set-literals/disambiguating_A06_t02/01: Crash -LanguageFeatures/Set-literals/disambiguating_A06_t02/02: Crash -LanguageFeatures/Set-literals/disambiguating_A06_t02/03: Crash -LanguageFeatures/Set-literals/disambiguating_A06_t02/04: Crash -LanguageFeatures/Set-literals/disambiguating_A06_t02/05: Crash -LanguageFeatures/Set-literals/disambiguating_A06_t02/06: Crash -LanguageFeatures/Set-literals/disambiguating_A06_t02/07: Crash -LanguageFeatures/Set-literals/disambiguating_A06_t02/none: Crash LanguageFeatures/Set-literals/exact_types_of_literals_A01_t03: RuntimeError -LanguageFeatures/Set-literals/type_inference_A01_t02: Crash LanguageFeatures/Set-literals/type_inference_A07_t01: CompileTimeError LanguageFeatures/Set-literals/type_inference_A08_t01: CompileTimeError LanguageFeatures/Set-literals/type_inference_A09_t01: CompileTimeError
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart index 84e646c..7694ba4 100644 --- a/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart +++ b/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
@@ -4,55 +4,55 @@ /*element: main:calls=*,params=0*/ main() { - method1(new Class1a()); - method2(new Class2a<int>()); - method3(new Class3a()); - method3(new Class3b()); - method4(new Class4a()); - method4(new Class4b()); + method1(new Class1a()..field1); + method2(new Class2a<int>()..field2); + method3(new Class3a()..field3); + method3(new Class3b()..field3); + method4(new Class4a()..field4); + method4(new Class4b()..field4); } class Class1a { - /*element: Class1a.field1:elided*/ + /*element: Class1a.field1:emitted*/ int field1; } -/*element: method1:params=1*/ +/*element: method1:assign=[field1],params=1*/ @pragma('dart2js:noInline') method1(dynamic c) { c.field1 = 42; } class Class2a<T> { - /*strong.element: Class2a.field2:checked,elided*/ - /*omit.element: Class2a.field2:elided*/ - /*strongConst.element: Class2a.field2:checked,elided*/ - /*omitConst.element: Class2a.field2:elided*/ + /*strong.element: Class2a.field2:checked,emitted*/ + /*omit.element: Class2a.field2:emitted*/ + /*strongConst.element: Class2a.field2:checked,emitted*/ + /*omitConst.element: Class2a.field2:emitted*/ T field2; } /*strong.element: method2:calls=[set$field2(1)],params=1*/ -/*omit.element: method2:params=1*/ +/*omit.element: method2:assign=[field2],params=1*/ /*strongConst.element: method2:calls=[set$field2(1)],params=1*/ -/*omitConst.element: method2:params=1*/ +/*omitConst.element: method2:assign=[field2],params=1*/ @pragma('dart2js:noInline') method2(dynamic c) { c.field2 = 42; } class Class3a { - /*strong.element: Class3a.field3:checked,elided*/ - /*omit.element: Class3a.field3:elided,set=simple*/ - /*strongConst.element: Class3a.field3:checked,elided*/ - /*omitConst.element: Class3a.field3:elided,set=simple*/ + /*strong.element: Class3a.field3:checked,emitted*/ + /*omit.element: Class3a.field3:emitted,set=simple*/ + /*strongConst.element: Class3a.field3:checked,emitted*/ + /*omitConst.element: Class3a.field3:emitted,set=simple*/ int field3; } class Class3b { - /*strong.element: Class3b.field3:checked,elided*/ - /*omit.element: Class3b.field3:elided,set=simple*/ - /*strongConst.element: Class3b.field3:checked,elided*/ - /*omitConst.element: Class3b.field3:elided,set=simple*/ + /*strong.element: Class3b.field3:checked,emitted*/ + /*omit.element: Class3b.field3:emitted,set=simple*/ + /*strongConst.element: Class3b.field3:checked,emitted*/ + /*omitConst.element: Class3b.field3:emitted,set=simple*/ int field3; } @@ -63,18 +63,18 @@ } class Class4a { - /*strong.element: Class4a.field4:checked,elided*/ - /*omit.element: Class4a.field4:elided,set=simple*/ - /*strongConst.element: Class4a.field4:checked,elided*/ - /*omitConst.element: Class4a.field4:elided,set=simple*/ + /*strong.element: Class4a.field4:checked,emitted*/ + /*omit.element: Class4a.field4:emitted,set=simple*/ + /*strongConst.element: Class4a.field4:checked,emitted*/ + /*omitConst.element: Class4a.field4:emitted,set=simple*/ int field4; } class Class4b implements Class4a { - /*strong.element: Class4b.field4:checked,elided*/ - /*omit.element: Class4b.field4:elided,set=simple*/ - /*strongConst.element: Class4b.field4:checked,elided*/ - /*omitConst.element: Class4b.field4:elided,set=simple*/ + /*strong.element: Class4b.field4:checked,emitted*/ + /*omit.element: Class4b.field4:emitted,set=simple*/ + /*strongConst.element: Class4b.field4:checked,emitted*/ + /*omitConst.element: Class4b.field4:emitted,set=simple*/ @override int field4; }
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart new file mode 100644 index 0000000..84e646c --- /dev/null +++ b/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
@@ -0,0 +1,86 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/*element: main:calls=*,params=0*/ +main() { + method1(new Class1a()); + method2(new Class2a<int>()); + method3(new Class3a()); + method3(new Class3b()); + method4(new Class4a()); + method4(new Class4b()); +} + +class Class1a { + /*element: Class1a.field1:elided*/ + int field1; +} + +/*element: method1:params=1*/ +@pragma('dart2js:noInline') +method1(dynamic c) { + c.field1 = 42; +} + +class Class2a<T> { + /*strong.element: Class2a.field2:checked,elided*/ + /*omit.element: Class2a.field2:elided*/ + /*strongConst.element: Class2a.field2:checked,elided*/ + /*omitConst.element: Class2a.field2:elided*/ + T field2; +} + +/*strong.element: method2:calls=[set$field2(1)],params=1*/ +/*omit.element: method2:params=1*/ +/*strongConst.element: method2:calls=[set$field2(1)],params=1*/ +/*omitConst.element: method2:params=1*/ +@pragma('dart2js:noInline') +method2(dynamic c) { + c.field2 = 42; +} + +class Class3a { + /*strong.element: Class3a.field3:checked,elided*/ + /*omit.element: Class3a.field3:elided,set=simple*/ + /*strongConst.element: Class3a.field3:checked,elided*/ + /*omitConst.element: Class3a.field3:elided,set=simple*/ + int field3; +} + +class Class3b { + /*strong.element: Class3b.field3:checked,elided*/ + /*omit.element: Class3b.field3:elided,set=simple*/ + /*strongConst.element: Class3b.field3:checked,elided*/ + /*omitConst.element: Class3b.field3:elided,set=simple*/ + int field3; +} + +/*element: method3:calls=[set$field3(1)],params=1*/ +@pragma('dart2js:noInline') +method3(dynamic c) { + c.field3 = 42; +} + +class Class4a { + /*strong.element: Class4a.field4:checked,elided*/ + /*omit.element: Class4a.field4:elided,set=simple*/ + /*strongConst.element: Class4a.field4:checked,elided*/ + /*omitConst.element: Class4a.field4:elided,set=simple*/ + int field4; +} + +class Class4b implements Class4a { + /*strong.element: Class4b.field4:checked,elided*/ + /*omit.element: Class4b.field4:elided,set=simple*/ + /*strongConst.element: Class4b.field4:checked,elided*/ + /*omitConst.element: Class4b.field4:elided,set=simple*/ + @override + int field4; +} + +/*element: method4:calls=[set$field4(1)],params=1*/ +@pragma('dart2js:noInline') +method4(Class4a c) { + c.field4 = 42; +}
diff --git a/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart b/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart new file mode 100644 index 0000000..d85a4a0 --- /dev/null +++ b/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
@@ -0,0 +1,30 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +main() { + print(const Class1().field1); + print(const Class2(field2: true).field2); + print(const Class3().field3); + print(const Class3(field3: true).field3); +} + +class Class1 { + /*element: Class1.field1:constant=BoolConstant(false)*/ + final bool field1; + + const Class1({this.field1: false}); +} + +class Class2 { + /*strongConst.element: Class2.field2:constant=BoolConstant(true)*/ + final bool field2; + + const Class2({this.field2: false}); +} + +class Class3 { + final bool field3; + + const Class3({this.field3: false}); +}
diff --git a/tests/compiler/dart2js/field_analysis/jdata/dynamic_set.dart b/tests/compiler/dart2js/field_analysis/jdata/dynamic_set.dart new file mode 100644 index 0000000..b228203 --- /dev/null +++ b/tests/compiler/dart2js/field_analysis/jdata/dynamic_set.dart
@@ -0,0 +1,63 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +main() { + method1(new Class1a()); + method2(new Class2a<int>()); + method3(new Class3a()); + method3(new Class3b()); + method4(new Class4a()); + method4(new Class4b()); +} + +class Class1a { + /*element: Class1a.field1:elided*/ + int field1; +} + +@pragma('dart2js:noInline') +method1(dynamic c) { + c.field1 = 42; +} + +class Class2a<T> { + /*element: Class2a.field2:elided*/ + T field2; +} + +@pragma('dart2js:noInline') +method2(dynamic c) { + c.field2 = 42; +} + +class Class3a { + /*element: Class3a.field3:elided*/ + int field3; +} + +class Class3b { + /*element: Class3b.field3:elided*/ + int field3; +} + +@pragma('dart2js:noInline') +method3(dynamic c) { + c.field3 = 42; +} + +class Class4a { + /*element: Class4a.field4:elided*/ + int field4; +} + +class Class4b implements Class4a { + /*element: Class4b.field4:elided*/ + @override + int field4; +} + +@pragma('dart2js:noInline') +method4(Class4a c) { + c.field4 = 42; +}
diff --git a/tests/compiler/dart2js/field_analysis/jdata/unused_constructors.dart b/tests/compiler/dart2js/field_analysis/jdata/unused_constructors.dart new file mode 100644 index 0000000..219c643 --- /dev/null +++ b/tests/compiler/dart2js/field_analysis/jdata/unused_constructors.dart
@@ -0,0 +1,24 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +class Class1 { + /*element: Class1.field:constant=IntConstant(87)*/ + final int field; + + Class1.constructor1({this.field = 42}); + Class1.constructor2({this.field = 87}); + Class1.constructor3({this.field = 123}); +} + +class Class2 { + final int field; + + const Class2([this.field]); +} + +main() { + print(new Class1.constructor2().field); + print(const Class2(42).field); + print(new Class2().field); +}
diff --git a/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart b/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart index 79b4cb0..a28477b 100644 --- a/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart +++ b/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
@@ -30,6 +30,7 @@ static const String eagerCreationIndex = 'index'; static const String isLazy = 'lazy'; static const String isEffectivelyFinal = 'final'; + static const String isElided = 'elided'; } class JAllocatorAnalysisDataComputer extends DataComputer<Features> { @@ -45,6 +46,9 @@ ir.Member node = closedWorld.elementMap.getMemberDefinition(member).node; Features features = new Features(); FieldAnalysisData fieldData = fieldAnalysis.getFieldData(member); + if (fieldData.isElided && !fieldData.isEffectivelyConstant) { + features.add(Tags.isElided); + } if (fieldData.isInitializedInAllocator) { features.add(Tags.isInitializedInAllocator); }
diff --git a/tests/compiler/dart2js/field_analysis/kdata/constant_fields.dart b/tests/compiler/dart2js/field_analysis/kdata/constant_fields.dart new file mode 100644 index 0000000..df9b18b --- /dev/null +++ b/tests/compiler/dart2js/field_analysis/kdata/constant_fields.dart
@@ -0,0 +1,31 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +main() { + print(const Class1().field1); + print(const Class2(field2: true).field2); + print(const Class3().field3); + print(const Class3(field3: true).field3); +} + +class Class1 { + /*element: Class1.field1:Class1.=field1:BoolConstant(false),initial=NullConstant*/ + final bool field1; + + const Class1({this.field1: false}); +} + +class Class2 { + /*element: Class2.field2:Class2.=field2:BoolConstant(false),initial=NullConstant*/ + final bool field2; + + const Class2({this.field2: false}); +} + +class Class3 { + /*element: Class3.field3:Class3.=field3:BoolConstant(false),initial=NullConstant*/ + final bool field3; + + const Class3({this.field3: false}); +}
diff --git a/tests/compiler/dart2js/impact/data/classes.dart b/tests/compiler/dart2js/impact/data/classes.dart index c7f1e97..5a067d6 100644 --- a/tests/compiler/dart2js/impact/data/classes.dart +++ b/tests/compiler/dart2js/impact/data/classes.dart
@@ -207,7 +207,20 @@ } /*strong.element: testEnum:static=[Enum.A]*/ -/*strongConst.element: testEnum:static=[init:Enum._name,init:Enum.index],type=[const:Enum,inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSString,inst:JSUInt31,inst:JSUInt32]*/ +/*strongConst.element: testEnum: + static=[ + Enum._name=StringConstant("Enum.A"), + Enum.index=IntConstant(0)], + type=[ + const:Enum, + inst:JSDouble, + inst:JSInt, + inst:JSNumber, + inst:JSPositiveInt, + inst:JSString, + inst:JSUInt31, + inst:JSUInt32] +*/ testEnum() => Enum.A; /*element: staticGenericMethod:
diff --git a/tests/compiler/dart2js/impact/data/constants.dart b/tests/compiler/dart2js/impact/data/constants.dart index 91feb99..12db520 100644 --- a/tests/compiler/dart2js/impact/data/constants.dart +++ b/tests/compiler/dart2js/impact/data/constants.dart
@@ -102,7 +102,10 @@ setLiteral() => const {true, false}; /*strong.element: instanceConstant:static=[Class.(2)],type=[inst:JSBool]*/ -/*strongConst.element: instanceConstant:static=[init:Class.field2,init:SuperClass.field1],type=[const:Class,inst:JSBool]*/ +/*strongConst.element: instanceConstant: + static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)], + type=[const:Class,inst:JSBool] +*/ instanceConstant() => const Class(true, false); /*element: typeLiteral:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String]*/ @@ -170,7 +173,10 @@ setLiteralRef() => setLiteralField; /*strong.element: instanceConstantRef:static=[instanceConstantField]*/ -/*strongConst.element: instanceConstantRef:static=[init:Class.field2,init:SuperClass.field1],type=[const:Class,inst:JSBool]*/ +/*strongConst.element: instanceConstantRef: + static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)], + type=[const:Class,inst:JSBool] +*/ instanceConstantRef() => instanceConstantField; /*strong.element: typeLiteralRef:static=[typeLiteralField]*/ @@ -235,7 +241,10 @@ setLiteralDeferred() => defer.setLiteralField; /*strong.element: instanceConstantDeferred:static=[instanceConstantField{defer}]*/ -/*strongConst.element: instanceConstantDeferred:static=[init:Class.field2,init:SuperClass.field1],type=[const:Class{defer},inst:JSBool]*/ +/*strongConst.element: instanceConstantDeferred: + static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)], + type=[const:Class{defer},inst:JSBool] +*/ instanceConstantDeferred() => defer.instanceConstantField; /*strong.element: typeLiteralDeferred:static=[typeLiteralField{defer}]*/
diff --git a/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart b/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart index 1c553b0..8a1f1ec 100644 --- a/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart +++ b/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart
@@ -75,6 +75,17 @@ const ConstantData('proxy', 'ConstructedConstant(_Proxy())'), const ConstantData('const [] == null', 'BoolConstant(false)'), const ConstantData('proxy == null', 'BoolConstant(false)'), + const ConstantData('proxy != null', 'BoolConstant(true)'), + const ConstantData('null == proxy', 'BoolConstant(false)'), + const ConstantData('null != proxy', 'BoolConstant(true)'), + const ConstantData('true == proxy', 'BoolConstant(false)'), + const ConstantData('true != proxy', 'BoolConstant(true)'), + const ConstantData('0 == proxy', 'BoolConstant(false)'), + const ConstantData('0 != proxy', 'BoolConstant(true)'), + const ConstantData('0.5 == proxy', 'BoolConstant(false)'), + const ConstantData('0.5 != proxy', 'BoolConstant(true)'), + const ConstantData('"" == proxy', 'BoolConstant(false)'), + const ConstantData('"" != proxy', 'BoolConstant(true)'), const ConstantData('Object', 'TypeConstant(Object)'), const ConstantData('null ?? 0', 'IntConstant(0)'), const ConstantData( @@ -380,11 +391,10 @@ expectedErrors: 'ConstEvalFailedAssertionWithMessage'), const ConstantData('const Class6(2)', 'ConstructedConstant(Class6())'), const ConstantData('const Class7()', 'ConstructedConstant(Class7())'), - // TODO(johnniwinther): Expect a NonConstant and errors when 31799 is fixed. - const ConstantData( - 'const Class7() == const Class7()', - 'BoolConstant(true)', - ), + const ConstantData('const Class7() == const Class7()', 'NonConstant', + expectedErrors: 'ConstEvalInvalidEqualsOperandType'), + const ConstantData('const Class7() != const Class7()', 'NonConstant', + expectedErrors: 'ConstEvalInvalidEqualsOperandType'), const ConstantData('const Class8(not_string.length)', 'NonConstant', expectedErrors: 'ConstEvalInvalidPropertyGet'), const ConstantData(
diff --git a/tests/compiler/dart2js/rti/emission/fixed_type_argument.dart b/tests/compiler/dart2js/rti/emission/fixed_type_argument.dart new file mode 100644 index 0000000..3db4d67 --- /dev/null +++ b/tests/compiler/dart2js/rti/emission/fixed_type_argument.dart
@@ -0,0 +1,29 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/*strong.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/ +/*omit.class: A:checkedTypeArgument,checks=[],typeArgument*/ +class A {} + +/*strong.class: B:checkedInstance,checks=[$isA],typeArgument*/ +/*omit.class: B:checks=[$isA],typeArgument*/ +class B implements A {} + +/*class: C:checks=[],indirectInstance*/ +class C<T> { + @pragma('dart2js:noInline') + method(void Function(T) f) {} +} + +/*strong.class: D:checks=[$asC],instance*/ +/*omit.class: D:checks=[],instance*/ +class D extends C<B> {} + +main() { + C<A> c = new D(); + c.method( + /*strong.checks=[$signature],instance*/ + /*omit.checks=[],instance*/ + (A a) {}); +}
diff --git a/tests/compiler/dart2js/rti/emission/fixed_type_argument_implements.dart b/tests/compiler/dart2js/rti/emission/fixed_type_argument_implements.dart new file mode 100644 index 0000000..0b22968 --- /dev/null +++ b/tests/compiler/dart2js/rti/emission/fixed_type_argument_implements.dart
@@ -0,0 +1,29 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Test that we emit the relation between B and A even when B is only live +// as a type argument through the supertype of D. + +/*strong.class: A:checkedTypeArgument,checks=[],typeArgument*/ +class A {} + +/*strong.class: B:checks=[$isA],typeArgument*/ +/*omit.class: B:checks=[],typeArgument*/ +class B implements A {} + +/*strong.class: C:checkedInstance*/ +/*omit.class: C:*/ +class C<T> {} + +/*strong.class: D:checks=[$asC,$isC],instance*/ +/*omit.class: D:checks=[],instance*/ +class D implements C<B> {} + +main() { + C<A> c = new D(); + test(c); +} + +@pragma('dart2js:noInline') +void test(C<A> c) {}
diff --git a/tests/compiler/dart2js/rti/emission/mixin_type_arguments.dart b/tests/compiler/dart2js/rti/emission/mixin_type_arguments.dart index cc6f668..9644a40 100644 --- a/tests/compiler/dart2js/rti/emission/mixin_type_arguments.dart +++ b/tests/compiler/dart2js/rti/emission/mixin_type_arguments.dart
@@ -4,19 +4,19 @@ import 'package:expect/expect.dart' show Expect; -/*class: A:checks=[]*/ +/*class: A:checks=[],typeArgument*/ class A {} -/*class: B:checks=[]*/ +/*class: B:checks=[],typeArgument*/ class B {} -/*class: C:checks=[]*/ +/*class: C:checks=[],typeArgument*/ class C {} -/*class: D:checks=[]*/ +/*class: D:checks=[],typeArgument*/ class D {} -/*class: E:checks=[]*/ +/*class: E:checks=[],typeArgument*/ class E {} /*class: F:checks=[],typeArgument*/
diff --git a/tests/compiler/dart2js/static_type/data/null_access.dart b/tests/compiler/dart2js/static_type/data/null_access.dart new file mode 100644 index 0000000..de65e93 --- /dev/null +++ b/tests/compiler/dart2js/static_type/data/null_access.dart
@@ -0,0 +1,44 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +main() { + test1(); + test2(); + test3(); +} + +class Class1 { + const Class1(); + + void method1() {} +} + +test1() { + const Class1 c = null; + return /*Null*/ c. /*invoke: void*/ method1(); +} + +class Class2<T> { + const Class2(); + + T method2() => null; +} + +test2() { + const Class2<int> c = null; + // TODO(johnniwinther): Track the unreachable code properly. + return /*Null*/ c. /*invoke: <bottom>*/ method2(); +} + +class Class3<T> { + const Class3(); + + Class3<T> method3() => null; +} + +test3() { + const Class3<int> c = null; + // TODO(johnniwinther): Track the unreachable code properly. + return /*Null*/ c. /*invoke: Class3<<bottom>>*/ method3(); +}
diff --git a/tests/compiler/dart2js_extra/boolean_conversion_test.dart b/tests/compiler/dart2js_extra/boolean_conversion_test.dart new file mode 100644 index 0000000..46a8994 --- /dev/null +++ b/tests/compiler/dart2js_extra/boolean_conversion_test.dart
@@ -0,0 +1,104 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// SharedOptions=--enable-experiment=control-flow-collections +// dart2jsOptions=--omit-implicit-checks + +// Note: --omit-implicit-checks causes Expect.isNull to misbehave, so we use +// Expect.equals(null, ...) instead. + +import 'package:expect/expect.dart'; + +void main() { + conditionalTest(); + orTest(); + andTest(); + ifTest(); + forTest(); + whileTest(); + doTest(); + notTest(); + ifElementTest(); + forElementTest(); +} + +void conditionalTest() { + bool x = null; + Expect.isFalse(x ? true : false); +} + +void orTest() { + bool x = null; + Expect.equals(null, x || x); + Expect.isFalse(x || false); + Expect.isTrue(x || true); + Expect.equals(null, false || x); + Expect.isTrue(true || x); +} + +void andTest() { + bool x = null; + Expect.isFalse(x && x); + Expect.isFalse(x && false); + Expect.isFalse(x && true); + Expect.isFalse(false && x); + Expect.equals(null, true && x); +} + +void ifTest() { + bool x = null; + Expect.isFalse(() { + if (x) { + return true; + } else { + return false; + } + }()); +} + +void forTest() { + bool x = null; + Expect.isFalse(() { + for (; x;) { + return true; + } + return false; + }()); +} + +void whileTest() { + bool x = null; + Expect.isFalse(() { + while (x) { + return true; + } + return false; + }()); +} + +void doTest() { + bool x = null; + Expect.equals(1, () { + int n = 0; + do { + n++; + } while (x); + return n; + }()); +} + +void notTest() { + bool x = null; + Expect.isTrue(!x); +} + +void ifElementTest() { + bool x = null; + Expect.listEquals([], [if (x) 1]); +} + +void forElementTest() { + bool x = null; + Expect.listEquals([], [for (var i = 0; x; i++) i]); +}
diff --git a/tests/compiler/dart2js_extra/constant_folding_test.dart b/tests/compiler/dart2js_extra/constant_folding_test.dart index cc88f68..393994a 100644 --- a/tests/compiler/dart2js_extra/constant_folding_test.dart +++ b/tests/compiler/dart2js_extra/constant_folding_test.dart
@@ -4,6 +4,8 @@ import "package:expect/expect.dart"; +// SharedOptions=--enable-experiment=constant-update-2018 + void main() { const BitNot(42, 4294967253).check(); const BitNot(4294967253, 42).check(); @@ -12,6 +14,8 @@ const BitNot(0, 0xFFFFFFFF).check(); const BitNot(4294967295, 0).check(); const BitNot(0x12121212121212, 0xEDEDEDED).check(); + const BitNot(0x7fffffff00000000, 0xffffffff).check(); + const BitNot(0x8000000000000000, 0xffffffff).check(); const Negate(0, -0).check(); const Negate(-0, 0).check(); @@ -50,6 +54,10 @@ const Negate(double.minPositive, -double.minPositive).check(); const Negate(-double.minPositive, double.minPositive).check(); const Negate(double.nan, double.nan).check(); + const Negate(0x7fffffff00000000, -0x7fffffff00000000).check(); + const Negate(-0x7fffffff00000000, 0x7fffffff00000000).check(); + const Negate(0x8000000000000000, -0x8000000000000000).check(); + const Negate(-0x8000000000000000, 0x8000000000000000).check(); const Not(true, false).check(); const Not(false, true).check(); @@ -65,6 +73,12 @@ const BitAnd(0xFFFFFFFF, 0, 0).check(); const BitAnd(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF).check(); const BitAnd(0x123456789ABC, 0xEEEEEEEEEEEE, 0x46688AAC).check(); + const BitAnd(0x7fffffff00008000, 0x8000000000008000, 0x8000).check(); + const BitAnd(0x8000000000008000, 0x7fffffff00008000, 0x8000).check(); + const BitAnd(true, true, true).check(); + const BitAnd(true, false, false).check(); + const BitAnd(false, true, false).check(); + const BitAnd(false, false, false).check(); const BitOr(314159, 271828, 323583).check(); const BitOr(271828, 314159, 323583).check(); @@ -77,6 +91,12 @@ const BitOr(0xFFFFFFFF, 0, 0xFFFFFFFF).check(); const BitOr(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF).check(); const BitOr(0x123456789ABC, 0x111111111111, 0x57799BBD).check(); + const BitOr(0x7000000080000000, 0x8000000000008000, 0x80008000).check(); + const BitOr(0x8000000000008000, 0x7000000080000000, 0x80008000).check(); + const BitOr(true, true, true).check(); + const BitOr(true, false, true).check(); + const BitOr(false, true, true).check(); + const BitOr(false, false, false).check(); const BitXor(314159, 271828, 61179).check(); const BitXor(271828, 314159, 61179).check(); @@ -88,6 +108,12 @@ const BitXor(0xFFFFFFFF, 0, 0xFFFFFFFF).check(); const BitXor(0xFFFFFFFF, 0xFFFFFFFF, 0).check(); const BitXor(0x123456789ABC, 0x111111111111, 0x47698BAD).check(); + const BitXor(0x7000000012340000, 0x8000000011110000, 0x03250000).check(); + const BitXor(0x8000000011110000, 0x7000000012340000, 0x03250000).check(); + const BitXor(true, true, false).check(); + const BitXor(true, false, true).check(); + const BitXor(false, true, true).check(); + const BitXor(false, false, false).check(); const ShiftLeft(42, 0, 42).check(); const ShiftLeft(42, 5, 1344).check(); @@ -104,6 +130,14 @@ const ShiftLeft(-1, 31, 0x80000000).check(); const ShiftLeft(-1, 32, 0).check(); const ShiftLeft(-1, 100, 0).check(); + const ShiftLeft(0x7000000000008000, 0, 0x8000).check(); + const ShiftLeft(0x7000000000008000, 1, 0x10000).check(); + const ShiftLeft(0x7000000000008000, 16, 0x80000000).check(); + const ShiftLeft(0x7000000000008000, 17, 0x0).check(); + const ShiftLeft(0x8000000000008000, 0, 0x8000).check(); + const ShiftLeft(0x8000000000008000, 1, 0x10000).check(); + const ShiftLeft(0x8000000000008000, 16, 0x80000000).check(); + const ShiftLeft(0x8000000000008000, 17, 0x0).check(); const ShiftRight(8675309, 0, 8675309).check(); const ShiftRight(8675309, 5, 271103).check(); @@ -127,6 +161,14 @@ const ShiftRight(-1073741824, 31, 0xFFFFFFFF).check(); const ShiftRight(-1073741824, 32, 0xFFFFFFFF).check(); const ShiftRight(-1073741824, 100, 0xFFFFFFFF).check(); + const ShiftRight(0x7000000000008000, 0, 0x8000).check(); + const ShiftRight(0x7000000000008000, 1, 0x4000).check(); + const ShiftRight(0x7000000000008000, 15, 0x1).check(); + const ShiftRight(0x7000000000008000, 16, 0).check(); + const ShiftRight(0x8000000000008000, 0, 0x8000).check(); + const ShiftRight(0x8000000000008000, 1, 0x4000).check(); + const ShiftRight(0x8000000000008000, 15, 0x1).check(); + const ShiftRight(0x8000000000008000, 16, 0).check(); const BooleanAnd(true, true, true).check(); const BooleanAnd(true, false, false).check(); @@ -346,9 +388,7 @@ const TruncatingDivide(9007199254740991, -0.5, -18014398509481982).check(); const TruncatingDivide(-9007199254740991, 0.5, -18014398509481982).check(); const TruncatingDivide(-9007199254740991, -0.5, 18014398509481982).check(); - const TruncatingDivide( - 0x80000000 * 0x100000000, -1, -0x80000000 * 0x100000000) - .check(); + const TruncatingDivide(0x8000000000000000, -1, -0x8000000000000000).check(); const TruncatingDivide(2.71828, 3.14159, 0).check(); const TruncatingDivide(2.71828, 1, 2).check(); const TruncatingDivide(2.71828, -1, -2).check(); @@ -837,6 +877,8 @@ const Equals(double.infinity, double.negativeInfinity, false).check(); const Equals(double.negativeInfinity, double.infinity, false).check(); const Equals(double.negativeInfinity, double.negativeInfinity, true).check(); + const Equals(0x8000000000000000, 0x8000000000000000, true).check(); + const Equals(0x8000000000000000, -9223372036854775808, false).check(); const Identity(null, null, true).check(); const Identity(null, "", false).check(); @@ -848,8 +890,7 @@ const Identity(false, true, false).check(); const Identity(0, false, false).check(); const Identity(true, 1, false).check(); - // TODO(36194) - //const Identity(double.nan, double.nan, false).check(); + const Identity(double.nan, double.nan, false).check(); const Identity(0, 0, true).check(); const Identity(0.0, 0.0, true).check(); const Identity(-0.0, -0.0, true).check(); @@ -868,6 +909,8 @@ const Identity(double.negativeInfinity, double.infinity, false).check(); const Identity(double.negativeInfinity, double.negativeInfinity, true) .check(); + const Identity(0x8000000000000000, 0x8000000000000000, true).check(); + const Identity(0x8000000000000000, -9223372036854775808, false).check(); const IfNull(null, null, null).check(); const IfNull(null, 1, 1).check();
diff --git a/tests/compiler/dart2js_extra/fixed_type_argument_implements_test.dart b/tests/compiler/dart2js_extra/fixed_type_argument_implements_test.dart new file mode 100644 index 0000000..f0c397e --- /dev/null +++ b/tests/compiler/dart2js_extra/fixed_type_argument_implements_test.dart
@@ -0,0 +1,22 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Test that we emit the relation between B and A even when B is only live +// as a type argument through the supertype of D. + +class A {} + +class B implements A {} + +class C<T> {} + +class D implements C<B> {} + +main() { + C<A> c = new D(); + test(c); +} + +@pragma('dart2js:noInline') +void test(C<A> c) {}
diff --git a/tests/compiler/dart2js_extra/fixed_type_argument_test.dart b/tests/compiler/dart2js_extra/fixed_type_argument_test.dart new file mode 100644 index 0000000..74ac892 --- /dev/null +++ b/tests/compiler/dart2js_extra/fixed_type_argument_test.dart
@@ -0,0 +1,22 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Test that we emit the relation between B and A even when B is only live +// as a type argument through the superclass of D. + +class A {} + +class B implements A {} + +class C<T> { + @pragma('dart2js:noInline') + method(void Function(T) f) {} +} + +class D extends C<B> {} + +main() { + C<A> c = new D(); + c.method((A a) {}); +}
diff --git a/tests/language_2/abstract_equal_test.dart b/tests/language_2/abstract_equal_test.dart new file mode 100644 index 0000000..2ff5b59 --- /dev/null +++ b/tests/language_2/abstract_equal_test.dart
@@ -0,0 +1,34 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// SharedOptions=--enable-experiment=constant-update-2018 + +class A { + bool operator ==(other); + const A(); +} + +class B implements A { + const B(); +} + +class C extends A { + const C(); +} + +class Invalid { + bool operator ==(other) => false; + const Invalid(); +} + +class D implements Invalid { + const D(); +} + +main() { + print(const {A(): 1}); + print(const {B(): 2}); + print(const {C(): 3}); + print(const {D(): 4}); +}
diff --git a/tests/language_2/const_inference_test.dart b/tests/language_2/const_inference_test.dart new file mode 100644 index 0000000..2e556bf --- /dev/null +++ b/tests/language_2/const_inference_test.dart
@@ -0,0 +1,140 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "package:expect/expect.dart"; + +R constFunction<T, R>(T _) => null; + +C<T> getC<T>() => const C(constFunction); + +List<T> getList<T>() => const []; + +Set<T> getSet<T>() => const {}; + +Map<K, V> getMap<K, V>() => const {}; + +R Function(T) getFunction<T, R>() { + List<R Function(T)> list = const [constFunction]; + return list[0]; +} + +C<T> getImplicitConstC<T>() { + List<C<T>> list = const [C(constFunction)]; + return list[0]; +} + +List<T> getImplicitConstList<T>() { + List<List<T>> list = const [[]]; + return list[0]; +} + +Set<T> getImplicitConstSet<T>() { + List<Set<T>> list = const [{}]; + return list[0]; +} + +Map<K, V> getImplicitConstMap<K, V>() { + List<Map<K, V>> list = const [{}]; + return list[0]; +} + +class C<T> { + final Object fn; + const C(T Function(T) this.fn); +} + +void expectOfType<T>(Object obj) { + // An exact type test would be better, but since `Null` is a subtype of all + // types that can be written in Dart 2.0, it should not matter in practice. + // + // (`obj.runtimeType == T` does not work for List/Map/Sets because the runtime + // type is an implementation-specific subtype of those interfaces.) + Expect.isTrue(obj is T, "`$obj` should be of type `$T`"); +} + +testClassInstance() { + expectOfType<C<Null>>(getC<int>()); + expectOfType<C<Null>>(getC<String>()); + expectOfType<C<Null>>(getC()); +} + +testImplicitConstClassInstance() { + expectOfType<C<Null>>(getImplicitConstC<int>()); + expectOfType<C<Null>>(getImplicitConstC<String>()); + expectOfType<C<Null>>(getImplicitConstC()); +} + +testDownwardsClassInference() { + expectOfType<Null Function(Null)>(getC<int>().fn); + expectOfType<Null Function(Null)>(getC<String>().fn); + expectOfType<Null Function(Null)>(getC().fn); +} + +testList() { + expectOfType<List<Null>>(getList<int>()); + expectOfType<List<Null>>(getList<String>()); + expectOfType<List<Null>>(getList()); +} + +testImplicitConstList() { + expectOfType<List<Null>>(getImplicitConstList<int>()); + expectOfType<List<Null>>(getImplicitConstList<String>()); + expectOfType<List<Null>>(getImplicitConstList()); +} + +testImplicitConstSet() { + expectOfType<Set<Null>>(getImplicitConstSet<int>()); + expectOfType<Set<Null>>(getImplicitConstSet<String>()); + expectOfType<Set<Null>>(getImplicitConstSet()); +} + +testSet() { + expectOfType<Set<Null>>(getSet<int>()); + expectOfType<Set<Null>>(getSet<String>()); + expectOfType<Set<Null>>(getSet()); +} + +testMap() { + expectOfType<Map<Null, Null>>(getMap<int, int>()); + expectOfType<Map<Null, Null>>(getMap<int, String>()); + expectOfType<Map<Null, Null>>(getMap<String, int>()); + expectOfType<Map<Null, Null>>(getMap<String, String>()); + expectOfType<Map<Null, Null>>(getMap<Null, Null>()); + expectOfType<Map<Null, Null>>(getMap()); +} + +testImplicitConstMap() { + expectOfType<Map<Null, Null>>(getImplicitConstMap<int, int>()); + expectOfType<Map<Null, Null>>(getImplicitConstMap<int, String>()); + expectOfType<Map<Null, Null>>(getImplicitConstMap<String, int>()); + expectOfType<Map<Null, Null>>(getImplicitConstMap<String, String>()); + expectOfType<Map<Null, Null>>(getImplicitConstMap<Null, Null>()); + expectOfType<Map<Null, Null>>(getImplicitConstMap()); +} + +testFunction() { + expectOfType<Null Function(Object)>(getFunction<int, int>()); + expectOfType<Null Function(Object)>(getFunction<int, String>()); + expectOfType<Null Function(Object)>(getFunction<String, int>()); + expectOfType<Null Function(Object)>(getFunction<String, String>()); + expectOfType<Null Function(Object)>(getFunction<Null, Null>()); + expectOfType<Null Function(Object)>(getFunction()); +} + +/// Tests that type inference for constants does not reference the type +/// parameter. Instead, free type parameters should substituted to obtain the +/// least closure (e.g. `List<T>` becomes `List<Null>` and `R Function(T)` +/// becomes `Null Function(Object)`). +main() { + testClassInstance(); + testImplicitConstClassInstance(); + testDownwardsClassInference(); + testList(); + testImplicitConstList(); + testSet(); + testImplicitConstSet(); + testMap(); + testImplicitConstMap(); + testFunction(); +}
diff --git a/tests/language_2/const_list_test.dart b/tests/language_2/const_list_test.dart index b848c9e..cdc0fb3 100644 --- a/tests/language_2/const_list_test.dart +++ b/tests/language_2/const_list_test.dart
@@ -16,32 +16,32 @@ growableList.add(i); growableList2.add(i); } - Expect.equals(true, growableList == growableList); - Expect.equals(false, growableList == growableList2); - Expect.equals(true, fixedList == fixedList); - Expect.equals(false, fixedList == fixedList2); - Expect.equals(false, fixedList == growableList); + Expect.equals(growableList, growableList); + Expect.notEquals(growableList, growableList2); + Expect.equals(fixedList, fixedList); + Expect.notEquals(fixedList, fixedList2); + Expect.notEquals(fixedList, growableList); growableList.add(4); - Expect.equals(false, fixedList == growableList); + Expect.notEquals(fixedList, growableList); Expect.equals(4, growableList.removeLast()); - Expect.equals(false, fixedList == growableList); + Expect.notEquals(fixedList, growableList); fixedList[3] = 0; - Expect.equals(false, fixedList == growableList); + Expect.notEquals(fixedList, growableList); } static testLiterals() { dynamic a = [1, 2, 3.1]; dynamic b = [1, 2, 3.1]; - Expect.equals(false, a == b); + Expect.notEquals(a, b); a = const [1, 2, 3.1]; b = const [1, 2, 3.1]; - Expect.equals(true, a == b); + Expect.identical(a, b); a = const <num>[1, 2, 3.1]; b = const [1, 2, 3.1]; - Expect.equals(false, a == b); + Expect.identical(a, b); a = const <dynamic>[1, 2, 3.1]; b = const [1, 2, 3.1]; - Expect.equals(true, a == b); + Expect.notEquals(a, b); } }
diff --git a/tests/language_2/constants_2018/constant_type_literal_test.dart b/tests/language_2/constants_2018/constant_type_literal_test.dart index 717825a..33cf4a9 100644 --- a/tests/language_2/constants_2018/constant_type_literal_test.dart +++ b/tests/language_2/constants_2018/constant_type_literal_test.dart
@@ -8,12 +8,16 @@ import "dart:core"; import "dart:core" as core; -import "dart:core" deferred as dcore; +// No reloading support for deferred loading. +// See https://github.com/dart-lang/sdk/issues/33118, +import "dart:core" deferred as dcore; //# 01: crash on reload // Declares F function type alias, M mixin and C class. import "constant_type_literal_types.dart"; import "constant_type_literal_types.dart" as p; -import "constant_type_literal_types.dart" deferred as d; +// No reloading support for deferred loading. +// See https://github.com/dart-lang/sdk/issues/33118, +import "constant_type_literal_types.dart" deferred as d; //# 02: crash on reload main() { const Test(int, core.int);
diff --git a/tests/language_2/control_flow_collections/for_non_bool_condition_test.dart b/tests/language_2/control_flow_collections/for_non_bool_condition_test.dart new file mode 100644 index 0000000..fbc3834 --- /dev/null +++ b/tests/language_2/control_flow_collections/for_non_bool_condition_test.dart
@@ -0,0 +1,15 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018 + +import 'package:expect/expect.dart'; + +void main() { + // Non-bool condition expression. + dynamic nonBool = 3; + Expect.throwsTypeError(() => <int>[for (; nonBool;) 1]); + Expect.throwsTypeError(() => <int, int>{for (; nonBool;) 1: 1}); + Expect.throwsTypeError(() => <int>{for (; nonBool;) 1}); +}
diff --git a/tests/language_2/control_flow_collections/for_null_condition_test.dart b/tests/language_2/control_flow_collections/for_null_condition_test.dart new file mode 100644 index 0000000..6b890fd --- /dev/null +++ b/tests/language_2/control_flow_collections/for_null_condition_test.dart
@@ -0,0 +1,15 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018 + +import 'package:expect/expect.dart'; + +void main() { + // Null condition expression. + bool nullBool = null; + Expect.throwsAssertionError(() => <int>[for (; nullBool;) 1]); + Expect.throwsAssertionError(() => <int, int>{for (; nullBool;) 1: 1}); + Expect.throwsAssertionError(() => <int>{for (; nullBool;) 1}); +}
diff --git a/tests/language_2/control_flow_collections/for_runtime_error_test.dart b/tests/language_2/control_flow_collections/for_runtime_error_test.dart new file mode 100644 index 0000000..f036a94 --- /dev/null +++ b/tests/language_2/control_flow_collections/for_runtime_error_test.dart
@@ -0,0 +1,29 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018 + +import 'package:expect/expect.dart'; + +void main() { + // Cast for variable. + dynamic nonInt = "string"; + Expect.throwsTypeError(() => <int>[for (int i = nonInt; false;) 1]); + Expect.throwsTypeError(() => <int, int>{for (int i = nonInt; false;) 1: 1}); + Expect.throwsTypeError(() => <int>{for (int i = nonInt; false;) 1}); + + // Cast for-in variable. + dynamic nonIterable = 3; + Expect.throwsTypeError(() => <int>[for (int i in nonIterable) 1]); + Expect.throwsTypeError(() => <int, int>{for (int i in nonIterable) 1: 1}); + Expect.throwsTypeError(() => <int>{for (int i in nonIterable) 1}); + + // Wrong element type. + Expect.throwsTypeError(() => <int>[for (var i = 0; i < 1; i++) nonInt]); + Expect.throwsTypeError( + () => <int, int>{for (var i = 0; i < 1; i++) nonInt: 1}); + Expect.throwsTypeError( + () => <int, int>{for (var i = 0; i < 1; i++) 1: nonInt}); + Expect.throwsTypeError(() => <int>{for (var i = 0; i < 1; i++) nonInt}); +}
diff --git a/tests/language_2/control_flow_collections/for_test.dart b/tests/language_2/control_flow_collections/for_test.dart index 17730bc..8df9d75 100644 --- a/tests/language_2/control_flow_collections/for_test.dart +++ b/tests/language_2/control_flow_collections/for_test.dart
@@ -241,42 +241,10 @@ } void testRuntimeErrors() { - // Non-bool condition expression. - dynamic nonBool = 3; - Expect.throwsTypeError(() => <int>[for (; nonBool;) 1]); - Expect.throwsTypeError(() => <int, int>{for (; nonBool;) 1: 1}); - Expect.throwsTypeError(() => <int>{for (; nonBool;) 1}); - - // Null condition expression. - bool nullBool = null; - Expect.throwsAssertionError(() => <int>[for (; nullBool;) 1]); - Expect.throwsAssertionError(() => <int, int>{for (; nullBool;) 1: 1}); - Expect.throwsAssertionError(() => <int>{for (; nullBool;) 1}); - - // Cast for variable. - dynamic nonInt = "string"; - Expect.throwsTypeError(() => <int>[for (int i = nonInt; false;) 1]); - Expect.throwsTypeError(() => <int, int>{for (int i = nonInt; false;) 1: 1}); - Expect.throwsTypeError(() => <int>{for (int i = nonInt; false;) 1}); - - // Cast for-in variable. - dynamic nonIterable = 3; - Expect.throwsTypeError(() => <int>[for (int i in nonIterable) 1]); - Expect.throwsTypeError(() => <int, int>{for (int i in nonIterable) 1: 1}); - Expect.throwsTypeError(() => <int>{for (int i in nonIterable) 1}); - // Null iterable. Iterable<int> nullIterable = null; Expect.throwsNoSuchMethodError(() => <int>[for (var i in nullIterable) 1]); Expect.throwsNoSuchMethodError( () => <int, int>{for (var i in nullIterable) 1: 1}); Expect.throwsNoSuchMethodError(() => <int>{for (var i in nullIterable) 1}); - - // Wrong element type. - Expect.throwsTypeError(() => <int>[for (var i = 0; i < 1; i++) nonInt]); - Expect.throwsTypeError( - () => <int, int>{for (var i = 0; i < 1; i++) nonInt: 1}); - Expect.throwsTypeError( - () => <int, int>{for (var i = 0; i < 1; i++) 1: nonInt}); - Expect.throwsTypeError(() => <int>{for (var i = 0; i < 1; i++) nonInt}); }
diff --git a/tests/language_2/control_flow_collections/if_null_condition_test.dart b/tests/language_2/control_flow_collections/if_null_condition_test.dart new file mode 100644 index 0000000..10cbb6b --- /dev/null +++ b/tests/language_2/control_flow_collections/if_null_condition_test.dart
@@ -0,0 +1,14 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018 + +import 'package:expect/expect.dart'; + +void main() { + bool nullBool = null; + Expect.throwsAssertionError(() => <int>[if (nullBool) 1]); + Expect.throwsAssertionError(() => <int, int>{if (nullBool) 1: 1}); + Expect.throwsAssertionError(() => <int>{if (nullBool) 1}); +}
diff --git a/tests/language_2/control_flow_collections/if_runtime_error_test.dart b/tests/language_2/control_flow_collections/if_runtime_error_test.dart new file mode 100644 index 0000000..8bf5469 --- /dev/null +++ b/tests/language_2/control_flow_collections/if_runtime_error_test.dart
@@ -0,0 +1,14 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018 + +import 'package:expect/expect.dart'; + +void main() { + dynamic nonBool = 3; + Expect.throwsTypeError(() => <int>[if (nonBool) 1]); + Expect.throwsTypeError(() => <int, int>{if (nonBool) 1: 1}); + Expect.throwsTypeError(() => <int>{if (nonBool) 1}); +}
diff --git a/tests/language_2/control_flow_collections/if_test.dart b/tests/language_2/control_flow_collections/if_test.dart index 99b3d39..4a922f8 100644 --- a/tests/language_2/control_flow_collections/if_test.dart +++ b/tests/language_2/control_flow_collections/if_test.dart
@@ -19,7 +19,6 @@ testShortCircuit(); testDuplicateKeys(); testKeyOrder(); - testRuntimeFailures(); } void testList() { @@ -229,15 +228,3 @@ }; Expect.equals("1:a,2:a", set.join(",")); } - -void testRuntimeFailures() { - dynamic nonBool = 3; - Expect.throwsTypeError(() => <int>[if (nonBool) 1]); - Expect.throwsTypeError(() => <int, int>{if (nonBool) 1: 1}); - Expect.throwsTypeError(() => <int>{if (nonBool) 1}); - - bool nullBool = null; - Expect.throwsAssertionError(() => <int>[if (nullBool) 1]); - Expect.throwsAssertionError(() => <int, int>{if (nullBool) 1: 1}); - Expect.throwsAssertionError(() => <int>{if (nullBool) 1}); -}
diff --git a/tests/language_2/control_flow_collections/type_error_test.dart b/tests/language_2/control_flow_collections/type_error_test.dart index 4e98549..533dc18 100644 --- a/tests/language_2/control_flow_collections/type_error_test.dart +++ b/tests/language_2/control_flow_collections/type_error_test.dart
@@ -34,9 +34,9 @@ var _ = <int>{for (int i in s) 1}; //# 22: compile-time error // Wrong for declaration element type. - var _ = <int>[for (int i = "s";;) 1]; //# 23: compile-time error - var _ = <int, int>{for (int i = "s";;) 1: 1}; //# 24: compile-time error - var _ = <int>{for (int i = "s";;) 1}; //# 25: compile-time error + var _ = <int>[for (int i = "s"; false;) 1]; //# 23: compile-time error + var _ = <int, int>{for (int i = "s"; false;) 1: 1}; //# 24: compile-time error + var _ = <int>{for (int i = "s"; false;) 1}; //# 25: compile-time error // Wrong for body element type. var _ = <int>[for (; false;) "s"]; //# 26: compile-time error
diff --git a/tests/language_2/control_flow_collections/utils.dart b/tests/language_2/control_flow_collections/utils.dart index b240e24..e2d6ade 100644 --- a/tests/language_2/control_flow_collections/utils.dart +++ b/tests/language_2/control_flow_collections/utils.dart
@@ -34,37 +34,37 @@ } T expectDynamic<T>(dynamic value) { - Expect.identical(dynamic, T); + Expect.equals(dynamic, T); return value; } T expectInt<T>(dynamic value) { - Expect.identical(int, T); + Expect.equals(int, T); return value; } T expectString<T>(dynamic value) { - Expect.identical(String, T); + Expect.equals(String, T); return value; } Iterable<T> expectIntIterable<T>(dynamic value) { - Expect.identical(int, T); + Expect.equals(int, T); return value; } Set<T> expectIntSet<T>() { - Expect.identical(int, T); + Expect.equals(int, T); return Set(); } Stream<T> expectIntStream<T>(dynamic elements) { - Expect.identical(int, T); + Expect.equals(int, T); return Stream<T>.fromIterable(elements); } Set<T> expectDynamicSet<T>() { - Expect.identical(dynamic, T); + Expect.equals(dynamic, T); return Set(); }
diff --git a/tests/language_2/emit_const_fields_test.dart b/tests/language_2/emit_const_fields_test.dart index 1a3d7a5..8264c50 100644 --- a/tests/language_2/emit_const_fields_test.dart +++ b/tests/language_2/emit_const_fields_test.dart
@@ -17,5 +17,5 @@ main() { Expect.isTrue(42 == Guide.LTUAE); - Expect.isTrue("1978-03-08" == Guide.EARTH["Status"][1]); + Expect.isTrue("1978-03-08" == (Guide.EARTH["Status"] as List)[1]); }
diff --git a/tests/language_2/function_propagation_test.dart b/tests/language_2/function_propagation_test.dart index 83e37d6..9c6f7e6 100644 --- a/tests/language_2/function_propagation_test.dart +++ b/tests/language_2/function_propagation_test.dart
@@ -12,14 +12,12 @@ main() { var a = new A(); - Expect.isFalse(a is A); - - var a2 = new A(); - Expect.isFalse(a is F); + Expect.type<A>(a); + Expect.notType<F>(a); Function a3 = new A(); - Expect.isFalse(a3 is A); + Expect.notType<A>(a3); F a4 = new A(); - Expect.isFalse(a4 is A); + Expect.notType<A>(a4); }
diff --git a/tests/language_2/function_subtype_inline2_test.dart b/tests/language_2/function_subtype_inline2_test.dart index 3a67be1..147bd4a 100644 --- a/tests/language_2/function_subtype_inline2_test.dart +++ b/tests/language_2/function_subtype_inline2_test.dart
@@ -27,8 +27,8 @@ int m1() => null; String m2() => null; -m3() => null; -m4(int i) => null; +Null m3() => null; +Null m4(int i) => null; main() { test((m) => new C.c1(m), 'c1');
diff --git a/tests/language_2/issue34147_test.dart b/tests/language_2/issue34147_test.dart new file mode 100644 index 0000000..69ac743 --- /dev/null +++ b/tests/language_2/issue34147_test.dart
@@ -0,0 +1,72 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; + +void main() { + conditionalTest(); + orTest(); + andTest(); + ifTest(); + forTest(); + whileTest(); + doTest(); + notTest(); +} + +void conditionalTest() { + bool x = null; + Expect.throwsAssertionError(() => x ? 1 : 0); +} + +void orTest() { + bool x = null; + Expect.throwsAssertionError(() => x || x); + Expect.throwsAssertionError(() => x || false); + Expect.throwsAssertionError(() => x || true); + Expect.throwsAssertionError(() => false || x); + Expect.isTrue(true || x); +} + +void andTest() { + bool x = null; + Expect.throwsAssertionError(() => x && x); + Expect.throwsAssertionError(() => x && false); + Expect.throwsAssertionError(() => x && true); + Expect.isFalse(false && x); + Expect.throwsAssertionError(() => true && x); +} + +void ifTest() { + bool x = null; + Expect.throwsAssertionError(() { + if (x) {} + }); +} + +void forTest() { + bool x = null; + Expect.throwsAssertionError(() { + for (; x;) {} + }); +} + +void whileTest() { + bool x = null; + Expect.throwsAssertionError(() { + while (x) {} + }); +} + +void doTest() { + bool x = null; + Expect.throwsAssertionError(() { + do {} while (x); + }); +} + +void notTest() { + bool x = null; + Expect.throwsAssertionError(() => !x); +}
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status index d7c1115..2a073ac 100644 --- a/tests/language_2/language_2_analyzer.status +++ b/tests/language_2/language_2_analyzer.status
@@ -17,7 +17,6 @@ const_cast2_test/none: CompileTimeError # failing-by-design: Not a const expression, see Issue #34334 covariant_subtyping_with_mixin_test: CompileTimeError # Issue 34329 dynamic_prefix_core_test/01: MissingCompileTimeError # failing-by-design: #34339 -emit_const_fields_test: CompileTimeError # failing-by-design: #34340 enum_syntax_test/05: Fail # Issue 34341 enum_syntax_test/06: Fail # Issue 34341 f_bounded_quantification2_test: CompileTimeError # Issue 34583
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status index 851a895..7f34dad 100644 --- a/tests/language_2/language_2_dart2js.status +++ b/tests/language_2/language_2_dart2js.status
@@ -22,7 +22,6 @@ config_import_test: RuntimeError # Test flag is not passed to the compiler. const_constructor_nonconst_param_test/01: MissingCompileTimeError const_dynamic_type_literal_test/03: Pass # but it shouldn't until we fix issue 17207 -control_flow_collections/*: Skip deopt_inlined_function_lazy_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351 deopt_smi_op_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351 double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in dart2js; bug #11551. @@ -68,6 +67,9 @@ [ $compiler != dart2js ] minify_closure_variable_collision_test: SkipByDesign # Regression test for dart2js +[ $builder_tag == dart2js_production && $compiler == dart2js ] +control_flow_collections/for_non_bool_condition_test: Crash # Issue 36442 + [ $compiler == dart2js && $runtime == chrome ] field_override_optimization_test: RuntimeError @@ -478,7 +480,6 @@ deferred_redirecting_factory_test: RuntimeError double_int_to_string_test: RuntimeError, OK # non JS number semantics dynamic_prefix_core_test/none: CompileTimeError -emit_const_fields_test: CompileTimeError enum_mirror_test: RuntimeError example_constructor_test: RuntimeError expect_test: RuntimeError, OK # Issue 13080
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status index f6296b7..3047a9d 100644 --- a/tests/language_2/language_2_dartdevc.status +++ b/tests/language_2/language_2_dartdevc.status
@@ -35,7 +35,6 @@ deferred_load_library_wrong_args_test/01: MissingRuntimeError, RuntimeError # Issue 29920 double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in ddc dynamic_prefix_core_test/01: MissingCompileTimeError -emit_const_fields_test: CompileTimeError enum_syntax_test/05: MissingCompileTimeError enum_syntax_test/06: MissingCompileTimeError execute_finally6_test: RuntimeError # Issue 29920 @@ -175,12 +174,10 @@ const_optional_args_test/01: MissingCompileTimeError const_syntax_test/05: MissingCompileTimeError constants_test/05: MissingCompileTimeError -control_flow_collections/*: Skip covariant_subtyping_test: RuntimeError deferred_load_library_wrong_args_test/01: CompileTimeError double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in ddk dynamic_prefix_core_test/none: CompileTimeError -emit_const_fields_test: CompileTimeError # Issue 31533 external_test/21: CompileTimeError external_test/24: CompileTimeError function_propagation_test: RuntimeError
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status index 53267cd..96c638e 100644 --- a/tests/language_2/language_2_kernel.status +++ b/tests/language_2/language_2_kernel.status
@@ -37,7 +37,6 @@ const_nested_test: RuntimeError const_string_test: RuntimeError constructor12_test: RuntimeError -control_flow_collections/*: Skip covariant_subtyping_test: RuntimeError ct_const_test: RuntimeError cyclic_type2_test: CompileTimeError @@ -49,7 +48,6 @@ deferred_redirecting_factory_test: RuntimeError deferred_static_seperate_test: RuntimeError dynamic_prefix_core_test/none: CompileTimeError -emit_const_fields_test: CompileTimeError example_constructor_test: RuntimeError external_test/10: MissingRuntimeError external_test/13: MissingRuntimeError @@ -124,12 +122,6 @@ regress_29025_test: CompileTimeError regress_29405_test: CompileTimeError regress_30339_test: CompileTimeError -spread_collections/await_test: CompileTimeError -spread_collections/const_test: CompileTimeError -spread_collections/inference_test: CompileTimeError -spread_collections/map_set_ambiguity_test: CompileTimeError -spread_collections/spread_test: CompileTimeError -spread_collections/syntax_test: CompileTimeError string_interpolation_and_buffer_test: RuntimeError super_bound_closure_test/none: CompileTimeError super_test: RuntimeError @@ -146,32 +138,9 @@ mixin_method_override_test/G5: Skip # Issue 34354 private_method_tearoff_test: RuntimeError -[ $compiler == dartk ] -control_flow_collections/*: Skip - [ $compiler == dartkp ] -control_flow_collections/*: Skip covariant_subtyping_test: RuntimeError generic_no_such_method_dispatcher_test: RuntimeError # Issue 31424 -spread_collections/await_test: CompileTimeError -spread_collections/const_error_test/02: MissingCompileTimeError -spread_collections/const_error_test/03: MissingCompileTimeError -spread_collections/const_error_test/05: MissingCompileTimeError -spread_collections/const_error_test/06: MissingCompileTimeError -spread_collections/const_error_test/07: MissingCompileTimeError -spread_collections/const_error_test/08: MissingCompileTimeError -spread_collections/const_error_test/10: MissingCompileTimeError -spread_collections/const_error_test/11: MissingCompileTimeError -spread_collections/const_error_test/12: MissingCompileTimeError -spread_collections/const_error_test/13: MissingCompileTimeError -spread_collections/const_error_test/14: MissingCompileTimeError -spread_collections/const_error_test/15: MissingCompileTimeError -spread_collections/const_error_test/16: MissingCompileTimeError -spread_collections/const_test: CompileTimeError -spread_collections/inference_test: CompileTimeError -spread_collections/map_set_ambiguity_test: CompileTimeError -spread_collections/spread_test: CompileTimeError -spread_collections/syntax_test: CompileTimeError web_int_literals_test/*: SkipByDesign # Test applies only to JavaScript targets [ $compiler == fasta ] @@ -191,24 +160,6 @@ const_constructor_nonconst_param_test/01: MissingCompileTimeError constructor5_test: CompileTimeError # Verification error constructor6_test: CompileTimeError # Verification error -control_flow_collections/await_for_inference_test: CompileTimeError -control_flow_collections/await_for_test: CompileTimeError -control_flow_collections/if_const_error_test/21: MissingCompileTimeError -control_flow_collections/if_const_error_test/22: MissingCompileTimeError -control_flow_collections/if_const_error_test/23: MissingCompileTimeError -control_flow_collections/if_const_error_test/24: MissingCompileTimeError -control_flow_collections/if_const_error_test/35: MissingCompileTimeError -control_flow_collections/if_const_error_test/36: MissingCompileTimeError -control_flow_collections/if_const_error_test/37: MissingCompileTimeError -control_flow_collections/if_promotion_test/none: CompileTimeError -control_flow_collections/type_error_test/00: MissingCompileTimeError -control_flow_collections/type_error_test/01: MissingCompileTimeError -control_flow_collections/type_error_test/02: MissingCompileTimeError -control_flow_collections/type_error_test/10: MissingCompileTimeError -control_flow_collections/type_error_test/13: MissingCompileTimeError -control_flow_collections/type_error_test/23: MissingCompileTimeError -control_flow_collections/type_error_test/24: MissingCompileTimeError -control_flow_collections/type_error_test/25: MissingCompileTimeError implicit_creation/implicit_const_not_default_values_test/e1: MissingCompileTimeError implicit_creation/implicit_const_not_default_values_test/e10: MissingCompileTimeError implicit_creation/implicit_const_not_default_values_test/e11: MissingCompileTimeError @@ -230,10 +181,6 @@ implicit_creation/implicit_const_not_default_values_test/e7: MissingCompileTimeError implicit_creation/implicit_const_not_default_values_test/e8: MissingCompileTimeError mixin_method_override_test/G4: Crash # Assertion error: mixin_full_resolution.dart': 'src.typeParameters.length == dst.typeParameters.length': is not true. -spread_collections/const_error_test/12: MissingCompileTimeError -spread_collections/const_error_test/13: Crash -spread_collections/const_error_test/13: MissingCompileTimeError -spread_collections/const_error_test/14: MissingCompileTimeError vm/regress_33469_test/01: MissingCompileTimeError vm/regress_33469_test/02: MissingCompileTimeError vm/regress_33469_test/03: MissingCompileTimeError @@ -247,10 +194,6 @@ async_return_types_test/nestedFuture: MissingCompileTimeError # Issue 33068 const_cast2_test/01: CompileTimeError # Issue 32517 const_cast2_test/none: CompileTimeError # Issue 32517 -constants_2018/equals_test/01: MissingCompileTimeError # New test introduced in https://dart-review.googlesource.com/c/sdk/+/97510 -constants_2018/equals_test/02: MissingCompileTimeError # New test introduced in https://dart-review.googlesource.com/c/sdk/+/97510 -constants_2018/equals_test/03: MissingCompileTimeError # New test introduced in https://dart-review.googlesource.com/c/sdk/+/97510 -constants_2018/equals_test/04: MissingCompileTimeError # New test introduced in https://dart-review.googlesource.com/c/sdk/+/97510 constants_2018/potential_const_dynamic_test/sh3: CompileTimeError # New test introduced in https://dart-review.googlesource.com/c/sdk/+/97510 constants_2018/potential_const_type_test/sh3: CompileTimeError # New test introduced in https://dart-review.googlesource.com/c/sdk/+/97510 deferred_inheritance_constraints_test/extends: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273. @@ -447,22 +390,6 @@ vm/debug_break_enabled_vm_test/none: CompileTimeError # KernelVM bug: Bad test using extended break syntax. vm/regress_27201_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273. -[ $arch != simarm && $arch != simarm64 && $arch != simdbc64 && $compiler == dartk ] -spread_collections/await_test: CompileTimeError -spread_collections/const_test: CompileTimeError -spread_collections/inference_test: CompileTimeError -spread_collections/map_set_ambiguity_test: CompileTimeError -spread_collections/spread_test: CompileTimeError -spread_collections/syntax_test: CompileTimeError - -[ $arch == simdbc64 && $compiler == dartk ] -spread_collections/await_test: CompileTimeError -spread_collections/const_test: CompileTimeError -spread_collections/inference_test: CompileTimeError -spread_collections/map_set_ambiguity_test: CompileTimeError -spread_collections/spread_test: CompileTimeError -spread_collections/syntax_test: CompileTimeError - [ $builder_tag == obfuscated && $compiler == dartkp ] generic_function_dcall_test/01: SkipByDesign # Prints type names invocation_mirror_test: RuntimeError # Issue 34911 @@ -555,33 +482,14 @@ assertion_initializer_const_error2_test/cc09: MissingCompileTimeError # Not reporting failed assert() at compile time. assertion_initializer_const_error2_test/cc10: MissingCompileTimeError # Not reporting failed assert() at compile time. -[ $compiler == dartk && ($arch == simarm || $arch == simarm64) ] -spread_collections/await_test: CompileTimeError -spread_collections/const_test: CompileTimeError -spread_collections/inference_test: CompileTimeError -spread_collections/map_set_ambiguity_test: CompileTimeError -spread_collections/spread_test: CompileTimeError -spread_collections/syntax_test: CompileTimeError - [ $compiler == dartkb && $runtime == vm && $strong ] async_star_test/03: Pass, RuntimeError # Please triage async_star_test/04: Pass, RuntimeError # Please triage compile_time_constant_o_test/01: Pass compile_time_constant_o_test/02: Pass const_dynamic_type_literal_test/02: Pass -control_flow_collections/*: Skip map_literal3_test/01: Pass map_literal3_test/02: Pass -spread_collections/await_test: CompileTimeError -spread_collections/const_test: CompileTimeError -spread_collections/inference_test: CompileTimeError -spread_collections/map_set_ambiguity_test: CompileTimeError -spread_collections/spread_test: CompileTimeError -spread_collections/syntax_test: CompileTimeError -spread_collections/type_error_test/00: DartkCrash -spread_collections/type_error_test/02: DartkCrash -spread_collections/type_error_test/03: DartkCrash -spread_collections/type_error_test/05: DartkCrash vm/bool_check_stack_traces_test/02: Pass vm/causal_async_exception_stack2_test: RuntimeError # Please triage vm/causal_async_exception_stack_test: RuntimeError # Please triage @@ -744,7 +652,6 @@ deferred_static_seperate_test: RuntimeError # KernelVM bug: Deferred loading kernel issue 30273. deopt_inlined_function_lazy_test: Skip # Incompatible flag: --deoptimize-alot dynamic_prefix_core_test/none: CompileTimeError -emit_const_fields_test: CompileTimeError # Issue 31533 enum_mirror_test: SkipByDesign example_constructor_test: Fail, OK export_ambiguous_main_test: Skip # Issue 29895 Fail Issue 14763 @@ -901,7 +808,6 @@ constants_test/05: MissingCompileTimeError deferred_load_library_wrong_args_test/01: CompileTimeError dynamic_prefix_core_test/none: CompileTimeError -emit_const_fields_test: CompileTimeError external_test/21: CompileTimeError external_test/24: CompileTimeError generic_no_such_method_dispatcher_simple_test: CompileTimeError @@ -1291,7 +1197,6 @@ deferred_static_seperate_test: RuntimeError # KernelVM bug: Deferred loading kernel issue 30273. disassemble_test: Pass, Slow, Crash # dartbug.com/34971 dynamic_prefix_core_test/none: CompileTimeError -emit_const_fields_test: CompileTimeError # Issue 31533 example_constructor_test: Fail, OK external_test/10: MissingRuntimeError # KernelVM bug: Unbound external. external_test/13: MissingRuntimeError # KernelVM bug: Unbound external.
diff --git a/tests/language_2/super_test.dart b/tests/language_2/super_test.dart index 7394989..f96f4fe 100644 --- a/tests/language_2/super_test.dart +++ b/tests/language_2/super_test.dart
@@ -17,10 +17,10 @@ Expect.equals(3, sub.u); sub = new Sub.stat(); - Expect.equals(0, sub.x); - Expect.equals(1, sub.y); - Expect.equals(2, sub.v); - Expect.equals(3, sub.w); + Expect.equals(2, sub.x); + Expect.equals(3, sub.y); + Expect.equals(0, sub.v); + Expect.equals(1, sub.w); Expect.equals(4, sub.z); Expect.equals(5, sub.u); }
diff --git a/tests/language_2/unevaluated_field.dart b/tests/language_2/unevaluated_field.dart new file mode 100644 index 0000000..d674af5 --- /dev/null +++ b/tests/language_2/unevaluated_field.dart
@@ -0,0 +1,23 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// SharedOptions=--enable-experiment=constant-update-2018 + +// Test that environment constants in field initializers work properly. + +import "package:expect/expect.dart"; + +const int gx = const int.fromEnvironment("x"); + +class A { + final int x = gx; + final int y = const int.fromEnvironment("y"); + const A(); +} + +main() { + const a = const A(); + Expect.isTrue(a.x == null || a.x != null); + Expect.isTrue(a.y == null || a.y != null); +}
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status index a709997..04313d4 100644 --- a/tests/lib_2/lib_2_kernel.status +++ b/tests/lib_2/lib_2_kernel.status
@@ -16,6 +16,9 @@ async/timer_not_available_test: RuntimeError isolate/ping_pause_test: Skip # Timeout +[ $compiler == dartkb ] +mirrors/*: Skip # Mirrors are not yet supported in bytecode modes. + [ $compiler == fasta ] html/*: Skip # TODO(ahe): Make dart:html available. isolate/browser/*: Skip # TODO(ahe): Make dart:html available.
diff --git a/tests/standalone_2/io/secure_socket_renegotiate_test.dart b/tests/standalone_2/io/secure_socket_renegotiate_test.dart index e527da9..d10e743 100644 --- a/tests/standalone_2/io/secure_socket_renegotiate_test.dart +++ b/tests/standalone_2/io/secure_socket_renegotiate_test.dart
@@ -4,6 +4,7 @@ // // OtherResources=certificates/server_chain.pem // OtherResources=certificates/server_key.pem +// OtherResources=secure_socket_renegotiate_client.dart // This test verifies that client certificates work, if the client and server // are in separate processes, and that connection renegotiation works, and @@ -66,10 +67,10 @@ void main() { runServer().then((SecureServerSocket server) { var clientScript = - Platform.script.toFilePath().replaceFirst("_test.dart", "_client.dart"); - Expect.isTrue(clientScript.endsWith("_client.dart")); + Platform.script.resolve('secure_socket_renegotiate_client.dart').toFilePath(); Process - .run(Platform.executable, [clientScript, server.port.toString()]).then( + .run(Platform.executable, + []..addAll(Platform.executableArguments)..addAll([clientScript, server.port.toString()])).then( (ProcessResult result) { if (result.exitCode != 0) { print("Client failed, stdout:");
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status index cf60651..74d303c 100644 --- a/tests/standalone_2/standalone_2.status +++ b/tests/standalone_2/standalone_2.status
@@ -86,7 +86,7 @@ no_assert_test: Fail, OK # This is testing a vm flag. [ $mode == product && $runtime == dart_precompiled ] -dwarf_stack_trace_test: Pass, RuntimeError +dwarf_stack_trace_test: SkipByDesign # Due to instruction canonicalization we can end up having the wrong names in stack traces. [ $mode == release && $runtime == vm && $system == macos ] io/named_pipe_script_test: Pass, RuntimeError # Issue 28737
diff --git a/third_party/.gitignore b/third_party/.gitignore index 836a11d..28a6f8a 100644 --- a/third_party/.gitignore +++ b/third_party/.gitignore
@@ -12,6 +12,5 @@ !clang.tar.gz.sha1 !unittest.tar.gz.sha1 !update.sh -!/googletest # but ignore a subfolder of tcmalloc (some client ignores /tcmalloc/.gitignore) /tcmalloc/gperftools
diff --git a/tools/FAKE_COMMITS b/tools/FAKE_COMMITS index c11b0c2..32518f9 100644 --- a/tools/FAKE_COMMITS +++ b/tools/FAKE_COMMITS
@@ -28,3 +28,4 @@ Analyzer branch commits: Force build on new analyzer-branch linux build with new workflow Trigger bots +Switch benchmark builders to Ubuntu 16.04
diff --git a/tools/VERSION b/tools/VERSION index 83fcfb8..d0461b8 100644 --- a/tools/VERSION +++ b/tools/VERSION
@@ -33,7 +33,7 @@ MAJOR 2 MINOR 2 PATCH 1 -PRERELEASE 3 -PRERELEASE_PATCH 1 -ABI_VERSION 1 -OLDEST_SUPPORTED_ABI_VERSION 0 +PRERELEASE 4 +PRERELEASE_PATCH 0 +ABI_VERSION 2 +OLDEST_SUPPORTED_ABI_VERSION 1
diff --git a/tools/addlatexhash.dart b/tools/addlatexhash.dart index 21f8d52..c1cbddc 100755 --- a/tools/addlatexhash.dart +++ b/tools/addlatexhash.dart
@@ -22,11 +22,11 @@ // NB: This utility assumes UN*X style line endings, \n, in the LaTeX // source file received as input; it will not work with other styles. +import 'dart:convert'; import 'dart:io'; -import 'package:crypto/crypto.dart'; import 'package:convert/convert.dart'; -import 'package:utf/utf.dart'; +import 'package:crypto/crypto.dart'; // ---------------------------------------------------------------------- // Normalization of the text: removal or normalization of parts that @@ -491,7 +491,7 @@ final gatheredLine = gatherLines(lines, startIndex, nextIndex); final simplifiedLine = simplifyLine(gatheredLine); listSink.write(" % $simplifiedLine\n"); - var digest = sha1.convert(encodeUtf8(simplifiedLine)); + var digest = sha1.convert(utf8.encode(simplifiedLine)); return digest.bytes; }
diff --git a/tools/bots/dart_sdk.py b/tools/bots/dart_sdk.py index f9688a9..301f269 100755 --- a/tools/bots/dart_sdk.py +++ b/tools/bots/dart_sdk.py
@@ -66,10 +66,19 @@ sdk_path = os.path.join(bot_utils.DART_DIR, utils.GetBuildRoot(BUILD_OS, 'release', arch), 'dart-sdk') + product_sdk_path = os.path.join(bot_utils.DART_DIR, + utils.GetBuildRoot(BUILD_OS, 'product', arch), + 'dart-sdk') sdk_zip = os.path.join(bot_utils.DART_DIR, utils.GetBuildRoot(BUILD_OS, 'release', arch), 'dartsdk-%s-%s.zip' % (BUILD_OS, arch)) FileDelete(sdk_zip) + # We don't support precompilation on ia32. + if arch != 'ia32': + # Patch in all the PRODUCT built AOT binaries. + CopyBetween(product_sdk_path, sdk_path, 'bin', 'utils', GuessExtension('gen_snapshot')) + CopyBetween(product_sdk_path, sdk_path, 'bin', GuessExtension('dartaotruntime')) + # Zip it up. CreateZip(sdk_path, sdk_zip) DartArchiveUploadSDKs(BUILD_OS, arch, sdk_zip) @@ -186,6 +195,21 @@ if os.path.exists(f): os.remove(f) +def CopyBetween(src_path, dst_path, *relatives): + try: + os.makedirs(os.path.join(dst_path, *relatives[:-1])) + except OSError: + # This is fine. + pass + shutil.copy2( + os.path.join(src_path, *relatives), + os.path.join(dst_path, *relatives[:-1])) + +def GuessExtension(binary): + if 'win' in BUILD_OS: + return binary + '.exe' + return binary + def DartArchiveFile(local_path, remote_path, checksum_files=False): gsutil = bot_utils.GSUtil() gsutil.upload(local_path, remote_path, public=True)
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json index 16e0f7d..78e10bc 100644 --- a/tools/bots/test_matrix.json +++ b/tools/bots/test_matrix.json
@@ -266,6 +266,7 @@ }}, "dart2js-production-(linux|mac|win)-d8": { "options": { + "builder-tag": "dart2js_production", "use-sdk": true, "dart2js-options": ["-O3"] }}, @@ -323,7 +324,7 @@ "dartk-optcounter-(linux|mac|win)-(debug|product|release)-(ia32|x64)": { "options": { "builder-tag": "optimization_counter_threshold", - "vm-options": ["--optimization-counter-threshold=5"] + "vm-options": ["--optimization-counter-threshold=5", "--random-seed=__RANDOM__"] }}, "dartk-reload-(linux|mac|win)-(debug|product|release)-(ia32|x64)": { "options": { @@ -441,12 +442,7 @@ { "name": "vm mixed mode tests", "arguments": [ - "-ndartkb-mixed-linux-${mode}-${arch}", - "language_2", - "corelib_2", - "lib_2", - "standalone_2", - "ffi" + "-ndartkb-mixed-linux-${mode}-${arch}" ], "fileset": "vm-kernel", "shards": 10 @@ -454,12 +450,7 @@ { "name": "vm bytecode compiler tests", "arguments": [ - "-ndartkb-compile-linux-${mode}-${arch}", - "language_2", - "corelib_2", - "lib_2", - "standalone_2", - "ffi" + "-ndartkb-compile-linux-${mode}-${arch}" ], "fileset": "vm-kernel", "shards": 10 @@ -467,12 +458,7 @@ { "name": "vm interpreter tests", "arguments": [ - "-ndartkb-interpret-linux-${mode}-${arch}", - "language_2", - "corelib_2", - "lib_2", - "standalone_2", - "ffi" + "-ndartkb-interpret-linux-${mode}-${arch}" ], "fileset": "vm-kernel", "shards": 10 @@ -1328,6 +1314,18 @@ "--mode=release", "create_sdk"] }, { + "name": "build gen_kernel.dart.snapshot and dart2aot", + "script": "tools/build.py", + "arguments": ["--arch=x64,arm,arm64", "--mode=release", + "copy_gen_kernel_snapshot", "copy_dart2aot"] + }, + { + "name": "build gen_snapshot and dartaotruntime", + "script": "tools/build.py", + "arguments": ["--arch=x64,arm,arm64", "--mode=product", + "copy_gen_snapshot", "copy_dartaotruntime"] + }, + { "name": "upload sdk", "script": "tools/bots/dart_sdk.py" }, @@ -1360,6 +1358,18 @@ "--mode=release", "create_sdk"] }, { + "name": "build gen_kernel.dart.snapshot and dart2aot", + "script": "tools/build.py", + "arguments": ["--arch=x64", "--mode=release", + "copy_gen_kernel_snapshot", "copy_dart2aot"] + }, + { + "name": "build gen_snapshot and dartaotruntime", + "script": "tools/build.py", + "arguments": ["--arch=x64", "--mode=product", + "copy_gen_snapshot", "copy_dartaotruntime"] + }, + { "name": "upload sdk", "script": "tools/bots/dart_sdk.py" } @@ -1714,14 +1724,23 @@ "arguments": ["noop"] }, { - "name": "remove out directory to do a clean build", + "name": "remove out directory to do a clean linux-ia32 build", "script": "tools/bots/try_benchmarks.sh", "arguments": ["clean"] }, { "name": "build linux-ia32 for benchmarking", + "script": "tools/build.py", + "arguments": [ + "--mode=release", + "--arch=ia32", + "create_sdk", + "runtime"] + }, + { + "name": "archive linux-ia32 for benchmarking", "script": "tools/bots/try_benchmarks.sh", - "arguments": ["linux-ia32-build"] + "arguments": ["linux-ia32-archive"] }, { "name": "try linux-ia32 benchmarking", @@ -1729,14 +1748,69 @@ "arguments": ["linux-ia32-benchmark"] }, { - "name": "build linux-x64 for benchmarking", + "name": "remove out directory to do a clean linux-x64 build", "script": "tools/bots/try_benchmarks.sh", - "arguments": ["linux-x64-build"] + "arguments": ["clean"] + }, + { + "name": "build linux-x64 for benchmarking", + "script": "tools/build.py", + "arguments": [ + "--mode=release", + "--arch=x64", + "create_sdk", + "runtime", + "gen_snapshot", + "dart_precompiled_runtime"] + }, + { + "name": "build linux-x64 simdbc for benchmarking", + "script": "tools/build.py", + "arguments": ["--mode=release", "--arch=simdbc64", "runtime"] + }, + { + "name": "archive linux-x64 for benchmarking", + "script": "tools/bots/try_benchmarks.sh", + "arguments": ["linux-x64-archive"] }, { "name": "try linux-x64 benchmarking", "script": "tools/bots/try_benchmarks.sh", "arguments": ["linux-x64-benchmark"] + }, + { + "name": "remove out directory to do a clean linux-x64-bytecode build", + "script": "tools/bots/try_benchmarks.sh", + "arguments": ["clean"] + }, + { + "name": "generate ninja for linux-x64-bytecode", + "script": "tools/gn.py", + "arguments": [ + "--mode=release", + "--arch=x64", + "--bytecode"] + }, + { + "name": "build linux-x64-bytecode for benchmarking", + "script": "tools/build.py", + "arguments": [ + "--mode=release", + "--arch=x64", + "create_sdk", + "runtime", + "gen_snapshot", + "dart_precompiled_runtime"] + }, + { + "name": "archive linux-x64-bytecode for benchmarking", + "script": "tools/bots/try_benchmarks.sh", + "arguments": ["linux-x64-bytecode-archive"] + }, + { + "name": "try linux-x64-bytecode benchmarking", + "script": "tools/bots/try_benchmarks.sh", + "arguments": ["linux-x64-bytecode-benchmark"] } ] },
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh index 5f0aa28..a501a0d 100755 --- a/tools/bots/try_benchmarks.sh +++ b/tools/bots/try_benchmarks.sh
@@ -13,16 +13,23 @@ owner=sortie if [ $# -lt 1 ]; then - echo "Usage: $0 COMMAND ..." - echo - echo "Where COMMAND is one of:" - echo - echo " noop - Just print description." - echo " clean - Remove out/ directory." - echo " linux-ia32-build - Build linux-ia32 for benchmarking." - echo " linux-ia32-benchmark - Try linux-ia32 benchmarking." - echo " linux-x64-build - Build linux-x64 for benchmarking." - echo " linux-x64-benchmark - Try linux-x64 benchmarking." +cat << EOF +Usage: $0 COMMAND ..." + +Where COMMAND is one of:" + + noop - Just print description. + clean - Remove out/ directory. + linux-ia32-build - Build linux-ia32 for benchmarking. + linux-ia32-archive - Archive linux-ia32. + linux-ia32-benchmark - Try linux-ia32 benchmarking. + linux-x64-build - Build linux-x64 for benchmarking. + linux-x64-archive - Archive linux-x64. + linux-x64-benchmark - Try linux-x64 benchmarking. + linux-x64-bytecode-build - Build linux-x64 with bytecode for benchmarking. + linux-x64-bytecode-archive - Archive linux-x64 with bytecode. + linux-x64-bytecode-benchmark - Try linux-x64 with bytecode benchmarking. +EOF exit 1 fi @@ -64,13 +71,16 @@ : elif [ "$command" = clean ]; then rm -rf out + rm -rf tmp rm -f linux-ia32.tar.gz rm -f linux-ia32_profile.tar.gz rm -f linux-x64.tar.gz rm -f linux-x64_profile.tar.gz elif [ "$command" = linux-ia32-build ]; then + # NOTE: These are duplicated in tools/bots/test_matrix.json, keep in sync. ./tools/build.py --mode=release --arch=ia32 create_sdk ./tools/build.py --mode=release --arch=ia32 runtime + elif [ "$command" = linux-ia32-archive ]; then tar -czf linux-ia32_profile.tar.gz \ --exclude .git \ --exclude .gitignore \ @@ -208,12 +218,24 @@ out/ReleaseIA32/run_vm_tests GenKernelKernelLoadKernel cd .. rm -rf tmp - elif [ "$command" = linux-x64-build ]; then + elif [ "$command" = linux-x64-build ] || + [ "$command" = linux-x64-bytecode-build ]; then + # NOTE: These are duplicated in tools/bots/test_matrix.json, keep in sync. + if [ "$command" = linux-x64-bytecode-build ]; then + # Beware: Don't mix --bytecode with a non-bytecode out/. + ./tools/gn.py --mode=release --arch=x64 --bytecode + fi ./tools/build.py --mode=release --arch=x64 create_sdk ./tools/build.py --mode=release --arch=x64 runtime ./tools/build.py --mode=release --arch=x64 gen_snapshot ./tools/build.py --mode=release --arch=x64 dart_precompiled_runtime ./tools/build.py --mode=release --arch=simdbc64 runtime + elif [ "$command" = linux-x64-archive ] || + [ "$command" = linux-x64-bytecode-archive ]; then + simdbc_dart=out/ReleaseSIMDBC64/dart + if [ "$command" = linux-x64-bytecode-archive ]; then + simdbc_dart= + fi tar -czf linux-x64_profile.tar.gz \ --exclude .git \ --exclude .gitignore \ @@ -223,7 +245,7 @@ out/ReleaseX64/vm_outline_strong.dill \ out/ReleaseX64/vm_platform_strong.dill \ out/ReleaseX64/dart-sdk \ - out/ReleaseSIMDBC64/dart \ + $simdbc_dart \ out/ReleaseX64/dart \ out/ReleaseX64/gen_snapshot \ out/ReleaseX64/gen_kernel_bytecode.dill \ @@ -324,7 +346,7 @@ out/ReleaseX64/vm_outline_strong.dill \ out/ReleaseX64/vm_platform_strong.dill \ out/ReleaseX64/dart-sdk \ - out/ReleaseSIMDBC64/dart \ + $simdbc_dart \ out/ReleaseX64/dart \ out/ReleaseX64/gen_snapshot \ out/ReleaseX64/gen_kernel_bytecode.dill \ @@ -340,7 +362,8 @@ runtime/bin \ runtime/lib \ || (rm -f linux-x64.tar.gz; exit 1) - elif [ "$command" = linux-x64-benchmark ]; then + elif [ "$command" = linux-x64-benchmark ] || + [ "$command" = linux-x64-bytecode-benchmark ]; then rm -rf tmp mkdir tmp cd tmp @@ -358,7 +381,9 @@ out/ReleaseX64/dart --profile-period=10000 --packages=.packages --enable-interpreter --compilation-counter-threshold=-1 hello.dart out/ReleaseX64/dart --profile-period=10000 --packages=.packages --use-bytecode-compiler hello.dart out/ReleaseX64/dart --profile-period=10000 --packages=.packages --use-bytecode-compiler --optimization-counter-threshold=-1 hello.dart - out/ReleaseSIMDBC64/dart --profile-period=10000 --packages=.packages hello.dart + if [ "$command" = linux-x64-benchmark ]; then + out/ReleaseSIMDBC64/dart --profile-period=10000 --packages=.packages hello.dart + fi out/ReleaseX64/dart pkg/front_end/tool/perf.dart parse hello.dart out/ReleaseX64/dart pkg/front_end/tool/perf.dart scan hello.dart out/ReleaseX64/dart pkg/front_end/tool/fasta_perf.dart --legacy kernel_gen_e2e hello.dart
diff --git a/tools/download_abi_dills.py b/tools/download_abi_dills.py index fb77a55..6eaa9e6 100644 --- a/tools/download_abi_dills.py +++ b/tools/download_abi_dills.py
@@ -6,22 +6,50 @@ import utils -def main(): - abi_version = int(utils.GetAbiVersion()) - oldest_abi_version = int(utils.GetOldestSupportedAbiVersion()) +def procWait(p): + while p.returncode is None: + p.communicate() + p.poll() + return p.returncode + + +def findAbiVersion(version): + cmd = ['cipd', 'instances', 'dart/abiversions/%d' % version] + p = subprocess.Popen(cmd, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE, + shell = utils.IsWindows(), + cwd = utils.DART_DIR) + return procWait(p) == 0 + + +def downloadAbiDills(oldest_abi_version, abi_version): cmd = ['cipd', 'ensure', '-root', 'tools/abiversions', '-ensure-file', '-'] ensure_file = '' - for i in xrange(oldest_abi_version, abi_version): + for i in xrange(oldest_abi_version, abi_version + 1): ensure_file += '@Subdir %d\ndart/abiversions/%d latest\n\n' % (i, i) if not ensure_file: return 0 p = subprocess.Popen(cmd, stdin = subprocess.PIPE, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE, shell = utils.IsWindows(), cwd = utils.DART_DIR) p.communicate(ensure_file) p.stdin.close() - return p.wait() + return procWait(p) + + +def main(): + abi_version = int(utils.GetAbiVersion()) + oldest_abi_version = int(utils.GetOldestSupportedAbiVersion()) + + # The latest abi version may not have an entry in CIPD yet, so check first. + if not findAbiVersion(abi_version): + abi_version -= 1 + + return downloadAbiDills(oldest_abi_version, abi_version) if __name__ == '__main__':
diff --git a/tools/gn.py b/tools/gn.py index bc05a61..fbd1814 100755 --- a/tools/gn.py +++ b/tools/gn.py
@@ -245,6 +245,8 @@ if not args.platform_sdk and not gn_args['target_cpu'].startswith('arm'): gn_args['dart_platform_sdk'] = args.platform_sdk gn_args['dart_stripped_binary'] = 'exe.stripped/dart' + gn_args['dartaotruntime_stripped_binary'] = 'exe.stripped/dartaotruntime' + gn_args['gen_snapshot_stripped_binary'] = 'exe.stripped/gen_snapshot' # Setup the user-defined sysroot. if UseSysroot(args, gn_args):
diff --git a/tools/infra/config/OWNERS b/tools/infra/config/OWNERS deleted file mode 100644 index 90c8c15..0000000 --- a/tools/infra/config/OWNERS +++ /dev/null
@@ -1,6 +0,0 @@ -agable@google.com -athom@google.com -iannucci@google.com -kustermann@google.com -tandrii@google.com -whesse@google.com
diff --git a/tools/infra/config/README.md b/tools/infra/config/README.md deleted file mode 100644 index a46a2e7..0000000 --- a/tools/infra/config/README.md +++ /dev/null
@@ -1 +0,0 @@ -This directory contains configuration files for chrome infrastructure services.
diff --git a/tools/infra/config/cq.cfg b/tools/infra/config/cq.cfg deleted file mode 100644 index dd1680c..0000000 --- a/tools/infra/config/cq.cfg +++ /dev/null
@@ -1,42 +0,0 @@ -# See http://luci-config.appspot.com/schemas/projects/refs:cq.cfg for the -# documentation of this file format. -version: 1 -cq_status_url: "https://chromium-cq-status.appspot.com" -git_repo_url: "https://dart.googlesource.com/sdk.git" -max_commit_burst: 2 -gerrit {} -verifiers { - gerrit_cq_ability { - committer_list: "project-dart-committers" - dry_run_access_list: "project-dart-tryjob-access" - allow_submit_with_open_deps: true - } - tree_status { - tree_status_url: "https://dart-status.appspot.com" - } - try_job { - buckets { - name: "luci.dart.try" - builders { name: "analyzer-analysis-server-linux-try" } - builders { name: "analyzer-linux-release-try" } - builders { name: "benchmark-linux-try" } - builders { name: "dart-sdk-windows-try" } - builders { name: "dart2js-strong-linux-x64-chrome-try" } - builders { name: "dart2js-minified-strong-linux-x64-d8-try" } - builders { name: "dart2js-strong-hostasserts-linux-ia32-d8-try" } - builders { name: "dart2js-unit-linux-x64-release-try" } - builders { name: "ddc-linux-release-chrome-try" } - builders { name: "front-end-linux-release-x64-try" } - builders { name: "gclient-try" } - builders { name: "pkg-linux-release-try" } - builders { name: "vm-canary-linux-debug-try" } - builders { name: "vm-kernel-linux-release-simdbc64-try" } - builders { name: "vm-kernel-linux-release-x64-try" } - builders { name: "vm-kernel-mac-release-x64-try" experiment_percentage: 5 } - builders { name: "vm-kernel-linux-product-x64-try" } - } - try_job_retry_config { - try_job_retry_quota: 0 - } - } -}
diff --git a/tools/patches/flutter-engine/75b2f9f919e5728902aff39a09223d1cc9402585.patch b/tools/patches/flutter-engine/75b2f9f919e5728902aff39a09223d1cc9402585.patch deleted file mode 100644 index 9d4241f..0000000 --- a/tools/patches/flutter-engine/75b2f9f919e5728902aff39a09223d1cc9402585.patch +++ /dev/null
@@ -1,28 +0,0 @@ -diff --git a/BUILD.gn b/BUILD.gn -index 2766d1b98..828196f8d 100644 ---- a/BUILD.gn -+++ b/BUILD.gn -@@ -60,8 +60,8 @@ group("flutter") { - - if (is_linux) { - public_deps += [ -- "$flutter_root/shell/platform/common/cpp/client_wrapper:client_wrapper_unittests", -- "$flutter_root/shell/platform/glfw/client_wrapper:client_wrapper_glfw_unittests", -+# "$flutter_root/shell/platform/common/cpp/client_wrapper:client_wrapper_unittests", -+# "$flutter_root/shell/platform/glfw/client_wrapper:client_wrapper_glfw_unittests", - ] - } - } -diff --git a/shell/platform/BUILD.gn b/shell/platform/BUILD.gn -index c3bd7569c..30abe167a 100644 ---- a/shell/platform/BUILD.gn -+++ b/shell/platform/BUILD.gn -@@ -13,7 +13,7 @@ group("platform") { - ] - } else if (is_linux) { - deps = [ -- "linux", -+# "linux", - ] - } else if (is_win) { - deps = [
diff --git a/tools/patches/flutter-engine/cc63d6e647df1cfd34a54adb63aba7f937ce6f6b.patch b/tools/patches/flutter-engine/cc63d6e647df1cfd34a54adb63aba7f937ce6f6b.patch new file mode 100644 index 0000000..5e81c49 --- /dev/null +++ b/tools/patches/flutter-engine/cc63d6e647df1cfd34a54adb63aba7f937ce6f6b.patch
@@ -0,0 +1,31 @@ +diff --git a/DEPS b/DEPS +index d7973695e..1113c3101 100644 +--- a/DEPS ++++ b/DEPS +@@ -52,7 +52,7 @@ vars = { + 'dart_dartdoc_tag': 'v0.28.2', + 'dart_fixnum_tag': '0.10.9', + 'dart_glob_tag': '1.1.7', +- 'dart_html_tag': '0.13.4+1', ++ 'dart_html_tag': '0.14.0', + 'dart_http_multi_server_tag': '2.0.5', + 'dart_http_parser_tag': '3.1.3', + 'dart_http_retry_tag': '0.1.1', +@@ -94,7 +94,6 @@ vars = { + 'dart_test_tag': '1.3.4', + 'dart_typed_data_tag': '1.1.6', + 'dart_usage_tag': '3.4.0', +- 'dart_utf_tag': '0.9.0+5', + 'dart_watcher_rev': '0.9.7+12', + 'dart_web_socket_channel_tag': '1.0.9', + 'dart_yaml_tag': '2.1.15', +@@ -341,9 +340,6 @@ deps = { + 'src/third_party/dart/third_party/pkg/test': + Var('dart_git') + '/test.git' + '@' + Var('dart_test_tag'), + +- 'src/third_party/dart/third_party/pkg/utf': +- Var('dart_git') + '/utf.git' + '@' + Var('dart_utf_tag'), +- + 'src/third_party/dart/third_party/pkg/usage': + Var('dart_git') + '/usage.git' + '@' + Var('dart_usage_tag'), +
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart index 852f8e7..6f6c394a 100644 --- a/tools/testing/dart/compiler_configuration.dart +++ b/tools/testing/dart/compiler_configuration.dart
@@ -109,7 +109,14 @@ CompilerConfiguration._subclass(this._configuration); /// A multiplier used to give tests longer time to run. - int get timeoutMultiplier => 1; + int get timeoutMultiplier { + if (_configuration.configuration.vmOptions + .any((s) => s.contains("optimization-counter-threshold"))) { + return 2; + } else { + return 1; + } + } // TODO(ahe): It shouldn't be necessary to pass [buildDir] to any of these // functions. It is fixed for a given configuration.
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart index db2ceb1..b3ad21d 100644 --- a/tools/testing/dart/test_suite.dart +++ b/tools/testing/dart/test_suite.dart
@@ -14,6 +14,7 @@ */ import 'dart:async'; import 'dart:io'; +import 'dart:math'; import "package:status_file/expectation.dart"; @@ -468,9 +469,10 @@ var args = configuration.standardOptions.toList(); if (configuration.compilerConfiguration.previewDart2) { - final dfePath = new Path("$buildDir/gen/kernel-service.dart.snapshot") - .absolute - .toNativePath(); + final filename = configuration.architecture == Architecture.x64 + ? '$buildDir/gen/kernel-service.dart.snapshot' + : '$buildDir/gen/kernel_service.dill'; + final dfePath = new Path(filename).absolute.toNativePath(); // '--dfe' has to be the first argument for run_vm_test to pick it up. args.insert(0, '--dfe=$dfePath'); } @@ -871,6 +873,11 @@ return commands; } + vmOptions = vmOptions + .map((s) => + s.replaceAll("__RANDOM__", "${Random().nextInt(0x7fffffff)}")) + .toList(); + List<String> runtimeArguments = compilerConfiguration.computeRuntimeArguments( configuration.runtimeConfiguration,
diff --git a/tools/utils.py b/tools/utils.py index a3657f2..d6878bc 100644 --- a/tools/utils.py +++ b/tools/utils.py
@@ -907,7 +907,9 @@ "Existing files which *did not* match the pattern inside the search " "directory are are:\n %s" % (missing_as_string, self._search_dir, '\n '.join(other_files))) - if throw: + # TODO: Figure out why windows coredump generation does not work. + # See http://dartbug.com/36469 + if throw and GuessOS() != 'win32': raise Exception('Missing crash dumps for: %s' % missing_as_string) def _get_file_name(self, file):
diff --git a/utils/gen_kernel/BUILD.gn b/utils/gen_kernel/BUILD.gn new file mode 100644 index 0000000..d69281f --- /dev/null +++ b/utils/gen_kernel/BUILD.gn
@@ -0,0 +1,22 @@ +# Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +# for details. All rights reserved. Use of this source code is governed by a +# BSD-style license that can be found in the LICENSE file. + +import("../application_snapshot.gni") + +application_snapshot("gen_kernel") { + main_dart = "../../pkg/vm/bin/gen_kernel.dart" + deps = [ + "../../runtime/vm:vm_platform", + ] + # NOTE: The output filename must be kept in sync with the output of the + # vm_platform rule. + vm_platform_out = get_label_info("../../runtime/vm:vm_platform", "root_out_dir") + vm_platform = "$vm_platform_out/vm_platform_strong.dill" + training_args = [ + "--platform", + rebase_path(vm_platform), + rebase_path("../../pkg/vm/bin/gen_kernel.dart"), + "-o -", + ] +}