Version 1.14.0-dev.4.0
Merge commit '1ffc230bf0952850497c913fb878df4333290abf' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 087ba19..3172396 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,9 @@
* Added `Uri.data` getter for `data:` URIs, and `UriData` class for the
return type.
* Added `growable` parameter to `List.filled` constructor.
+ * Added microsecond support to `DateTime`: `DateTime.microsecond`,
+ `DateTime.microsecondsSinceEpoch`, and
+ `new DateTime.fromMicrosecondsSinceEpoch`.
* `dart:math`
* `Random` added a `secure` constructor returning a cryptographically secure
@@ -21,6 +24,12 @@
### Tool changes
+* `dartfmt`
+
+ * Better line splitting in a variety of cases.
+
+ * Other optimizations and bug fixes.
+
* Pub
* **Breaking:** Pub now eagerly emits an error when a pubspec's "name" field
diff --git a/DEPS b/DEPS
index 8f64f6c..ed1aa95 100644
--- a/DEPS
+++ b/DEPS
@@ -39,7 +39,7 @@
# Revisions of /third_party/* dependencies.
"7zip_rev" : "@19997",
"args_tag": "@0.13.0",
- "async_tag": "@1.2.0",
+ "async_tag": "@1.4.0",
"barback_tag" : "@0.15.2+7",
"boringssl_rev" : "@daeafc22c66ad48f6b32fc8d3362eb9ba31b774e",
"charcode_tag": "@1.1.0",
@@ -47,12 +47,13 @@
"clang_rev" : "@28450",
"cli_util_tag" : "@0.0.1+2",
"collection_rev": "@f6135e6350c63eb3f4dd12953b8d4363faff16fc",
+ "convert_tag": "@1.0.0",
"crypto_rev" : "@2df57a1e26dd88e8d0614207d4b062c73209917d",
"csslib_tag" : "@0.12.0",
"dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",
- "dartdoc_tag" : "@v0.8.3",
+ "dartdoc_tag" : "@v0.8.4",
"dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
- "dart_style_tag": "@0.2.0",
+ "dart_style_tag": "@0.2.2",
"dev_compiler_rev": "@0.1.9",
"fake_async_rev" : "@38614",
"firefox_jsshell_rev" : "@45554",
@@ -60,14 +61,14 @@
"gsutil_rev" : "@33376",
"html_tag" : "@0.12.1+1",
"http_rev" : "@9b93e1542c753090c50b46ef1592d44bc858bfe7",
- "http_multi_server_tag" : "@1.3.2",
- "http_parser_rev" : "@8b179e36aba985208e4c5fb15cfddd386b6370a4",
+ "http_multi_server_tag" : "@2.0.0",
+ "http_parser_tag" : "@1.1.0",
"http_throttle_rev" : "@a81f08be942cdd608883c7b67795c12226abc235",
"idl_parser_rev": "@6316d5982dc24b34d09dd8b10fbeaaff28d83a48",
- "intl_rev": "@32047558bd220a53c1f4d93a26d54b83533b1475",
+ "intl_rev": "@a8b480b9c436f6c0ec16730804c914bdb4e30d53",
"jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "@1.1.1",
- "linter_rev": "@e5281475126efdc556c3eba6a8b6683fd814b033",
+ "linter_rev": "@5a599fd32d3b6ef00ffa7c330d1f32bbad287228",
"logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
"markdown_rev": "@4aaadf3d940bb172e1f6285af4d2b1710d309982",
"matcher_tag": "@0.12.0",
@@ -82,13 +83,13 @@
"petitparser_rev" : "@37878",
"ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",
"plugin_tag": "@0.1.0",
- "pool_rev": "@e454b4b54d2987e8d2f0fbd3ac519641ada9bd0f",
- "pub_rev": "@8c091bf6332e8b392fdac63ae297426fb65ed925",
+ "pool_tag": "@1.2.1",
+ "pub_rev": "@3000544b752bbc89e5e01559eed7f70e9401632b",
"pub_cache_tag": "@v0.1.0",
"pub_semver_tag": "@1.2.1",
"quiver_tag": "@0.21.4",
"root_certificates_rev": "@c3a41df63afacec62fcb8135196177e35fe72f71",
- "scheduled_test_tag": "@0.12.1+2",
+ "scheduled_test_tag": "@0.12.4+2",
"shelf_tag": "@0.6.2+1",
"smoke_rev" : "@f3361191cc2a85ebc1e4d4c33aec672d7915aba9",
"source_maps_tag": "@0.10.1",
@@ -99,7 +100,7 @@
"stack_trace_tag": "@1.4.2",
"string_scanner_tag": "@0.1.4",
"sunflower_rev": "@879b704933413414679396b129f5dfa96f7a0b1e",
- "test_tag": "@0.12.3+8",
+ "test_tag": "@0.12.6+1",
"test_reflective_loader_tag": "@0.0.3",
"utf_rev": "@1f55027068759e2d52f2c12de6a57cce5f3c5ee6",
"unittest_tag": "@0.11.6",
@@ -183,6 +184,8 @@
(Var("github_mirror") % "cli_util") + Var("cli_util_tag"),
Var("dart_root") + "/third_party/pkg/collection":
(Var("github_mirror") % "collection") + Var("collection_rev"),
+ Var("dart_root") + "/third_party/pkg/convert":
+ "https://github.com/dart-lang/convert.git" + Var("convert_tag"),
Var("dart_root") + "/third_party/pkg/crypto":
(Var("github_mirror") % "crypto") + Var("crypto_rev"),
Var("dart_root") + "/third_party/pkg/csslib":
@@ -205,7 +208,7 @@
(Var("github_mirror") % "http_multi_server") +
Var("http_multi_server_tag"),
Var("dart_root") + "/third_party/pkg/http_parser":
- (Var("github_mirror") % "http_parser") + Var("http_parser_rev"),
+ (Var("github_mirror") % "http_parser") + Var("http_parser_tag"),
Var("dart_root") + "/third_party/pkg/http_throttle":
(Var("github_mirror") % "http_throttle") +
Var("http_throttle_rev"),
@@ -244,7 +247,7 @@
Var("dart_root") + "/third_party/pkg/plugin":
(Var("github_mirror") % "plugin") + Var("plugin_tag"),
Var("dart_root") + "/third_party/pkg/pool":
- (Var("github_mirror") % "pool") + Var("pool_rev"),
+ (Var("github_mirror") % "pool") + Var("pool_tag"),
Var("dart_root") + "/third_party/pkg/pub_semver":
(Var("github_mirror") % "pub_semver") + Var("pub_semver_tag"),
Var("dart_root") + "/third_party/pkg/pub":
diff --git a/pkg/analysis_server/benchmark/integration/README.md b/pkg/analysis_server/benchmark/integration/README.md
index 78431f9..9955c11 100644
--- a/pkg/analysis_server/benchmark/integration/README.md
+++ b/pkg/analysis_server/benchmark/integration/README.md
@@ -20,9 +20,7 @@
* **inputFile** = the instrumentation or log file
Additional arguments are passed directly to main.dart.
-For example, you may want to specify --newTaskModel to measure performance
-with the new task model versus the old task model,
-or if the log was recorded on one machine and is played back on another,
+For example, if the log was recorded on one machine and is played back on another,
then you might need to specify -m<oldSrcPath>,<newSrcPath>
to map the source paths for playback.
When specifying additional arguments, any occurrences of @tmpSrcDir@
@@ -49,7 +47,6 @@
* **-t, --tmpSrcDir <dirPath>**
The temporary directory containing source used during performance measurement.
WARNING: The contents of the target directory will be modified
-* **--newTaskModel** enable the use of the new task model
* **-d, --diagnosticPort** localhost port on which server
will provide diagnostic web pages
* **-v, --verbose** Verbose logging
diff --git a/pkg/analysis_server/benchmark/integration/driver.dart b/pkg/analysis_server/benchmark/integration/driver.dart
index 80aec4c1..aac45a2 100644
--- a/pkg/analysis_server/benchmark/integration/driver.dart
+++ b/pkg/analysis_server/benchmark/integration/driver.dart
@@ -45,8 +45,6 @@
final Logger logger = new Logger('Driver');
- final bool newTaskModel;
-
/**
* The diagnostic port for Analysis Server or `null` if none.
*/
@@ -70,7 +68,7 @@
*/
Completer<Results> _runCompleter = new Completer<Results>();
- Driver({this.newTaskModel, this.diagnosticPort});
+ Driver({this.diagnosticPort});
/**
* Return a [Future] that completes with the [Results] of running
@@ -114,9 +112,7 @@
});
running = true;
return server
- .start(
- diagnosticPort: diagnosticPort,
- newTaskModel: newTaskModel /*profileServer: true*/)
+ .start(diagnosticPort: diagnosticPort /*profileServer: true*/)
.then((params) {
server.listenToOutput(dispatchNotification);
server.exitCode.then((_) {
diff --git a/pkg/analysis_server/benchmark/integration/main.dart b/pkg/analysis_server/benchmark/integration/main.dart
index 100ab6f..e0fbc80 100644
--- a/pkg/analysis_server/benchmark/integration/main.dart
+++ b/pkg/analysis_server/benchmark/integration/main.dart
@@ -26,8 +26,7 @@
});
PerfArgs args = parseArgs(rawArgs);
- Driver driver = new Driver(
- diagnosticPort: args.diagnosticPort, newTaskModel: args.newTaskModel);
+ Driver driver = new Driver(diagnosticPort: args.diagnosticPort);
Stream<Operation> stream = openInput(args);
StreamSubscription<Operation> subscription;
subscription = stream.listen((Operation op) {
@@ -57,7 +56,6 @@
const HELP_CMDLINE_OPTION = 'help';
const INPUT_CMDLINE_OPTION = 'input';
const MAP_OPTION = 'map';
-const NEW_TASK_MODEL_OPTION = 'newTaskModel';
/**
* The amount of time to give the server to respond to a shutdown request
@@ -94,10 +92,6 @@
help: '<dirPath>\n'
'The temporary directory containing source used during performance measurement.\n'
'WARNING: The contents of the target directory will be modified');
- _argParser.addFlag(NEW_TASK_MODEL_OPTION,
- help: "enable the use of the new task model",
- defaultsTo: false,
- negatable: false);
_argParser.addOption(DIAGNOSTIC_PORT_OPTION,
abbr: 'd',
help: 'localhost port on which server will provide diagnostic web pages');
@@ -181,8 +175,6 @@
showHelp = true;
}
- perfArgs.newTaskModel = args[NEW_TASK_MODEL_OPTION];
-
String portText = args[DIAGNOSTIC_PORT_OPTION];
if (portText != null) {
perfArgs.diagnosticPort = int.parse(portText, onError: (s) {
@@ -253,9 +245,4 @@
* The diagnostic port for Analysis Server or `null` if none.
*/
int diagnosticPort;
-
- /**
- * `true` if the server should run using the new task model.
- */
- bool newTaskModel;
}
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 68947be..b20b660 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -61,7 +61,7 @@
</style></head>
<body>
<h1>Analysis Server API Specification</h1>
- <h1 style="color:#999999">Version 1.13.0</h1>
+ <h1 style="color:#999999">Version 1.14.0</h1>
<p>
This document contains a specification of the API provided by the
analysis server. The API in this document is currently under
@@ -2304,7 +2304,27 @@
field is omitted if the file is not an HTML file.
</p>
</dd></dl></dd></dl>
-
+ <h2 class="domain"><a name="domain_diagnostic">Domain: diagnostic</a></h2>
+ <p>
+ The diagnostic domain contains server diagnostics APIs.
+ </p>
+
+ <h3>Requests</h3><dl><dt class="request"><a name="request_diagnostic.getDiagnostics">diagnostic.getDiagnostics</a> (<a href="#request_diagnostic.getDiagnostics">#</a>)</dt><dd><div class="box"><pre>request: {
+ "id": String
+ "method": "diagnostic.getDiagnostics"
+}</pre><br><pre>response: {
+ "id": String
+ "error": <span style="color:#999999">optional</span> <a href="#type_RequestError">RequestError</a>
+ "result": {
+ "<b>contexts</b>": List<<a href="#type_ContextData">ContextData</a>>
+ }
+}</pre></div>
+ <p>Return server diagnostics.</p>
+
+ <h4>Returns</h4><dl><dt class="field"><b><i>contexts ( List<<a href="#type_ContextData">ContextData</a>> )</i></b></dt><dd>
+
+ <p>The list of analysis contexts.</p>
+ </dd></dl></dd></dl>
<h2 class="domain"><a name="types">Types</a></h2>
<p>
@@ -2755,7 +2775,37 @@
For suggestions of this kind, the completion is
the named argument identifier including a trailing ':' and space.
</p>
- </dd><dt class="value">OPTIONAL_ARGUMENT</dt><dt class="value">PARAMETER</dt></dl></dd><dt class="typeDefinition"><a name="type_Element">Element: object</a></dt><dd>
+ </dd><dt class="value">OPTIONAL_ARGUMENT</dt><dt class="value">PARAMETER</dt></dl></dd><dt class="typeDefinition"><a name="type_ContextData">ContextData: object</a></dt><dd>
+ <p>
+ Information about an analysis context.
+ </p>
+
+ <dl><dt class="field"><b><i>name ( String )</i></b></dt><dd>
+
+ <p>
+ The name of the context.
+ </p>
+ </dd><dt class="field"><b><i>explicitFileCount ( int )</i></b></dt><dd>
+
+ <p>
+ Explicitly analyzed files.
+ </p>
+ </dd><dt class="field"><b><i>implicitFileCount ( int )</i></b></dt><dd>
+
+ <p>
+ Implicitly analyzed files.
+ </p>
+ </dd><dt class="field"><b><i>workItemQueueLength ( int )</i></b></dt><dd>
+
+ <p>
+ The number of work items in the queue.
+ </p>
+ </dd><dt class="field"><b><i>cacheEntryExceptions ( List<String> )</i></b></dt><dd>
+
+ <p>
+ Exceptions associated with cache entries.
+ </p>
+ </dd></dl></dd><dt class="typeDefinition"><a name="type_Element">Element: object</a></dt><dd>
<p>
Information about an element (something that can be declared
in code).
@@ -2858,7 +2908,12 @@
<dl><dt class="value">LIBRARY</dt><dt class="value">PART</dt></dl></dd><dt class="typeDefinition"><a name="type_FilePath">FilePath: String</a></dt><dd>
<p>
- The absolute path of a file.
+ The absolute, normalized path of a file.
+ </p>
+ <p>
+ If the format of a file path in a request is not valid, e.g. the
+ path is not absolute or is not normalized, then an error of type
+ <tt>INVALID_FILE_PATH_FORMAT</tt> will be generated.
</p>
</dd><dt class="typeDefinition"><a name="type_FoldingKind">FoldingKind: String</a></dt><dd>
<p>
@@ -3636,6 +3691,12 @@
The context root used to create an execution context does not
exist.
</p>
+ </dd><dt class="value">INVALID_FILE_PATH_FORMAT</dt><dd>
+
+ <p>
+ The format of the given file path is invalid, e.g. is not
+ absolute and normalized.
+ </p>
</dd><dt class="value">INVALID_OVERLAY_CHANGE</dt><dd>
<p>
@@ -4301,7 +4362,7 @@
TBD
</p>
<h2 class="domain"><a name="index">Index</a></h2>
- <h3>Domains</h3><h4>server (<a href="#domain_server">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_server.getVersion">getVersion</a></li><li><a href="#request_server.shutdown">shutdown</a></li><li><a href="#request_server.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_server.connected">connected</a></li><li><a href="#notification_server.error">error</a></li><li><a href="#notification_server.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getErrors">getErrors</a></li><li><a href="#request_analysis.getHover">getHover</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</a></li><li><a href="#request_analysis.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.reanalyze">reanalyze</a></li><li><a href="#request_analysis.setAnalysisRoots">setAnalysisRoots</a></li><li><a href="#request_analysis.setGeneralSubscriptions">setGeneralSubscriptions</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li><li><a href="#request_analysis.updateOptions">updateOptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.analyzedFiles">analyzedFiles</a></li><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.flushResults">flushResults</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.implemented">implemented</a></li><li><a href="#notification_analysis.invalidate">invalidate</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li><li><a href="#notification_analysis.overrides">overrides</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_completion.results">results</a></li></ul></div></div><h4>search (<a href="#domain_search">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_search.findElementReferences">findElementReferences</a></li><li><a href="#request_search.findMemberDeclarations">findMemberDeclarations</a></li><li><a href="#request_search.findMemberReferences">findMemberReferences</a></li><li><a href="#request_search.findTopLevelDeclarations">findTopLevelDeclarations</a></li><li><a href="#request_search.getTypeHierarchy">getTypeHierarchy</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_search.results">results</a></li></ul></div></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.format">format</a></li><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getAvailableRefactorings">getAvailableRefactorings</a></li><li><a href="#request_edit.getFixes">getFixes</a></li><li><a href="#request_edit.getRefactoring">getRefactoring</a></li><li><a href="#request_edit.sortMembers">sortMembers</a></li><li><a href="#request_edit.organizeDirectives">organizeDirectives</a></li></ul></div><h4>execution (<a href="#domain_execution">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_execution.createContext">createContext</a></li><li><a href="#request_execution.deleteContext">deleteContext</a></li><li><a href="#request_execution.mapUri">mapUri</a></li><li><a href="#request_execution.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_execution.launchData">launchData</a></li></ul></div></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisOptions">AnalysisOptions</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_CompletionId">CompletionId</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_ExecutableFile">ExecutableFile</a></li><li><a href="#type_ExecutableKind">ExecutableKind</a></li><li><a href="#type_ExecutionContextId">ExecutionContextId</a></li><li><a href="#type_ExecutionService">ExecutionService</a></li><li><a href="#type_FileKind">FileKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_GeneralAnalysisService">GeneralAnalysisService</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_HoverInformation">HoverInformation</a></li><li><a href="#type_ImplementedClass">ImplementedClass</a></li><li><a href="#type_ImplementedMember">ImplementedMember</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_SearchId">SearchId</a></li><li><a href="#type_SearchResult">SearchResult</a></li><li><a href="#type_SearchResultKind">SearchResultKind</a></li><li><a href="#type_ServerService">ServerService</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_TypeHierarchyItem">TypeHierarchyItem</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
+ <h3>Domains</h3><h4>server (<a href="#domain_server">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_server.getVersion">getVersion</a></li><li><a href="#request_server.shutdown">shutdown</a></li><li><a href="#request_server.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_server.connected">connected</a></li><li><a href="#notification_server.error">error</a></li><li><a href="#notification_server.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getErrors">getErrors</a></li><li><a href="#request_analysis.getHover">getHover</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</a></li><li><a href="#request_analysis.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.reanalyze">reanalyze</a></li><li><a href="#request_analysis.setAnalysisRoots">setAnalysisRoots</a></li><li><a href="#request_analysis.setGeneralSubscriptions">setGeneralSubscriptions</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li><li><a href="#request_analysis.updateOptions">updateOptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.analyzedFiles">analyzedFiles</a></li><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.flushResults">flushResults</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.implemented">implemented</a></li><li><a href="#notification_analysis.invalidate">invalidate</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li><li><a href="#notification_analysis.overrides">overrides</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_completion.results">results</a></li></ul></div></div><h4>search (<a href="#domain_search">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_search.findElementReferences">findElementReferences</a></li><li><a href="#request_search.findMemberDeclarations">findMemberDeclarations</a></li><li><a href="#request_search.findMemberReferences">findMemberReferences</a></li><li><a href="#request_search.findTopLevelDeclarations">findTopLevelDeclarations</a></li><li><a href="#request_search.getTypeHierarchy">getTypeHierarchy</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_search.results">results</a></li></ul></div></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.format">format</a></li><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getAvailableRefactorings">getAvailableRefactorings</a></li><li><a href="#request_edit.getFixes">getFixes</a></li><li><a href="#request_edit.getRefactoring">getRefactoring</a></li><li><a href="#request_edit.sortMembers">sortMembers</a></li><li><a href="#request_edit.organizeDirectives">organizeDirectives</a></li></ul></div><h4>execution (<a href="#domain_execution">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_execution.createContext">createContext</a></li><li><a href="#request_execution.deleteContext">deleteContext</a></li><li><a href="#request_execution.mapUri">mapUri</a></li><li><a href="#request_execution.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_execution.launchData">launchData</a></li></ul></div></div><h4>diagnostic (<a href="#domain_diagnostic">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_diagnostic.getDiagnostics">getDiagnostics</a></li></ul></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisOptions">AnalysisOptions</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_CompletionId">CompletionId</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_ContextData">ContextData</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_ExecutableFile">ExecutableFile</a></li><li><a href="#type_ExecutableKind">ExecutableKind</a></li><li><a href="#type_ExecutionContextId">ExecutionContextId</a></li><li><a href="#type_ExecutionService">ExecutionService</a></li><li><a href="#type_FileKind">FileKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_GeneralAnalysisService">GeneralAnalysisService</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_HoverInformation">HoverInformation</a></li><li><a href="#type_ImplementedClass">ImplementedClass</a></li><li><a href="#type_ImplementedMember">ImplementedMember</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_SearchId">SearchId</a></li><li><a href="#type_SearchResult">SearchResult</a></li><li><a href="#type_SearchResultKind">SearchResultKind</a></li><li><a href="#type_ServerService">ServerService</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_TypeHierarchyItem">TypeHierarchyItem</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
</body></html>
\ No newline at end of file
diff --git a/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart b/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
index 81ad8dc..e931ba3 100644
--- a/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
@@ -9447,7 +9447,6 @@
* "explicitFileCount": int
* "implicitFileCount": int
* "workItemQueueLength": int
- * "workItemQueueLengthAverage": String
* "cacheEntryExceptions": List<String>
* }
*
@@ -9462,8 +9461,6 @@
int _workItemQueueLength;
- String _workItemQueueLengthAverage;
-
List<String> _cacheEntryExceptions;
/**
@@ -9519,21 +9516,6 @@
}
/**
- * A rolling average of work items in the queue. (A double encoded as a
- * String.)
- */
- String get workItemQueueLengthAverage => _workItemQueueLengthAverage;
-
- /**
- * A rolling average of work items in the queue. (A double encoded as a
- * String.)
- */
- void set workItemQueueLengthAverage(String value) {
- assert(value != null);
- this._workItemQueueLengthAverage = value;
- }
-
- /**
* Exceptions associated with cache entries.
*/
List<String> get cacheEntryExceptions => _cacheEntryExceptions;
@@ -9546,12 +9528,11 @@
this._cacheEntryExceptions = value;
}
- ContextData(String name, int explicitFileCount, int implicitFileCount, int workItemQueueLength, String workItemQueueLengthAverage, List<String> cacheEntryExceptions) {
+ ContextData(String name, int explicitFileCount, int implicitFileCount, int workItemQueueLength, List<String> cacheEntryExceptions) {
this.name = name;
this.explicitFileCount = explicitFileCount;
this.implicitFileCount = implicitFileCount;
this.workItemQueueLength = workItemQueueLength;
- this.workItemQueueLengthAverage = workItemQueueLengthAverage;
this.cacheEntryExceptions = cacheEntryExceptions;
}
@@ -9584,19 +9565,13 @@
} else {
throw jsonDecoder.missingKey(jsonPath, "workItemQueueLength");
}
- String workItemQueueLengthAverage;
- if (json.containsKey("workItemQueueLengthAverage")) {
- workItemQueueLengthAverage = jsonDecoder.decodeString(jsonPath + ".workItemQueueLengthAverage", json["workItemQueueLengthAverage"]);
- } else {
- throw jsonDecoder.missingKey(jsonPath, "workItemQueueLengthAverage");
- }
List<String> cacheEntryExceptions;
if (json.containsKey("cacheEntryExceptions")) {
cacheEntryExceptions = jsonDecoder.decodeList(jsonPath + ".cacheEntryExceptions", json["cacheEntryExceptions"], jsonDecoder.decodeString);
} else {
throw jsonDecoder.missingKey(jsonPath, "cacheEntryExceptions");
}
- return new ContextData(name, explicitFileCount, implicitFileCount, workItemQueueLength, workItemQueueLengthAverage, cacheEntryExceptions);
+ return new ContextData(name, explicitFileCount, implicitFileCount, workItemQueueLength, cacheEntryExceptions);
} else {
throw jsonDecoder.mismatch(jsonPath, "ContextData", json);
}
@@ -9608,7 +9583,6 @@
result["explicitFileCount"] = explicitFileCount;
result["implicitFileCount"] = implicitFileCount;
result["workItemQueueLength"] = workItemQueueLength;
- result["workItemQueueLengthAverage"] = workItemQueueLengthAverage;
result["cacheEntryExceptions"] = cacheEntryExceptions;
return result;
}
@@ -9623,7 +9597,6 @@
explicitFileCount == other.explicitFileCount &&
implicitFileCount == other.implicitFileCount &&
workItemQueueLength == other.workItemQueueLength &&
- workItemQueueLengthAverage == other.workItemQueueLengthAverage &&
listEqual(cacheEntryExceptions, other.cacheEntryExceptions, (String a, String b) => a == b);
}
return false;
@@ -9636,7 +9609,6 @@
hash = JenkinsSmiHash.combine(hash, explicitFileCount.hashCode);
hash = JenkinsSmiHash.combine(hash, implicitFileCount.hashCode);
hash = JenkinsSmiHash.combine(hash, workItemQueueLength.hashCode);
- hash = JenkinsSmiHash.combine(hash, workItemQueueLengthAverage.hashCode);
hash = JenkinsSmiHash.combine(hash, cacheEntryExceptions.hashCode);
return JenkinsSmiHash.finish(hash);
}
@@ -14093,6 +14065,7 @@
* GET_REACHABLE_SOURCES_INVALID_FILE
* INVALID_ANALYSIS_ROOT
* INVALID_EXECUTION_CONTEXT
+ * INVALID_FILE_PATH_FORMAT
* INVALID_OVERLAY_CHANGE
* INVALID_PARAMETER
* INVALID_REQUEST
@@ -14166,6 +14139,12 @@
static const INVALID_EXECUTION_CONTEXT = const RequestErrorCode._("INVALID_EXECUTION_CONTEXT");
/**
+ * The format of the given file path is invalid, e.g. is not absolute and
+ * normalized.
+ */
+ static const INVALID_FILE_PATH_FORMAT = const RequestErrorCode._("INVALID_FILE_PATH_FORMAT");
+
+ /**
* An "analysis.updateContent" request contained a ChangeContentOverlay
* object which can't be applied, due to an edit having an offset or length
* that is out of range.
@@ -14260,7 +14239,7 @@
/**
* A list containing all of the enum values that are defined.
*/
- static const List<RequestErrorCode> VALUES = const <RequestErrorCode>[CONTENT_MODIFIED, FILE_NOT_ANALYZED, FORMAT_INVALID_FILE, FORMAT_WITH_ERRORS, GET_ERRORS_INVALID_FILE, GET_NAVIGATION_INVALID_FILE, GET_REACHABLE_SOURCES_INVALID_FILE, INVALID_ANALYSIS_ROOT, INVALID_EXECUTION_CONTEXT, INVALID_OVERLAY_CHANGE, INVALID_PARAMETER, INVALID_REQUEST, NO_INDEX_GENERATED, ORGANIZE_DIRECTIVES_ERROR, REFACTORING_REQUEST_CANCELLED, SERVER_ALREADY_STARTED, SERVER_ERROR, SORT_MEMBERS_INVALID_FILE, SORT_MEMBERS_PARSE_ERRORS, UNANALYZED_PRIORITY_FILES, UNKNOWN_REQUEST, UNKNOWN_SOURCE, UNSUPPORTED_FEATURE];
+ static const List<RequestErrorCode> VALUES = const <RequestErrorCode>[CONTENT_MODIFIED, FILE_NOT_ANALYZED, FORMAT_INVALID_FILE, FORMAT_WITH_ERRORS, GET_ERRORS_INVALID_FILE, GET_NAVIGATION_INVALID_FILE, GET_REACHABLE_SOURCES_INVALID_FILE, INVALID_ANALYSIS_ROOT, INVALID_EXECUTION_CONTEXT, INVALID_FILE_PATH_FORMAT, INVALID_OVERLAY_CHANGE, INVALID_PARAMETER, INVALID_REQUEST, NO_INDEX_GENERATED, ORGANIZE_DIRECTIVES_ERROR, REFACTORING_REQUEST_CANCELLED, SERVER_ALREADY_STARTED, SERVER_ERROR, SORT_MEMBERS_INVALID_FILE, SORT_MEMBERS_PARSE_ERRORS, UNANALYZED_PRIORITY_FILES, UNKNOWN_REQUEST, UNKNOWN_SOURCE, UNSUPPORTED_FEATURE];
final String name;
@@ -14286,6 +14265,8 @@
return INVALID_ANALYSIS_ROOT;
case "INVALID_EXECUTION_CONTEXT":
return INVALID_EXECUTION_CONTEXT;
+ case "INVALID_FILE_PATH_FORMAT":
+ return INVALID_FILE_PATH_FORMAT;
case "INVALID_OVERLAY_CHANGE":
return INVALID_OVERLAY_CHANGE;
case "INVALID_PARAMETER":
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol.dart b/pkg/analysis_server/lib/plugin/protocol/protocol.dart
index 5617efc..9daa9f0 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol.dart
@@ -441,6 +441,15 @@
"Invalid execution context: $contextId"));
/**
+ * Initialize a newly created instance to represent the
+ * INVALID_FILE_PATH_FORMAT error condition.
+ */
+ Response.invalidFilePathFormat(Request request, path)
+ : this(request.id,
+ error: new RequestError(RequestErrorCode.INVALID_FILE_PATH_FORMAT,
+ 'Invalid file path format: $path'));
+
+ /**
* Initialize a newly created instance to represent an error condition caused
* by a [request] that had invalid parameter. [path] is the path to the
* invalid parameter, in Javascript notation (e.g. "foo.bar" means that the
diff --git a/pkg/analysis_server/lib/src/analysis_logger.dart b/pkg/analysis_server/lib/src/analysis_logger.dart
index bc2276e..8b9c9b6 100644
--- a/pkg/analysis_server/lib/src/analysis_logger.dart
+++ b/pkg/analysis_server/lib/src/analysis_logger.dart
@@ -47,11 +47,6 @@
}
@override
- void logError2(String message, Object exception) {
- baseLogger.severe(message, exception);
- }
-
- @override
void logInformation(String message, [CaughtException exception]) {
if (exception == null) {
baseLogger.info(message);
@@ -59,9 +54,4 @@
baseLogger.info(message, exception.exception, exception.stackTrace);
}
}
-
- @override
- void logInformation2(String message, Object exception) {
- baseLogger.info(message, exception);
- }
}
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 6a5ace1..f72f051 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -72,7 +72,7 @@
* The version of the analysis server. The value should be replaced
* automatically during the build.
*/
- static final String VERSION = '1.12.0';
+ static final String VERSION = '1.14.0';
/**
* The number of milliseconds to perform operations before inserting
@@ -185,8 +185,8 @@
* A table mapping [AnalysisContext]s to the completers that should be
* completed when analysis of this context is finished.
*/
- Map<AnalysisContext,
- Completer<AnalysisDoneReason>> contextAnalysisDoneCompleters =
+ Map<AnalysisContext, Completer<AnalysisDoneReason>>
+ contextAnalysisDoneCompleters =
new HashMap<AnalysisContext, Completer<AnalysisDoneReason>>();
/**
@@ -732,6 +732,15 @@
}
/**
+ * Return `true` if the given path is a valid `FilePath`.
+ *
+ * This means that it is absolute and normalized.
+ */
+ bool isValidFilePath(String path) {
+ return resourceProvider.absolutePathContext.isValid(path);
+ }
+
+ /**
* Returns a [Future] completing when [file] has been completely analyzed, in
* particular, all its errors have been computed. The future is completed
* with an [AnalysisDoneReason] indicating what caused the file's analysis to
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 061cc23..15e3c80 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -539,7 +539,7 @@
*/
void processOptionsForContext(ContextInfo info, Folder folder,
{bool optionsRemoved: false}) {
- Map<String, YamlNode> options;
+ Map<String, Object> options;
try {
options = analysisOptionsProvider.getOptions(folder);
} catch (_) {
@@ -550,6 +550,24 @@
return;
}
+ // In case options files are removed, revert to defaults.
+ if (optionsRemoved) {
+ // Start with defaults.
+ info.context.analysisOptions = new AnalysisOptionsImpl();
+
+ // Apply inherited options.
+ options = _getEmbeddedOptions(info.context);
+ if (options != null) {
+ configureContextOptions(info.context, options);
+ }
+ } else {
+ // Check for embedded options.
+ YamlMap embeddedOptions = _getEmbeddedOptions(info.context);
+ if (embeddedOptions != null) {
+ options = new Merger().merge(embeddedOptions, options);
+ }
+ }
+
// Notify options processors.
AnalysisEngine.instance.optionsPlugin.optionsProcessors
.forEach((OptionsProcessor p) {
@@ -562,34 +580,19 @@
}
});
- // In case options files are removed, revert to defaults.
- if (optionsRemoved) {
- // Start with defaults.
- info.context.analysisOptions = new AnalysisOptionsImpl();
+ configureContextOptions(info.context, options);
- // Apply inherited options.
- YamlMap embeddedOptions = _getEmbeddedOptions(info.context);
- if (embeddedOptions != null) {
- configureContextOptions(info.context, embeddedOptions);
- }
+ // Nothing more to do.
+ if (options == null) {
return;
}
- // Check for embedded options.
- YamlMap embeddedOptions = _getEmbeddedOptions(info.context);
- if (embeddedOptions != null) {
- options = new Merger().merge(embeddedOptions, options);
- }
-
- // Analysis options are processed 'in-line'.
var analyzer = options[AnalyzerOptions.analyzer];
if (analyzer is! Map) {
- // No options for analyzer.
+ // Done.
return;
}
- configureContextOptions(info.context, options);
-
// Set ignore patterns.
YamlList exclude = analyzer[AnalyzerOptions.exclude];
if (exclude != null) {
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index f1bdf14..19cf98e 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -65,7 +65,8 @@
if (errorInfo == null) {
server.sendResponse(new Response.getErrorsInvalidFile(request));
} else {
- errors = doAnalysisError_listFromEngine(
+ engine.AnalysisContext context = server.getAnalysisContext(file);
+ errors = doAnalysisError_listFromEngine(context,
errorInfo.lineInfo, errorInfo.errors);
server.sendResponse(
new AnalysisGetErrorsResult(errors).toResponse(request.id));
@@ -175,8 +176,9 @@
if (pair.context == null || pair.source == null) {
return new Response.getReachableSourcesInvalidFile(request);
}
- Map<String, List<String>> sources = new ReachableSourceCollector(
- pair.source, pair.context).collectSources();
+ Map<String, List<String>> sources =
+ new ReachableSourceCollector(pair.source, pair.context)
+ .collectSources();
return new AnalysisGetReachableSourcesResult(sources)
.toResponse(request.id);
}
@@ -245,9 +247,22 @@
*/
Response setAnalysisRoots(Request request) {
var params = new AnalysisSetAnalysisRootsParams.fromRequest(request);
+ List<String> includedPathList = params.included;
+ List<String> excludedPathList = params.excluded;
+ // validate
+ for (String path in includedPathList) {
+ if (!server.isValidFilePath(path)) {
+ return new Response.invalidFilePathFormat(request, path);
+ }
+ }
+ for (String path in excludedPathList) {
+ if (!server.isValidFilePath(path)) {
+ return new Response.invalidFilePathFormat(request, path);
+ }
+ }
// continue in server
- server.setAnalysisRoots(request.id, params.included, params.excluded,
- params.packageRoots == null ? {} : params.packageRoots);
+ server.setAnalysisRoots(request.id, includedPathList, excludedPathList,
+ params.packageRoots ?? <String, String>{});
return new AnalysisSetAnalysisRootsResult().toResponse(request.id);
}
@@ -347,8 +362,8 @@
class AnalysisDomainImpl implements AnalysisDomain {
final AnalysisServer server;
- final Map<ResultDescriptor,
- StreamController<engine.ComputedResult>> controllers =
+ final Map<ResultDescriptor, StreamController<engine.ComputedResult>>
+ controllers =
<ResultDescriptor, StreamController<engine.ComputedResult>>{};
AnalysisDomainImpl(this.server) {
diff --git a/pkg/analysis_server/lib/src/domain_diagnostic.dart b/pkg/analysis_server/lib/src/domain_diagnostic.dart
index 5d30d92..e9bd0c3 100644
--- a/pkg/analysis_server/lib/src/domain_diagnostic.dart
+++ b/pkg/analysis_server/lib/src/domain_diagnostic.dart
@@ -2,20 +2,17 @@
// for 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 src.domain_diagnostic;
+library analysis_server.src.domain_diagnostic;
-import 'dart:async';
import 'dart:collection';
import 'dart:core' hide Resource;
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/utilities/average.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/context/context.dart';
-import 'package:analyzer/src/generated/engine.dart'
- hide AnalysisCache, AnalysisContextImpl;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
import 'package:analyzer/src/task/driver.dart';
@@ -36,20 +33,12 @@
/// The analysis server that is using this handler to process requests.
final AnalysisServer server;
- /// The sampler tracking rolling work queue length averages.
- Sampler sampler;
-
/// Initialize a newly created handler to handle requests for the given
/// [server].
DiagnosticDomainHandler(this.server);
/// Answer the `diagnostic.diagnostics` request.
Response computeDiagnostics(Request request) {
- // Initialize sampler if needed.
- if (sampler == null) {
- sampler = new Sampler(server);
- }
-
List<ContextData> infos = <ContextData>[];
server.folderMap.forEach((Folder folder, AnalysisContext context) {
infos.add(extractData(folder, context));
@@ -63,11 +52,9 @@
int explicitFiles = 0;
int implicitFiles = 0;
int workItems = 0;
- String workItemAverage = '-1';
Set<String> exceptions = new HashSet<String>();
if (context is AnalysisContextImpl) {
workItems = _workItemCount(context);
- workItemAverage = sampler.getAverage(folder)?.toString() ?? '-1';
var cache = context.analysisCache;
if (cache is AnalysisCache) {
Set<AnalysisTarget> countedTargets = new HashSet<AnalysisTarget>();
@@ -92,7 +79,7 @@
}
}
return new ContextData(context.name, explicitFiles, implicitFiles,
- workItems, workItemAverage, exceptions.toList());
+ workItems, exceptions.toList());
}
@override
@@ -108,83 +95,3 @@
return null;
}
}
-
-/// Keeps track of a moving average of work item queue lengths mapped to
-/// contexts.
-///
-/// Sampling terminates after [maxSampleCount], if no one expresses interest
-/// by calling [resetTimerCountdown].
-class Sampler {
- /// Timer interval.
- static const Duration duration = const Duration(seconds: 1);
-
- /// Maximum number of samples taken between calls to [reset].
- static const int maxSampleCount = 30;
-
- /// Current sample count.
- int sampleCount = 0;
-
- /// The shared timer.
- Timer timer;
-
- /// Map of contexts (tracked as folders to avoid leaks) to averages.
- /// TOOD(pq): consider adding GC to remove mappings for deleted folders
- Map<Folder, Average> averages = new HashMap<Folder, Average>();
-
- final AnalysisServer server;
- Sampler(this.server) {
- start();
- _sample();
- }
-
- /// Get the average for the context associated with the given [folder].
- num getAverage(Folder folder) {
- resetTimerCountdown();
- return averages[folder].value;
- }
-
- /// Check if we're currently sampling.
- bool isSampling() => timer?.isActive ?? false;
-
- /// Reset counter.
- void resetTimerCountdown() {
- sampleCount = 0;
- }
-
- /// Start sampling.
- void start() {
- // No need to (re)start if already sampling.
- if (isSampling()) {
- return;
- }
- timer = new Timer.periodic(duration, (Timer timer) {
- _sample();
- if (sampleCount++ >= maxSampleCount) {
- timer.cancel();
- }
- });
- }
-
- /// Stop sampling.
- void stop() {
- timer.cancel();
- }
-
- /// Take a sample.
- void _sample() {
- try {
- server.folderMap.forEach((Folder folder, AnalysisContext context) {
- if (context is AnalysisContextImpl) {
- Average average = averages[folder];
- if (average == null) {
- average = new Average();
- averages[folder] = average;
- }
- average.addSample(_workItemCount(context));
- }
- });
- } on Exception {
- stop();
- }
- }
-}
diff --git a/pkg/analysis_server/lib/src/domain_execution.dart b/pkg/analysis_server/lib/src/domain_execution.dart
index c2f8a5a..3988de2 100644
--- a/pkg/analysis_server/lib/src/domain_execution.dart
+++ b/pkg/analysis_server/lib/src/domain_execution.dart
@@ -161,8 +161,7 @@
String filePath = source.fullName;
// check files
bool isDartFile = notice.resolvedDartUnit != null;
- bool isHtmlFile = notice.resolvedHtmlUnit != null;
- if (!isDartFile && !isHtmlFile) {
+ if (!isDartFile) {
return;
}
// prepare context
@@ -184,10 +183,6 @@
server.sendNotification(
new ExecutionLaunchDataParams(filePath, kind: kind)
.toNotification());
- } else if (isHtmlFile) {
- List<Source> libraries = context.getLibrariesReferencedFromHtml(source);
- server.sendNotification(new ExecutionLaunchDataParams(filePath,
- referencedFiles: _getFullNames(libraries)).toNotification());
}
});
}
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 1865146..93ad959 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -250,15 +250,20 @@
if (!engine.AnalysisEngine.isDartFileName(file)) {
return new Response.sortMembersInvalidFile(request);
}
- // prepare resolved units
- List<CompilationUnit> units = server.getResolvedCompilationUnits(file);
- if (units.isEmpty) {
+ // prepare location
+ ContextSourcePair contextSource = server.getContextSourcePair(file);
+ engine.AnalysisContext context = contextSource.context;
+ Source source = contextSource.source;
+ if (context == null || source == null) {
return new Response.sortMembersInvalidFile(request);
}
- // prepare context
- CompilationUnit unit = units.first;
- engine.AnalysisContext context = unit.element.context;
- Source source = unit.element.source;
+ // prepare parsed unit
+ CompilationUnit unit;
+ try {
+ unit = context.parseCompilationUnit(source);
+ } catch (e) {
+ return new Response.sortMembersInvalidFile(request);
+ }
// check if there are scan/parse errors in the file
engine.AnalysisErrorInfo errors = context.getErrors(source);
int numScanParseErrors = _getNumberOfScanParseErrors(errors.errors);
diff --git a/pkg/analysis_server/lib/src/get_handler.dart b/pkg/analysis_server/lib/src/get_handler.dart
deleted file mode 100644
index fbf70a1..0000000
--- a/pkg/analysis_server/lib/src/get_handler.dart
+++ /dev/null
@@ -1,1655 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analysis_server.src.get_handler;
-
-import 'dart:async';
-import 'dart:collection';
-import 'dart:convert';
-import 'dart:io';
-import 'dart:math';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
-import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/domain_completion.dart';
-import 'package:analysis_server/src/domain_execution.dart';
-import 'package:analysis_server/src/operation/operation.dart';
-import 'package:analysis_server/src/operation/operation_analysis.dart';
-import 'package:analysis_server/src/operation/operation_queue.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_index.dart';
-import 'package:analysis_server/src/services/index/store/split_store.dart';
-import 'package:analysis_server/src/socket_server.dart';
-import 'package:analysis_server/src/status/ast_writer.dart';
-import 'package:analysis_server/src/status/element_writer.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:analyzer/task/model.dart' as newTask;
-import 'package:plugin/plugin.dart';
-
-/**
- * A function that can be used to generate HTML output into the given [buffer].
- * The HTML that is generated must be valid (special characters must already be
- * encoded).
- */
-typedef void HtmlGenerator(StringBuffer buffer);
-
-/**
- * Instances of the class [GetHandler] handle GET requests.
- */
-class GetHandler {
- /**
- * The path used to request overall performance information.
- */
- static const String ANALYSIS_PERFORMANCE_PATH = '/perf/analysis';
-
- /**
- * The path used to request information about a element model.
- */
- static const String AST_PATH = '/ast';
-
- /**
- * The path used to request information about the cache entry corresponding
- * to a single file.
- */
- static const String CACHE_ENTRY_PATH = '/cache_entry';
-
- /**
- * The path used to request the list of source files in a certain cache
- * state.
- */
- static const String CACHE_STATE_PATH = '/cache_state';
-
- /**
- * The path used to request code completion information.
- */
- static const String COMPLETION_PATH = '/completion';
-
- /**
- * The path used to request communication performance information.
- */
- static const String COMMUNICATION_PERFORMANCE_PATH = '/perf/communication';
-
- /**
- * The path used to request information about a specific context.
- */
- static const String CONTEXT_PATH = '/context';
-
- /**
- * The path used to request information about a element model.
- */
- static const String ELEMENT_PATH = '/element';
-
- /**
- * The path used to request information about elements with the given name.
- */
- static const String INDEX_ELEMENT_BY_NAME = '/index/element-by-name';
-
- /**
- * The path used to request an overlay contents.
- */
- static const String OVERLAY_PATH = '/overlay';
-
- /**
- * The path used to request overlays information.
- */
- static const String OVERLAYS_PATH = '/overlays';
-
- /**
- * The path used to request the status of the analysis server as a whole.
- */
- static const String STATUS_PATH = '/status';
-
- /**
- * Query parameter used to represent the context to search for, when
- * accessing [CACHE_ENTRY_PATH] or [CACHE_STATE_PATH].
- */
- static const String CONTEXT_QUERY_PARAM = 'context';
-
- /**
- * Query parameter used to represent the descriptor to search for, when
- * accessing [CACHE_STATE_PATH].
- */
- static const String DESCRIPTOR_QUERY_PARAM = 'descriptor';
-
- /**
- * Query parameter used to represent the name of elements to search for, when
- * accessing [INDEX_ELEMENT_BY_NAME].
- */
- static const String INDEX_ELEMENT_NAME = 'name';
-
- /**
- * Query parameter used to represent the path of an overlayed file.
- */
- static const String PATH_PARAM = 'path';
-
- /**
- * Query parameter used to represent the source to search for, when accessing
- * [CACHE_ENTRY_PATH].
- */
- static const String SOURCE_QUERY_PARAM = 'entry';
-
- /**
- * Query parameter used to represent the cache state to search for, when
- * accessing [CACHE_STATE_PATH].
- */
- static const String STATE_QUERY_PARAM = 'state';
-
- static final ContentType _htmlContent =
- new ContentType("text", "html", charset: "utf-8");
-
- /**
- * The socket server whose status is to be reported on.
- */
- SocketServer _server;
-
- /**
- * Buffer containing strings printed by the analysis server.
- */
- List<String> _printBuffer;
-
- /**
- * Contents of overlay files.
- */
- final Map<String, String> _overlayContents = <String, String>{};
-
- /**
- * Initialize a newly created handler for GET requests.
- */
- GetHandler(this._server, this._printBuffer);
-
- /**
- * Return the active [CompletionDomainHandler]
- * or `null` if either analysis server is not running
- * or there is no completion domain handler.
- */
- CompletionDomainHandler get _completionDomainHandler {
- AnalysisServer analysisServer = _server.analysisServer;
- if (analysisServer == null) {
- return null;
- }
- return analysisServer.handlers
- .firstWhere((h) => h is CompletionDomainHandler, orElse: () => null);
- }
-
- /**
- * Handle a GET request received by the HTTP server.
- */
- void handleGetRequest(HttpRequest request) {
- String path = request.uri.path;
- if (path == STATUS_PATH) {
- _returnServerStatus(request);
- } else if (path == ANALYSIS_PERFORMANCE_PATH) {
- _returnAnalysisPerformance(request);
- } else if (path == AST_PATH) {
- _returnAst(request);
- } else if (path == CACHE_STATE_PATH) {
- _returnCacheState(request);
- } else if (path == CACHE_ENTRY_PATH) {
- _returnCacheEntry(request);
- } else if (path == COMPLETION_PATH) {
- _returnCompletionInfo(request);
- } else if (path == COMMUNICATION_PERFORMANCE_PATH) {
- _returnCommunicationPerformance(request);
- } else if (path == CONTEXT_PATH) {
- _returnContextInfo(request);
- } else if (path == ELEMENT_PATH) {
- _returnElement(request);
- } else if (path == INDEX_ELEMENT_BY_NAME) {
- _returnIndexElementByName(request);
- } else if (path == OVERLAY_PATH) {
- _returnOverlayContents(request);
- } else if (path == OVERLAYS_PATH) {
- _returnOverlaysInfo(request);
- } else {
- _returnUnknownRequest(request);
- }
- }
-
- /**
- * Return the folder being managed by the given [analysisServer] that matches
- * the given [contextFilter], or `null` if there is none.
- */
- Folder _findFolder(AnalysisServer analysisServer, String contextFilter) {
- return analysisServer.folderMap.keys.firstWhere(
- (Folder folder) => folder.path == contextFilter,
- orElse: () => null);
- }
-
- /**
- * Return `true` if the given analysis [context] has at least one entry with
- * an exception.
- */
- bool _hasException(AnalysisContextImpl context) {
- bool hasException = false;
- context.visitCacheItems((Source source, SourceEntry sourceEntry,
- DataDescriptor rowDesc, CacheState state) {
- if (sourceEntry.exception != null) {
- hasException = true;
- }
- });
- return hasException;
- }
-
- /**
- * Return the folder in the [folderMap] with which the given [context] is
- * associated.
- */
- Folder _keyForValue(
- Map<Folder, AnalysisContext> folderMap, AnalysisContext context) {
- for (Folder folder in folderMap.keys) {
- if (folderMap[folder] == context) {
- return folder;
- }
- }
- return null;
- }
-
- /**
- * Return a response displaying overall performance information.
- */
- void _returnAnalysisPerformance(HttpRequest request) {
- AnalysisServer analysisServer = _server.analysisServer;
- if (analysisServer == null) {
- return _returnFailure(request, 'Analysis server is not running');
- }
- _writeResponse(request, (StringBuffer buffer) {
- _writePage(buffer, 'Analysis Server - Analysis Performance', [],
- (StringBuffer buffer) {
- buffer.write('<h3>Analysis Performance</h3>');
-
- //
- // Write performance tags.
- //
- {
- buffer.write('<p><b>Time spent in each phase of analysis</b></p>');
- buffer.write(
- '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
- _writeRow(buffer, ['Time (in ms)', 'Percent', 'Analysis Phase'],
- header: true);
- // prepare sorted tags
- List<PerformanceTag> tags = PerformanceTag.all.toList();
- tags.remove(ServerPerformanceStatistics.idle);
- tags.sort((a, b) => b.elapsedMs - a.elapsedMs);
- // prepare total time
- int totalTime = 0;
- tags.forEach((PerformanceTag tag) {
- totalTime += tag.elapsedMs;
- });
- // write rows
- void writeRow(PerformanceTag tag) {
- double percent = (tag.elapsedMs * 100) / totalTime;
- String percentStr = '${percent.toStringAsFixed(2)}%';
- _writeRow(buffer, [tag.elapsedMs, percentStr, tag.label],
- classes: ["right", "right", null]);
- }
- tags.forEach(writeRow);
- buffer.write('</table>');
- }
-
- //
- // Write new task model timing information.
- //
- if (AnalysisEngine.instance.useTaskModel) {
- buffer.write('<p><b>Task performace data</b></p>');
- buffer.write(
- '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
- _writeRow(
- buffer,
- [
- 'Task Name',
- 'Count',
- 'Total Time (in ms)',
- 'Average Time (in ms)'
- ],
- header: true);
-
- Map<Type, int> countMap = newTask.AnalysisTask.countMap;
- Map<Type, Stopwatch> stopwatchMap = newTask.AnalysisTask.stopwatchMap;
- List<Type> taskClasses = stopwatchMap.keys.toList();
- taskClasses.sort((Type first, Type second) =>
- first.toString().compareTo(second.toString()));
- int totalTime = 0;
- taskClasses.forEach((Type taskClass) {
- int count = countMap[taskClass];
- if (count == null) {
- count = 0;
- }
- int taskTime = stopwatchMap[taskClass].elapsedMilliseconds;
- totalTime += taskTime;
- _writeRow(buffer, [
- taskClass.toString(),
- count,
- taskTime,
- count <= 0 ? '-' : (taskTime / count).toStringAsFixed(3)
- ], classes: [
- null,
- "right",
- "right",
- "right"
- ]);
- });
- _writeRow(buffer, ['Total', '-', totalTime, '-'],
- classes: [null, "right", "right", "right"]);
- buffer.write('</table>');
- }
-
- //
- // Write old task model transition information.
- //
- {
- Map<DataDescriptor, Map<CacheState, int>> transitionMap =
- SourceEntry.transitionMap;
- buffer.write(
- '<p><b>Number of times a state transitioned to VALID (grouped by descriptor)</b></p>');
- if (transitionMap.isEmpty) {
- buffer.write('<p>none</p>');
- } else {
- List<DataDescriptor> descriptors = transitionMap.keys.toList();
- descriptors.sort((DataDescriptor first, DataDescriptor second) =>
- first.toString().compareTo(second.toString()));
- for (DataDescriptor key in descriptors) {
- Map<CacheState, int> countMap = transitionMap[key];
- List<CacheState> oldStates = countMap.keys.toList();
- oldStates.sort((CacheState first, CacheState second) =>
- first.toString().compareTo(second.toString()));
- buffer.write('<p>${key.toString()}</p>');
- buffer.write(
- '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
- _writeRow(buffer, ['Count', 'Previous State'], header: true);
- for (CacheState state in oldStates) {
- _writeRow(buffer, [countMap[state], state.toString()],
- classes: ["right", null]);
- }
- buffer.write('</table>');
- }
- }
- }
- });
- });
- }
-
- /**
- * Return a response containing information about an AST structure.
- */
- void _returnAst(HttpRequest request) {
- AnalysisServer analysisServer = _server.analysisServer;
- if (analysisServer == null) {
- return _returnFailure(request, 'Analysis server not running');
- }
- String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
- if (contextFilter == null) {
- return _returnFailure(
- request, 'Query parameter $CONTEXT_QUERY_PARAM required');
- }
- Folder folder = _findFolder(analysisServer, contextFilter);
- if (folder == null) {
- return _returnFailure(request, 'Invalid context: $contextFilter');
- }
- String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
- if (sourceUri == null) {
- return _returnFailure(
- request, 'Query parameter $SOURCE_QUERY_PARAM required');
- }
-
- AnalysisContextImpl context = analysisServer.folderMap[folder];
-
- _writeResponse(request, (StringBuffer buffer) {
- _writePage(buffer, 'Analysis Server - AST Structure',
- ['Context: $contextFilter', 'File: $sourceUri'], (HttpResponse) {
- Source source = context.sourceFactory.forUri(sourceUri);
- if (source == null) {
- buffer.write('<p>Not found.</p>');
- return;
- }
- SourceEntry entry = context.getReadableSourceEntryOrNull(source);
- if (entry == null) {
- buffer.write('<p>Not found.</p>');
- return;
- }
- CompilationUnit ast = (entry as DartEntry).anyParsedCompilationUnit;
- if (ast == null) {
- buffer.write('<p>null</p>');
- return;
- }
- AstWriter writer = new AstWriter(buffer);
- ast.accept(writer);
- if (writer.exceptions.isNotEmpty) {
- buffer.write('<h3>Exceptions while creating page</h3>');
- for (CaughtException exception in writer.exceptions) {
- _writeException(buffer, exception);
- }
- }
- });
- });
- }
-
- /**
- * Return a response containing information about a single source file in the
- * cache.
- */
- void _returnCacheEntry(HttpRequest request) {
- AnalysisServer analysisServer = _server.analysisServer;
- if (analysisServer == null) {
- return _returnFailure(request, 'Analysis server not running');
- }
- String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
- if (contextFilter == null) {
- return _returnFailure(
- request, 'Query parameter $CONTEXT_QUERY_PARAM required');
- }
- Folder folder = _findFolder(analysisServer, contextFilter);
- if (folder == null) {
- return _returnFailure(request, 'Invalid context: $contextFilter');
- }
- String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
- if (sourceUri == null) {
- return _returnFailure(
- request, 'Query parameter $SOURCE_QUERY_PARAM required');
- }
-
- List<Folder> allContexts = <Folder>[];
- Map<Folder, SourceEntry> entryMap = new HashMap<Folder, SourceEntry>();
- analysisServer.folderMap
- .forEach((Folder folder, AnalysisContextImpl context) {
- Source source = context.sourceFactory.forUri(sourceUri);
- if (source != null) {
- SourceEntry entry = context.getReadableSourceEntryOrNull(source);
- if (entry != null) {
- allContexts.add(folder);
- entryMap[folder] = entry;
- }
- }
- });
- allContexts.sort((Folder firstFolder, Folder secondFolder) =>
- firstFolder.path.compareTo(secondFolder.path));
- AnalysisContextImpl context = analysisServer.folderMap[folder];
-
- _writeResponse(request, (StringBuffer buffer) {
- _writePage(buffer, 'Analysis Server - Cache Entry',
- ['Context: $contextFilter', 'File: $sourceUri'], (HttpResponse) {
- buffer.write('<h3>Analyzing Contexts</h3><p>');
- bool first = true;
- allContexts.forEach((Folder folder) {
- if (first) {
- first = false;
- } else {
- buffer.write('<br>');
- }
- AnalysisContextImpl analyzingContext =
- analysisServer.folderMap[folder];
- if (analyzingContext == context) {
- buffer.write(folder.path);
- } else {
- buffer.write(makeLink(
- CACHE_ENTRY_PATH,
- {
- CONTEXT_QUERY_PARAM: folder.path,
- SOURCE_QUERY_PARAM: sourceUri
- },
- HTML_ESCAPE.convert(folder.path)));
- }
- if (entryMap[folder].explicitlyAdded) {
- buffer.write(' (explicit)');
- } else {
- buffer.write(' (implicit)');
- }
- });
- buffer.write('</p>');
-
- SourceEntry entry = entryMap[folder];
- if (entry == null) {
- buffer.write('<p>Not being analyzed in this context.</p>');
- return;
- }
- Map<String, String> linkParameters = <String, String>{
- CONTEXT_QUERY_PARAM: folder.path,
- SOURCE_QUERY_PARAM: sourceUri
- };
-
- buffer.write('<h3>Library Independent</h3>');
- _writeDescriptorTable(buffer, entry.descriptors, entry.getState,
- entry.getValue, linkParameters);
- if (entry is DartEntry) {
- for (Source librarySource in entry.containingLibraries) {
- String libraryName = HTML_ESCAPE.convert(librarySource.fullName);
- buffer.write('<h3>In library $libraryName:</h3>');
- _writeDescriptorTable(
- buffer,
- entry.libraryDescriptors,
- (DataDescriptor descriptor) =>
- entry.getStateInLibrary(descriptor, librarySource),
- (DataDescriptor descriptor) =>
- entry.getValueInLibrary(descriptor, librarySource),
- linkParameters);
- }
- }
- if (entry.exception != null) {
- buffer.write('<h3>Exception</h3>');
- _writeException(buffer, entry.exception);
- }
- });
- });
- }
-
- /**
- * Return a response indicating the set of source files in a certain cache
- * state.
- */
- void _returnCacheState(HttpRequest request) {
- AnalysisServer analysisServer = _server.analysisServer;
- if (analysisServer == null) {
- return _returnFailure(request, 'Analysis server not running');
- }
- // Figure out which context is being searched within.
- String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
- if (contextFilter == null) {
- return _returnFailure(
- request, 'Query parameter $CONTEXT_QUERY_PARAM required');
- }
- // Figure out what CacheState is being searched for.
- String stateQueryParam = request.uri.queryParameters[STATE_QUERY_PARAM];
- if (stateQueryParam == null) {
- return _returnFailure(
- request, 'Query parameter $STATE_QUERY_PARAM required');
- }
- CacheState stateFilter = null;
- for (CacheState value in CacheState.values) {
- if (value.toString() == stateQueryParam) {
- stateFilter = value;
- }
- }
- if (stateFilter == null) {
- return _returnFailure(
- request, 'Query parameter $STATE_QUERY_PARAM is invalid');
- }
- // Figure out which descriptor is being searched for.
- String descriptorFilter =
- request.uri.queryParameters[DESCRIPTOR_QUERY_PARAM];
- if (descriptorFilter == null) {
- return _returnFailure(
- request, 'Query parameter $DESCRIPTOR_QUERY_PARAM required');
- }
-
- Folder folder = _findFolder(analysisServer, contextFilter);
- AnalysisContextImpl context = analysisServer.folderMap[folder];
- List<String> links = <String>[];
- context.visitCacheItems((Source source, SourceEntry dartEntry,
- DataDescriptor rowDesc, CacheState state) {
- if (state != stateFilter || rowDesc.toString() != descriptorFilter) {
- return;
- }
- String link = makeLink(
- CACHE_ENTRY_PATH,
- {
- CONTEXT_QUERY_PARAM: folder.path,
- SOURCE_QUERY_PARAM: source.uri.toString()
- },
- HTML_ESCAPE.convert(source.fullName));
- links.add(link);
- });
-
- _writeResponse(request, (StringBuffer buffer) {
- _writePage(buffer, 'Analysis Server - Cache Search', [
- 'Context: $contextFilter',
- 'Descriptor: ${HTML_ESCAPE.convert(descriptorFilter)}',
- 'State: ${HTML_ESCAPE.convert(stateQueryParam)}'
- ], (StringBuffer buffer) {
- buffer.write('<p>${links.length} files found</p>');
- buffer.write('<ul>');
- links.forEach((String link) {
- buffer.write('<li>$link</li>');
- });
- buffer.write('</ul>');
- });
- });
- }
-
- /**
- * Return a response displaying overall performance information.
- */
- void _returnCommunicationPerformance(HttpRequest request) {
- AnalysisServer analysisServer = _server.analysisServer;
- if (analysisServer == null) {
- return _returnFailure(request, 'Analysis server is not running');
- }
- _writeResponse(request, (StringBuffer buffer) {
- _writePage(buffer, 'Analysis Server - Communication Performance', [],
- (StringBuffer buffer) {
- buffer.write('<h3>Communication Performance</h3>');
- _writeTwoColumns(buffer, (StringBuffer buffer) {
- ServerPerformance perf = analysisServer.performanceDuringStartup;
- int requestCount = perf.requestCount;
- num averageLatency = requestCount > 0
- ? (perf.requestLatency / requestCount).round()
- : 0;
- int maximumLatency = perf.maxLatency;
- num slowRequestPercent = requestCount > 0
- ? (perf.slowRequestCount * 100 / requestCount).round()
- : 0;
- buffer.write('<h4>Startup</h4>');
- buffer.write('<table>');
- _writeRow(buffer, [requestCount, 'requests'],
- classes: ["right", null]);
- _writeRow(buffer, [averageLatency, 'ms average latency'],
- classes: ["right", null]);
- _writeRow(buffer, [maximumLatency, 'ms maximum latency'],
- classes: ["right", null]);
- _writeRow(buffer, [slowRequestPercent, '% > 150 ms latency'],
- classes: ["right", null]);
- if (analysisServer.performanceAfterStartup != null) {
- int startupTime = analysisServer.performanceAfterStartup.startTime -
- perf.startTime;
- _writeRow(
- buffer, [startupTime, 'ms for initial analysis to complete']);
- }
- buffer.write('</table>');
- }, (StringBuffer buffer) {
- ServerPerformance perf = analysisServer.performanceAfterStartup;
- if (perf == null) {
- return;
- }
- int requestCount = perf.requestCount;
- num averageLatency = requestCount > 0
- ? (perf.requestLatency * 10 / requestCount).round() / 10
- : 0;
- int maximumLatency = perf.maxLatency;
- num slowRequestPercent = requestCount > 0
- ? (perf.slowRequestCount * 100 / requestCount).round()
- : 0;
- buffer.write('<h4>Current</h4>');
- buffer.write('<table>');
- _writeRow(buffer, [requestCount, 'requests'],
- classes: ["right", null]);
- _writeRow(buffer, [averageLatency, 'ms average latency'],
- classes: ["right", null]);
- _writeRow(buffer, [maximumLatency, 'ms maximum latency'],
- classes: ["right", null]);
- _writeRow(buffer, [slowRequestPercent, '% > 150 ms latency'],
- classes: ["right", null]);
- buffer.write('</table>');
- });
- });
- });
- }
-
- /**
- * Return a response displaying code completion information.
- */
- void _returnCompletionInfo(HttpRequest request) {
- String value = request.requestedUri.queryParameters['index'];
- int index = value != null ? int.parse(value, onError: (_) => 0) : 0;
- _writeResponse(request, (StringBuffer buffer) {
- _writePage(buffer, 'Analysis Server - Completion Stats', [],
- (StringBuffer buffer) {
- _writeCompletionPerformanceDetail(buffer, index);
- _writeCompletionPerformanceList(buffer);
- });
- });
- }
-
- /**
- * Return a response containing information about a single source file in the
- * cache.
- */
- void _returnContextInfo(HttpRequest request) {
- AnalysisServer analysisServer = _server.analysisServer;
- if (analysisServer == null) {
- return _returnFailure(request, 'Analysis server not running');
- }
- String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
- if (contextFilter == null) {
- return _returnFailure(
- request, 'Query parameter $CONTEXT_QUERY_PARAM required');
- }
- Folder folder = _findFolder(analysisServer, contextFilter);
- if (folder == null) {
- return _returnFailure(request, 'Invalid context: $contextFilter');
- }
-
- List<String> priorityNames;
- List<String> explicitNames = <String>[];
- List<String> implicitNames = <String>[];
- Map<String, String> links = new HashMap<String, String>();
- List<CaughtException> exceptions = <CaughtException>[];
- AnalysisContextImpl context = analysisServer.folderMap[folder];
- priorityNames = context.prioritySources
- .map((Source source) => source.fullName)
- .toList();
- context.visitCacheItems((Source source, SourceEntry sourceEntry,
- DataDescriptor rowDesc, CacheState state) {
- String sourceName = source.fullName;
- if (!links.containsKey(sourceName)) {
- CaughtException exception = sourceEntry.exception;
- if (exception != null) {
- exceptions.add(exception);
- }
- String link = makeLink(
- CACHE_ENTRY_PATH,
- {
- CONTEXT_QUERY_PARAM: folder.path,
- SOURCE_QUERY_PARAM: source.uri.toString()
- },
- sourceName,
- exception != null);
- if (sourceEntry.explicitlyAdded) {
- explicitNames.add(sourceName);
- } else {
- implicitNames.add(sourceName);
- }
- links[sourceName] = link;
- }
- });
- explicitNames.sort();
- implicitNames.sort();
-
- _overlayContents.clear();
- context.visitContentCache((String fullName, int stamp, String contents) {
- _overlayContents[fullName] = contents;
- });
-
- void _writeFiles(
- StringBuffer buffer, String title, List<String> fileNames) {
- buffer.write('<h3>$title</h3>');
- if (fileNames == null || fileNames.isEmpty) {
- buffer.write('<p>None</p>');
- } else {
- buffer.write('<table style="width: 100%">');
- for (String fileName in fileNames) {
- buffer.write('<tr><td>');
- buffer.write(links[fileName]);
- buffer.write('</td><td>');
- if (_overlayContents.containsKey(fileName)) {
- buffer.write(
- makeLink(OVERLAY_PATH, {PATH_PARAM: fileName}, 'overlay'));
- }
- buffer.write('</td></tr>');
- }
- buffer.write('</table>');
- }
- }
-
- _writeResponse(request, (StringBuffer buffer) {
- _writePage(
- buffer, 'Analysis Server - Context', ['Context: $contextFilter'],
- (StringBuffer buffer) {
- List headerRowText = ['Context'];
- headerRowText.addAll(CacheState.values);
- buffer.write('<h3>Summary</h3>');
- buffer.write('<table>');
- _writeRow(buffer, headerRowText, header: true);
- AnalysisContextStatistics statistics = context.statistics;
- statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
- List rowText = [row.name];
- for (CacheState state in CacheState.values) {
- String text = row.getCount(state).toString();
- Map<String, String> params = <String, String>{
- STATE_QUERY_PARAM: state.toString(),
- CONTEXT_QUERY_PARAM: folder.path,
- DESCRIPTOR_QUERY_PARAM: row.name
- };
- rowText.add(makeLink(CACHE_STATE_PATH, params, text));
- }
- _writeRow(buffer, rowText, classes: [null, "right"]);
- });
- buffer.write('</table>');
-
- _writeFiles(buffer, 'Priority Files', priorityNames);
- _writeFiles(buffer, 'Explicitly Analyzed Files', explicitNames);
- _writeFiles(buffer, 'Implicitly Analyzed Files', implicitNames);
-
- buffer.write('<h3>Exceptions</h3>');
- if (exceptions.isEmpty) {
- buffer.write('<p>None</p>');
- } else {
- exceptions.forEach((CaughtException exception) {
- _writeException(buffer, exception);
- });
- }
- });
- });
- }
-
- /**
- * Return a response containing information about an element structure.
- */
- void _returnElement(HttpRequest request) {
- AnalysisServer analysisServer = _server.analysisServer;
- if (analysisServer == null) {
- return _returnFailure(request, 'Analysis server not running');
- }
- String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
- if (contextFilter == null) {
- return _returnFailure(
- request, 'Query parameter $CONTEXT_QUERY_PARAM required');
- }
- Folder folder = _findFolder(analysisServer, contextFilter);
- if (folder == null) {
- return _returnFailure(request, 'Invalid context: $contextFilter');
- }
- String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
- if (sourceUri == null) {
- return _returnFailure(
- request, 'Query parameter $SOURCE_QUERY_PARAM required');
- }
-
- AnalysisContextImpl context = analysisServer.folderMap[folder];
-
- _writeResponse(request, (StringBuffer buffer) {
- _writePage(buffer, 'Analysis Server - Element Model', [
- 'Context: $contextFilter',
- 'File: $sourceUri'
- ], (StringBuffer buffer) {
- Source source = context.sourceFactory.forUri(sourceUri);
- if (source == null) {
- buffer.write('<p>Not found.</p>');
- return;
- }
- SourceEntry entry = context.getReadableSourceEntryOrNull(source);
- if (entry == null) {
- buffer.write('<p>Not found.</p>');
- return;
- }
- LibraryElement element = entry.getValue(DartEntry.ELEMENT);
- if (element == null) {
- buffer.write('<p>null</p>');
- return;
- }
- element.accept(new ElementWriter(buffer));
- });
- });
- }
-
- void _returnFailure(HttpRequest request, String message) {
- _writeResponse(request, (StringBuffer buffer) {
- _writePage(buffer, 'Analysis Server - Failure', [],
- (StringBuffer buffer) {
- buffer.write(HTML_ESCAPE.convert(message));
- });
- });
- }
-
- /**
- * Return a response containing information about elements with the given
- * name.
- */
- Future _returnIndexElementByName(HttpRequest request) async {
- AnalysisServer analysisServer = _server.analysisServer;
- if (analysisServer == null) {
- return _returnFailure(request, 'Analysis server not running');
- }
- Index index = analysisServer.index;
- if (index == null) {
- return _returnFailure(request, 'Indexing is disabled');
- }
- String name = request.uri.queryParameters[INDEX_ELEMENT_NAME];
- if (name == null) {
- return _returnFailure(
- request, 'Query parameter $INDEX_ELEMENT_NAME required');
- }
- if (index is LocalIndex) {
- Map<List<String>, List<InspectLocation>> relations =
- await index.findElementsByName(name);
- _writeResponse(request, (StringBuffer buffer) {
- _writePage(buffer, 'Analysis Server - Index Elements', ['Name: $name'],
- (StringBuffer buffer) {
- buffer.write('<table border="1">');
- _writeRow(buffer, ['Element', 'Relationship', 'Location'],
- header: true);
- relations.forEach(
- (List<String> elementPath, List<InspectLocation> relations) {
- String elementLocation = elementPath.join(' ');
- relations.forEach((InspectLocation location) {
- var relString = location.relationship.identifier;
- var locString = '${location.path} offset=${location.offset} '
- 'length=${location.length} flags=${location.flags}';
- _writeRow(buffer, [elementLocation, relString, locString]);
- });
- });
- buffer.write('</table>');
- });
- });
- } else {
- return _returnFailure(request, 'LocalIndex expected, but $index found.');
- }
- }
-
- void _returnOverlayContents(HttpRequest request) {
- String path = request.requestedUri.queryParameters[PATH_PARAM];
- if (path == null) {
- return _returnFailure(request, 'Query parameter $PATH_PARAM required');
- }
- String contents = _overlayContents[path];
-
- _writeResponse(request, (StringBuffer buffer) {
- _writePage(buffer, 'Analysis Server - Overlay', [],
- (StringBuffer buffer) {
- buffer.write('<pre>${HTML_ESCAPE.convert(contents)}</pre>');
- });
- });
- }
-
- /**
- * Return a response displaying overlays information.
- */
- void _returnOverlaysInfo(HttpRequest request) {
- AnalysisServer analysisServer = _server.analysisServer;
- if (analysisServer == null) {
- return _returnFailure(request, 'Analysis server is not running');
- }
-
- _writeResponse(request, (StringBuffer buffer) {
- _writePage(buffer, 'Analysis Server - Overlays', [],
- (StringBuffer buffer) {
- buffer.write('<table border="1">');
- _overlayContents.clear();
- ContentCache overlayState = analysisServer.overlayState;
- overlayState.accept((String fullName, int stamp, String contents) {
- buffer.write('<tr>');
- String link =
- makeLink(OVERLAY_PATH, {PATH_PARAM: fullName}, fullName);
- DateTime time = new DateTime.fromMillisecondsSinceEpoch(stamp);
- _writeRow(buffer, [link, time]);
- _overlayContents[fullName] = contents;
- });
- int count = _overlayContents.length;
- buffer.write('<tr><td colspan="2">Total: $count entries.</td></tr>');
- buffer.write('</table>');
- });
- });
- }
-
- /**
- * Return a response indicating the status of the analysis server.
- */
- void _returnServerStatus(HttpRequest request) {
- _writeResponse(request, (StringBuffer buffer) {
- _writePage(buffer, 'Analysis Server - Status', [], (StringBuffer buffer) {
- if (_writeServerStatus(buffer)) {
- _writeAnalysisStatus(buffer);
- _writeEditStatus(buffer);
- _writeExecutionStatus(buffer);
- _writePluginStatus(buffer);
- _writeRecentOutput(buffer);
- }
- });
- });
- }
-
- /**
- * Return an error in response to an unrecognized request received by the HTTP
- * server.
- */
- void _returnUnknownRequest(HttpRequest request) {
- _writeResponse(request, (StringBuffer buffer) {
- _writePage(buffer, 'Analysis Server', [], (StringBuffer buffer) {
- buffer.write('<h3>Pages</h3>');
- buffer.write('<p>');
- buffer.write(makeLink(COMPLETION_PATH, {}, 'Completion data'));
- buffer.write('</p>');
- buffer.write('<p>');
- buffer
- .write(makeLink(COMMUNICATION_PERFORMANCE_PATH, {}, 'Performance'));
- buffer.write('</p>');
- buffer.write('<p>');
- buffer.write(makeLink(STATUS_PATH, {}, 'Server status'));
- buffer.write('</p>');
- buffer.write('<p>');
- buffer.write(makeLink(OVERLAYS_PATH, {}, 'File overlays'));
- buffer.write('</p>');
- });
- });
- }
-
- /**
- * Return a two digit decimal representation of the given non-negative integer
- * [value].
- */
- String _twoDigit(int value) {
- if (value < 10) {
- return '0$value';
- }
- return value.toString();
- }
-
- /**
- * Write the status of the analysis domain (on the main status page) to the
- * given [buffer] object.
- */
- void _writeAnalysisStatus(StringBuffer buffer) {
- AnalysisServer analysisServer = _server.analysisServer;
- Map<Folder, AnalysisContext> folderMap = analysisServer.folderMap;
- List<Folder> folders = folderMap.keys.toList();
- folders.sort((Folder first, Folder second) =>
- first.shortName.compareTo(second.shortName));
- AnalysisOptionsImpl options = analysisServer.defaultContextOptions;
- ServerOperationQueue operationQueue = analysisServer.operationQueue;
-
- buffer.write('<h3>Analysis Domain</h3>');
- _writeTwoColumns(buffer, (StringBuffer buffer) {
- if (operationQueue.isEmpty) {
- buffer.write('<p>Status: Done analyzing</p>');
- } else {
- ServerOperation operation = operationQueue.peek();
- if (operation is PerformAnalysisOperation) {
- Folder folder = _keyForValue(folderMap, operation.context);
- if (folder == null) {
- buffer.write('<p>Status: Analyzing in unmapped context</p>');
- } else {
- buffer.write('<p>Status: Analyzing in ${folder.path}</p>');
- }
- } else {
- buffer.write('<p>Status: Analyzing</p>');
- }
- }
-
- buffer.write('<p><b>Analysis Contexts</b></p>');
- buffer.write('<p>');
- bool first = true;
- folders.forEach((Folder folder) {
- if (first) {
- first = false;
- } else {
- buffer.write('<br>');
- }
- String key = folder.shortName;
- buffer.write(makeLink(CONTEXT_PATH, {CONTEXT_QUERY_PARAM: folder.path},
- key, _hasException(folderMap[folder])));
- });
- buffer.write('</p>');
-
- buffer.write('<p><b>Options</b></p>');
- buffer.write('<p>');
- _writeOption(
- buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
- _writeOption(buffer, 'Cache size', options.cacheSize);
- _writeOption(
- buffer, 'Enable strict call checks', options.enableStrictCallChecks);
- _writeOption(buffer, 'Enable super mixins', options.enableSuperMixins);
- _writeOption(buffer, 'Generate hints', options.hint);
- _writeOption(buffer, 'Generate dart2js hints', options.dart2jsHint);
- _writeOption(buffer, 'Generate errors in implicit files',
- options.generateImplicitErrors);
- _writeOption(
- buffer, 'Generate errors in SDK files', options.generateSdkErrors);
- _writeOption(buffer, 'Incremental resolution', options.incremental);
- _writeOption(buffer, 'Incremental resolution with API changes',
- options.incrementalApi);
- _writeOption(buffer, 'Preserve comments', options.preserveComments,
- last: true);
- buffer.write('</p>');
- int freq = AnalysisServer.performOperationDelayFreqency;
- String delay = freq > 0 ? '1 ms every $freq ms' : 'off';
- buffer.write('<p><b>perform operation delay:</b> $delay</p>');
-
- buffer.write('<p><b>Performance Data</b></p>');
- buffer.write('<p>');
- buffer.write(makeLink(ANALYSIS_PERFORMANCE_PATH, {}, 'Task data'));
- buffer.write('</p>');
- }, (StringBuffer buffer) {
- _writeSubscriptionMap(
- buffer, AnalysisService.VALUES, analysisServer.analysisServices);
- });
- }
-
- /**
- * Write performance information about a specific completion request
- * to the given [buffer] object.
- */
- void _writeCompletionPerformanceDetail(StringBuffer buffer, int index) {
- CompletionDomainHandler handler = _completionDomainHandler;
- CompletionPerformance performance;
- if (handler != null) {
- List<CompletionPerformance> list = handler.performanceList;
- if (list != null && list.isNotEmpty) {
- performance = list[max(0, min(list.length - 1, index))];
- }
- }
- if (performance == null) {
- buffer.write('<h3>Completion Performance Detail</h3>');
- buffer.write('<p>No completions yet</p>');
- return;
- }
- buffer.write('<h3>Completion Performance Detail</h3>');
- buffer.write('<p>${performance.startTimeAndMs} for ${performance.source}');
- buffer.write('<table>');
- _writeRow(buffer, ['Elapsed', '', 'Operation'], header: true);
- performance.operations.forEach((OperationPerformance op) {
- String elapsed = op.elapsed != null ? op.elapsed.toString() : '???';
- _writeRow(buffer, [elapsed, ' ', op.name]);
- });
- buffer.write('</table>');
- buffer.write('<p><b>Compute Cache Performance</b>: ');
- if (handler.computeCachePerformance == null) {
- buffer.write('none');
- } else {
- int elapsed = handler.computeCachePerformance.elapsedInMilliseconds;
- Source source = handler.computeCachePerformance.source;
- buffer.write(' $elapsed ms for $source');
- }
- buffer.write('</p>');
- }
-
- /**
- * Write a table showing summary information for the last several
- * completion requests to the given [buffer] object.
- */
- void _writeCompletionPerformanceList(StringBuffer buffer) {
- CompletionDomainHandler handler = _completionDomainHandler;
- buffer.write('<h3>Completion Performance List</h3>');
- if (handler == null) {
- return;
- }
- buffer.write('<table>');
- _writeRow(
- buffer,
- [
- 'Start Time',
- '',
- 'First (ms)',
- '',
- 'Complete (ms)',
- '',
- '# Notifications',
- '',
- '# Suggestions',
- '',
- 'Snippet'
- ],
- header: true);
- int index = 0;
- for (CompletionPerformance performance in handler.performanceList) {
- String link = makeLink(COMPLETION_PATH, {'index': '$index'},
- '${performance.startTimeAndMs}');
- _writeRow(buffer, [
- link,
- ' ',
- performance.firstNotificationInMilliseconds,
- ' ',
- performance.elapsedInMilliseconds,
- ' ',
- performance.notificationCount,
- ' ',
- performance.suggestionCount,
- ' ',
- HTML_ESCAPE.convert(performance.snippet)
- ]);
- ++index;
- }
-
- buffer.write('</table>');
- buffer.write('''
- <p><strong>First (ms)</strong> - the number of milliseconds
- from when completion received the request until the first notification
- with completion results was queued for sending back to the client.
- <p><strong>Complete (ms)</strong> - the number of milliseconds
- from when completion received the request until the final notification
- with completion results was queued for sending back to the client.
- <p><strong># Notifications</strong> - the total number of notifications
- sent to the client with completion results for this request.
- <p><strong># Suggestions</strong> - the number of suggestions
- sent to the client in the first notification, followed by a comma,
- followed by the number of suggestions send to the client
- in the last notification. If there is only one notification,
- then there will be only one number in this column.''');
- }
-
- /**
- * Generate a table showing the cache values corresponding to the given
- * [descriptors], using [getState] to get the cache state corresponding to
- * each descriptor, and [getValue] to get the cached value corresponding to
- * each descriptor. Append the resulting HTML to the given [buffer]. The
- * [linkParameters] will be used if the value is too large to be displayed on
- * the current page and needs to be linked to a separate page.
- */
- void _writeDescriptorTable(
- StringBuffer buffer,
- List<DataDescriptor> descriptors,
- CacheState getState(DataDescriptor),
- dynamic getValue(DataDescriptor),
- Map<String, String> linkParameters) {
- buffer.write('<dl>');
- for (DataDescriptor descriptor in descriptors) {
- String descriptorName = HTML_ESCAPE.convert(descriptor.toString());
- String descriptorState =
- HTML_ESCAPE.convert(getState(descriptor).toString());
- buffer.write('<dt>$descriptorName ($descriptorState)</dt><dd>');
- try {
- _writeValueAsHtml(buffer, getValue(descriptor), linkParameters);
- } catch (exception) {
- buffer.write('(${HTML_ESCAPE.convert(exception.toString())})');
- }
- buffer.write('</dd>');
- }
- buffer.write('</dl>');
- }
-
- /**
- * Write the status of the edit domain (on the main status page) to the given
- * [buffer].
- */
- void _writeEditStatus(StringBuffer buffer) {
- buffer.write('<h3>Edit Domain</h3>');
- _writeTwoColumns(buffer, (StringBuffer buffer) {
- buffer.write('<p><b>Performance Data</b></p>');
- buffer.write('<p>');
- buffer.write(makeLink(COMPLETION_PATH, {}, 'Completion data'));
- buffer.write('</p>');
- }, (StringBuffer buffer) {});
- }
-
- /**
- * Write a representation of the given [caughtException] to the given
- * [buffer]. If [isCause] is `true`, then the exception was a cause for
- * another exception.
- */
- void _writeException(StringBuffer buffer, CaughtException caughtException,
- {bool isCause: false}) {
- Object exception = caughtException.exception;
-
- if (exception is AnalysisException) {
- buffer.write('<p>');
- if (isCause) {
- buffer.write('Caused by ');
- }
- buffer.write(exception.message);
- buffer.write('</p>');
- _writeStackTrace(buffer, caughtException.stackTrace);
- CaughtException cause = exception.cause;
- if (cause != null) {
- buffer.write('<blockquote>');
- _writeException(buffer, cause, isCause: true);
- buffer.write('</blockquote>');
- }
- } else {
- buffer.write('<p>');
- if (isCause) {
- buffer.write('Caused by ');
- }
- buffer.write(exception.toString());
- buffer.write('<p>');
- _writeStackTrace(buffer, caughtException.stackTrace);
- }
- }
-
- /**
- * Write the status of the execution domain (on the main status page) to the
- * given [buffer].
- */
- void _writeExecutionStatus(StringBuffer buffer) {
- AnalysisServer analysisServer = _server.analysisServer;
- ExecutionDomainHandler handler = analysisServer.handlers.firstWhere(
- (RequestHandler handler) => handler is ExecutionDomainHandler,
- orElse: () => null);
- Set<ExecutionService> services = new Set<ExecutionService>();
- if (handler.onFileAnalyzed != null) {
- services.add(ExecutionService.LAUNCH_DATA);
- }
-
- if (handler != null) {
- buffer.write('<h3>Execution Domain</h3>');
- _writeTwoColumns(buffer, (StringBuffer buffer) {
- _writeSubscriptionList(buffer, ExecutionService.VALUES, services);
- }, (StringBuffer buffer) {});
- }
- }
-
- /**
- * Write a representation of an analysis option with the given [name] and
- * [value] to the given [buffer]. The option should be separated from other
- * options unless the [last] flag is true, indicating that this is the last
- * option in the list of options.
- */
- void _writeOption(StringBuffer buffer, String name, Object value,
- {bool last: false}) {
- buffer.write(name);
- buffer.write(' = ');
- buffer.write(value.toString());
- if (!last) {
- buffer.write('<br>');
- }
- }
-
- /**
- * Write a standard HTML page to the given [buffer]. The page will have the
- * given [title] and a body that is generated by the given [body] generator.
- */
- void _writePage(StringBuffer buffer, String title, List<String> subtitles,
- HtmlGenerator body) {
- DateTime now = new DateTime.now();
- String date = "${now.month}/${now.day}/${now.year}";
- String time =
- "${now.hour}:${_twoDigit(now.minute)}:${_twoDigit(now.second)}.${now.millisecond}";
-
- buffer.write('<!DOCTYPE html>');
- buffer.write('<html>');
- buffer.write('<head>');
- buffer.write('<meta charset="utf-8">');
- buffer.write(
- '<meta name="viewport" content="width=device-width, initial-scale=1.0">');
- buffer.write('<title>$title</title>');
- buffer.write('<style>');
- buffer.write('a {color: #0000DD; text-decoration: none;}');
- buffer.write('a:link.error {background-color: #FFEEEE;}');
- buffer.write('a:visited.error {background-color: #FFEEEE;}');
- buffer.write('a:hover.error {background-color: #FFEEEE;}');
- buffer.write('a:active.error {background-color: #FFEEEE;}');
- buffer.write(
- 'h3 {background-color: #DDDDDD; margin-top: 0em; margin-bottom: 0em;}');
- buffer.write('p {margin-top: 0.5em; margin-bottom: 0.5em;}');
-// response.write('span.error {text-decoration-line: underline; text-decoration-color: red; text-decoration-style: wavy;}');
- buffer.write(
- 'table.column {border: 0px solid black; width: 100%; table-layout: fixed;}');
- buffer.write('td.column {vertical-align: top; width: 50%;}');
- buffer.write('td.right {text-align: right;}');
- buffer.write('</style>');
- buffer.write('</head>');
-
- buffer.write('<body>');
- buffer.write(
- '<h2>$title <small><small>(as of $time on $date)</small></small></h2>');
- if (subtitles != null && subtitles.isNotEmpty) {
- buffer.write('<blockquote>');
- bool first = true;
- for (String subtitle in subtitles) {
- if (first) {
- first = false;
- } else {
- buffer.write('<br>');
- }
- buffer.write('<b>');
- buffer.write(subtitle);
- buffer.write('</b>');
- }
- buffer.write('</blockquote>');
- }
- try {
- body(buffer);
- } catch (exception, stackTrace) {
- buffer.write('<h3>Exception while creating page</h3>');
- _writeException(buffer, new CaughtException(exception, stackTrace));
- }
- buffer.write('</body>');
- buffer.write('</html>');
- }
-
- /**
- * Write the recent output section (on the main status page) to the given
- * [buffer] object.
- */
- void _writePluginStatus(StringBuffer buffer) {
- void writePlugin(Plugin plugin) {
- buffer.write(plugin.uniqueIdentifier);
- buffer.write(' (');
- buffer.write(plugin.runtimeType);
- buffer.write(')<br>');
- }
- buffer.write('<h3>Plugin Status</h3><p>');
- writePlugin(AnalysisEngine.instance.enginePlugin);
- writePlugin(_server.serverPlugin);
- for (Plugin plugin in _server.analysisServer.userDefinedPlugins) {
- writePlugin(plugin);
- }
- buffer.write('<p>');
- }
-
- /**
- * Write the recent output section (on the main status page) to the given
- * [buffer] object.
- */
- void _writeRecentOutput(StringBuffer buffer) {
- buffer.write('<h3>Recent Output</h3>');
- String output = HTML_ESCAPE.convert(_printBuffer.join('\n'));
- if (output.isEmpty) {
- buffer.write('<i>none</i>');
- } else {
- buffer.write('<pre>');
- buffer.write(output);
- buffer.write('</pre>');
- }
- }
-
- void _writeResponse(HttpRequest request, HtmlGenerator writePage) {
- HttpResponse response = request.response;
- response.statusCode = HttpStatus.OK;
- response.headers.contentType = _htmlContent;
- try {
- StringBuffer buffer = new StringBuffer();
- try {
- writePage(buffer);
- } catch (exception, stackTrace) {
- buffer.clear();
- _writePage(buffer, 'Internal Exception', [], (StringBuffer buffer) {
- _writeException(buffer, new CaughtException(exception, stackTrace));
- });
- }
- response.write(buffer.toString());
- } finally {
- response.close();
- }
- }
-
- /**
- * Write a single row within a table to the given [buffer]. The row will have
- * one cell for each of the [columns], and will be a header row if [header] is
- * `true`.
- */
- void _writeRow(StringBuffer buffer, List<Object> columns,
- {bool header: false, List<String> classes}) {
- buffer.write('<tr>');
- int count = columns.length;
- int maxClassIndex = classes == null ? 0 : classes.length - 1;
- for (int i = 0; i < count; i++) {
- String classAttribute = '';
- if (classes != null) {
- String className = classes[min(i, maxClassIndex)];
- if (className != null) {
- classAttribute = ' class="$className"';
- }
- }
- if (header) {
- buffer.write('<th$classAttribute>');
- } else {
- buffer.write('<td$classAttribute>');
- }
- buffer.write(columns[i]);
- if (header) {
- buffer.write('</th>');
- } else {
- buffer.write('</td>');
- }
- }
- buffer.write('</tr>');
- }
-
- /**
- * Write the status of the service domain (on the main status page) to the
- * given [response] object.
- */
- bool _writeServerStatus(StringBuffer buffer) {
- AnalysisServer analysisServer = _server.analysisServer;
- Set<ServerService> services = analysisServer.serverServices;
-
- buffer.write('<h3>Server Domain</h3>');
- _writeTwoColumns(buffer, (StringBuffer buffer) {
- if (analysisServer == null) {
- buffer.write('Status: <span style="color:red">Not running</span>');
- return false;
- }
- buffer.write('<p>');
- buffer.write('Status: Running<br>');
- buffer.write('Instrumentation: ');
- if (AnalysisEngine.instance.instrumentationService.isActive) {
- buffer.write('<span style="color:red">Active</span>');
- } else {
- buffer.write('Inactive');
- }
- buffer.write('<br>');
- buffer.write('Version: ');
- buffer.write(AnalysisServer.VERSION);
- buffer.write('</p>');
-
- buffer.write('<p><b>Performance Data</b></p>');
- buffer.write('<p>');
- buffer.write(makeLink(
- COMMUNICATION_PERFORMANCE_PATH, {}, 'Communication performance'));
- buffer.write('</p>');
- }, (StringBuffer buffer) {
- _writeSubscriptionList(buffer, ServerService.VALUES, services);
- });
- return true;
- }
-
- /**
- * Write a representation of the given [stackTrace] to the given [buffer].
- */
- void _writeStackTrace(StringBuffer buffer, StackTrace stackTrace) {
- if (stackTrace != null) {
- String trace = stackTrace.toString().replaceAll('#', '<br>#');
- if (trace.startsWith('<br>#')) {
- trace = trace.substring(4);
- }
- buffer.write('<p>');
- buffer.write(trace);
- buffer.write('</p>');
- }
- }
-
- /**
- * Given a [service] that could be subscribed to and a set of the services
- * that are actually subscribed to ([subscribedServices]), write a
- * representation of the service to the given [buffer].
- */
- void _writeSubscriptionInList(
- StringBuffer buffer, Enum service, Set<Enum> subscribedServices) {
- if (subscribedServices.contains(service)) {
- buffer.write('<code>+ </code>');
- } else {
- buffer.write('<code>- </code>');
- }
- buffer.write(service.name);
- buffer.write('<br>');
- }
-
- /**
- * Given a [service] that could be subscribed to and a set of paths that are
- * subscribed to the services ([subscribedPaths]), write a representation of
- * the service to the given [buffer].
- */
- void _writeSubscriptionInMap(
- StringBuffer buffer, Enum service, Set<String> subscribedPaths) {
- buffer.write('<p>');
- buffer.write(service.name);
- buffer.write('</p>');
- if (subscribedPaths == null || subscribedPaths.isEmpty) {
- buffer.write('none');
- } else {
- List<String> paths = subscribedPaths.toList();
- paths.sort();
- for (String path in paths) {
- buffer.write('<p>');
- buffer.write(path);
- buffer.write('</p>');
- }
- }
- }
-
- /**
- * Given a list containing all of the services that can be subscribed to in a
- * single domain ([allServices]) and a set of the services that are actually
- * subscribed to ([subscribedServices]), write a representation of the
- * subscriptions to the given [buffer].
- */
- void _writeSubscriptionList(StringBuffer buffer, List<Enum> allServices,
- Set<Enum> subscribedServices) {
- buffer.write('<p><b>Subscriptions</b></p>');
- buffer.write('<p>');
- for (Enum service in allServices) {
- _writeSubscriptionInList(buffer, service, subscribedServices);
- }
- buffer.write('</p>');
- }
-
- /**
- * Given a list containing all of the services that can be subscribed to in a
- * single domain ([allServices]) and a set of the services that are actually
- * subscribed to ([subscribedServices]), write a representation of the
- * subscriptions to the given [buffer].
- */
- void _writeSubscriptionMap(StringBuffer buffer, List<Enum> allServices,
- Map<Enum, Set<String>> subscribedServices) {
- buffer.write('<p><b>Subscriptions</b></p>');
- for (Enum service in allServices) {
- _writeSubscriptionInMap(buffer, service, subscribedServices[service]);
- }
- }
-
- /**
- * Write two columns of information to the given [buffer], where the
- * [leftColumn] and [rightColumn] functions are used to generate the content
- * of those columns.
- */
- void _writeTwoColumns(StringBuffer buffer, HtmlGenerator leftColumn,
- HtmlGenerator rightColumn) {
- buffer
- .write('<table class="column"><tr class="column"><td class="column">');
- leftColumn(buffer);
- buffer.write('</td><td class="column">');
- rightColumn(buffer);
- buffer.write('</td></tr></table>');
- }
-
- /**
- * Render the given [value] as HTML and append it to the given [buffer]. The
- * [linkParameters] will be used if the value is too large to be displayed on
- * the current page and needs to be linked to a separate page.
- */
- void _writeValueAsHtml(
- StringBuffer buffer, Object value, Map<String, String> linkParameters) {
- if (value == null) {
- buffer.write('<i>null</i>');
- } else if (value is String) {
- buffer.write('<pre>${HTML_ESCAPE.convert(value)}</pre>');
- } else if (value is List) {
- buffer.write('List containing ${value.length} entries');
- buffer.write('<ul>');
- for (var entry in value) {
- buffer.write('<li>');
- _writeValueAsHtml(buffer, entry, linkParameters);
- buffer.write('</li>');
- }
- buffer.write('</ul>');
- } else if (value is AstNode) {
- String link =
- makeLink(AST_PATH, linkParameters, value.runtimeType.toString());
- buffer.write('<i>$link</i>');
- } else if (value is Element) {
- String link =
- makeLink(ELEMENT_PATH, linkParameters, value.runtimeType.toString());
- buffer.write('<i>$link</i>');
- } else {
- buffer.write(HTML_ESCAPE.convert(value.toString()));
- buffer.write(' <i>(${value.runtimeType.toString()})</i>');
- }
- }
-
- /**
- * Create a link to [path] with query parameters [params], with inner HTML
- * [innerHtml]. If [hasError] is `true`, then the link will have the class
- * 'error'.
- */
- static String makeLink(
- String path, Map<String, String> params, String innerHtml,
- [bool hasError = false]) {
- Uri uri = new Uri(path: path, queryParameters: params);
- String href = HTML_ESCAPE.convert(uri.toString());
- String classAttribute = hasError ? ' class="error"' : '';
- return '<a href="$href"$classAttribute>$innerHtml</a>';
- }
-}
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index aeb8d03..66fac73 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -21,7 +21,6 @@
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart';
import 'package:analyzer/src/generated/source.dart';
/**
@@ -152,14 +151,18 @@
});
}
-void sendAnalysisNotificationErrors(AnalysisServer server, String file,
- LineInfo lineInfo, List<AnalysisError> errors) {
+void sendAnalysisNotificationErrors(
+ AnalysisServer server,
+ AnalysisContext context,
+ String file,
+ LineInfo lineInfo,
+ List<AnalysisError> errors) {
_sendNotification(server, () {
if (errors == null) {
errors = <AnalysisError>[];
}
var serverErrors =
- protocol.doAnalysisError_listFromEngine(lineInfo, errors);
+ protocol.doAnalysisError_listFromEngine(context, lineInfo, errors);
var params = new protocol.AnalysisErrorsParams(file, serverErrors);
server.sendNotification(params.toNotification());
});
@@ -422,16 +425,6 @@
server.sendServerErrorNotification(
'Failed to index Dart file: $file', exception, stackTrace);
}
- // HTML
- try {
- HtmlUnit htmlUnit = notice.resolvedHtmlUnit;
- if (htmlUnit != null) {
- server.addOperation(new _HtmlIndexOperation(context, file, htmlUnit));
- }
- } catch (exception, stackTrace) {
- server.sendServerErrorNotification(
- 'Failed to index HTML file: $file', exception, stackTrace);
- }
}
}
}
@@ -510,24 +503,6 @@
}
}
-class _HtmlIndexOperation extends _SingleFileOperation {
- final HtmlUnit unit;
-
- _HtmlIndexOperation(AnalysisContext context, String file, this.unit)
- : super(context, file);
-
- @override
- ServerOperationPriority get priority {
- return ServerOperationPriority.ANALYSIS_INDEX;
- }
-
- @override
- void perform(AnalysisServer server) {
- Index index = server.index;
- index.index(context, unit);
- }
-}
-
class _NotificationErrorsOperation extends _SingleFileOperation {
final LineInfo lineInfo;
final List<AnalysisError> errors;
@@ -543,7 +518,7 @@
@override
void perform(AnalysisServer server) {
- sendAnalysisNotificationErrors(server, file, lineInfo, errors);
+ sendAnalysisNotificationErrors(server, context, file, lineInfo, errors);
}
}
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index 678361f..981b694 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -9,6 +9,7 @@
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/services/search/search_engine.dart'
as engine;
+import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/generated/ast.dart' as engine;
import 'package:analyzer/src/generated/element.dart' as engine;
import 'package:analyzer/src/generated/engine.dart' as engine;
@@ -20,14 +21,29 @@
export 'package:analysis_server/plugin/protocol/protocol_dart.dart';
/**
- * Returns a list of AnalysisErrors correponding to the given list of Engine
+ * Returns a list of AnalysisErrors corresponding to the given list of Engine
* errors.
*/
List<AnalysisError> doAnalysisError_listFromEngine(
- engine.LineInfo lineInfo, List<engine.AnalysisError> errors) {
- return errors.map((engine.AnalysisError error) {
- return newAnalysisError_fromEngine(lineInfo, error);
- }).toList();
+ engine.AnalysisContext context,
+ engine.LineInfo lineInfo,
+ List<engine.AnalysisError> errors) {
+ List<AnalysisError> serverErrors = <AnalysisError>[];
+ for (engine.AnalysisError error in errors) {
+ ErrorProcessor processor = ErrorProcessor.getProcessor(context, error);
+ if (processor != null) {
+ engine.ErrorSeverity severity = processor.severity;
+ // Errors with null severity are filtered out.
+ if (severity != null) {
+ // Specified severities override.
+ serverErrors
+ .add(newAnalysisError_fromEngine(lineInfo, error, severity));
+ }
+ } else {
+ serverErrors.add(newAnalysisError_fromEngine(lineInfo, error));
+ }
+ }
+ return serverErrors;
}
/**
@@ -55,7 +71,7 @@
if (element.kind == engine.ElementKind.SETTER) {
return null;
} else {
- return element.returnType.toString();
+ return element.returnType?.toString();
}
} else if (element is engine.VariableElement) {
engine.DartType type = element.type;
@@ -69,9 +85,12 @@
/**
* Construct based on error information from the analyzer engine.
+ *
+ * If an [errorSeverity] is specified, it will override the one in [error].
*/
AnalysisError newAnalysisError_fromEngine(
- engine.LineInfo lineInfo, engine.AnalysisError error) {
+ engine.LineInfo lineInfo, engine.AnalysisError error,
+ [engine.ErrorSeverity errorSeverity]) {
engine.ErrorCode errorCode = error.errorCode;
// prepare location
Location location;
@@ -90,8 +109,12 @@
}
location = new Location(file, offset, length, startLine, startColumn);
}
+
+ // Deafult to the error's severity if none is specified.
+ errorSeverity ??= errorCode.errorSeverity;
+
// done
- var severity = new AnalysisErrorSeverity(errorCode.errorSeverity.name);
+ var severity = new AnalysisErrorSeverity(errorSeverity.name);
var type = new AnalysisErrorType(errorCode.type.name);
String message = error.message;
String correction = error.correction;
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
index 816894d..827024b 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
@@ -10,6 +10,8 @@
import 'package:analysis_server/src/provisional/completion/completion_core.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/source.dart';
export 'package:analysis_server/src/provisional/completion/completion_core.dart'
show EMPTY_LIST;
@@ -60,27 +62,61 @@
*/
abstract class DartCompletionRequest extends CompletionRequest {
/**
+ * Return the expression to the right of the "dot" or "dot dot",
+ * or `null` if this is not a "dot" completion (e.g. `foo.b`).
+ */
+ Expression get dotTarget;
+
+ /**
+ * Return `true` if free standing identifiers should be suggested
+ */
+ bool get includeIdentifiers;
+
+ /**
+ * Return the library element which contains the unit in which the completion
+ * is occurring. This may return `null` if the library cannot be determined
+ * (e.g. unlinked part file).
+ */
+ LibraryElement get libraryElement;
+
+ /**
+ * The source for the library containing the completion request.
+ * This may be different from the source in which the completion is requested
+ * if the completion is being requested in a part file.
+ * This may be `null` if the library for a part file cannot be determined.
+ */
+ Source get librarySource;
+
+ /**
+ * Answer the [DartType] for Object in dart:core
+ */
+ DartType get objectType;
+
+ /**
* Return the completion target. This determines what part of the parse tree
* will receive the newly inserted text.
+ * At a minimum, all declarations in the completion scope in [target.unit]
+ * will be resolved if they can be resolved.
*/
CompletionTarget get target;
/**
- * Return a [Future] that completes with a compilation unit in which
- * all declarations in all scopes containing [target] have been resolved.
- * The [Future] may return `null` if the unit cannot be resolved
+ * Return a [Future] that completes with a list of directives for the library
+ * in which in which the completion is occurring.
+ * The [Future] may return `null` if the library unit cannot be determined
* (e.g. unlinked part file).
* Any information obtained from [target] prior to calling this method
* should be discarded as it may have changed.
*/
- Future<CompilationUnit> resolveDeclarationsInScope();
+ Future<List<Directive>> resolveDirectives();
/**
* Return a [Future] that completes when the element associated with
- * the given [identifier] is available or if the identifier cannot be resolved
+ * the given [expression] in the target compilation unit is available.
+ * It may also complete if the expression cannot be resolved
* (e.g. unknown identifier, completion aborted, etc).
* Any information obtained from [target] prior to calling this method
* should be discarded as it may have changed.
*/
- Future resolveIdentifier(SimpleIdentifier identifier);
+ Future resolveExpression(Expression expression);
}
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart
index 014c270..64fecef 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart
@@ -12,6 +12,11 @@
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/library_member_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/library_prefix_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/named_constructor_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/static_member_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/type_member_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart';
import 'package:plugin/plugin.dart';
@@ -77,6 +82,16 @@
registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
() => new KeywordContributor());
registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+ () => new LibraryMemberContributor());
+ registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+ () => new LibraryPrefixContributor());
+ registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+ () => new NamedConstructorContributor());
+ registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+ () => new StaticMemberContributor());
+ registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+ () => new TypeMemberContributor());
+ registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
() => new UriContributor());
}
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
index 0cb0035..7762e9e 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
@@ -91,6 +91,11 @@
final CompilationUnit unit;
/**
+ * The offset within the source at which the completion is being requested.
+ */
+ final int offset;
+
+ /**
* The context in which the completion is occurring. This is the AST node
* which is a direct parent of [entity].
*/
@@ -162,11 +167,11 @@
Token commentToken = _getContainingCommentToken(entity, offset);
if (commentToken != null) {
return new CompletionTarget._(
- compilationUnit, containingNode, commentToken, true);
+ compilationUnit, offset, containingNode, commentToken, true);
}
// Target found.
return new CompletionTarget._(
- compilationUnit, containingNode, entity, false);
+ compilationUnit, offset, containingNode, entity, false);
} else {
// Since entity is a token, we don't need to look inside it; just
// proceed to the next entity.
@@ -195,12 +200,12 @@
if (docComment != null) {
containingNode = docComment;
} else {
- return new CompletionTarget._(
- compilationUnit, compilationUnit, commentToken, true);
+ return new CompletionTarget._(compilationUnit, offset,
+ compilationUnit, commentToken, true);
}
}
return new CompletionTarget._(
- compilationUnit, containingNode, entity, false);
+ compilationUnit, offset, containingNode, entity, false);
}
// Otherwise, the completion target is somewhere inside the entity,
@@ -225,7 +230,7 @@
// Since no completion target was found, we set the completion target
// entity to null and use the compilationUnit as the parent.
return new CompletionTarget._(
- compilationUnit, compilationUnit, null, false);
+ compilationUnit, offset, compilationUnit, null, false);
}
}
@@ -233,13 +238,30 @@
* Create a [CompletionTarget] holding the given [containingNode] and
* [entity].
*/
- CompletionTarget._(
- this.unit, AstNode containingNode, Object entity, this.isCommentText)
+ CompletionTarget._(this.unit, this.offset, AstNode containingNode,
+ Object entity, this.isCommentText)
: this.containingNode = containingNode,
this.entity = entity,
this.argIndex = _computeArgIndex(containingNode, entity);
/**
+ * Return `true` if the [containingNode] is a cascade
+ * and the completion insertion is not between the two dots.
+ * For example, `..d^` and `..^d` are considered a cascade
+ * from a completion standpoint, but `.^.d` is not.
+ */
+ bool get isCascade {
+ AstNode node = containingNode;
+ if (node is PropertyAccess) {
+ return node.isCascaded && offset > node.operator.offset + 1;
+ }
+ if (node is MethodInvocation) {
+ return node.isCascaded && offset > node.operator.offset + 1;
+ }
+ return false;
+ }
+
+ /**
* Return `true` if the target is a functional argument in an argument list.
* The target [AstNode] hierarchy *must* be resolved for this to work.
*/
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 27fb203..5833af4 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -27,6 +27,7 @@
import 'package:analyzer/src/generated/sdk_io.dart';
import 'package:args/args.dart';
import 'package:linter/src/plugin/linter_plugin.dart';
+import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
/**
@@ -208,11 +209,6 @@
static const String CLIENT_VERSION = "client-version";
/**
- * The name of the option used to disable the use of the new task model.
- */
- static const String DISABLE_NEW_TASK_MODEL = "disable-new-task-model";
-
- /**
* The name of the option used to enable incremental resolution of API
* changes.
*/
@@ -398,25 +394,21 @@
results[CLIENT_VERSION], AnalysisServer.VERSION, defaultSdk.sdkVersion);
AnalysisEngine.instance.instrumentationService = service;
//
- // Enable the new task model, if appropriate.
- //
- AnalysisEngine.instance.useTaskModel = !results[DISABLE_NEW_TASK_MODEL];
- //
// Process all of the plugins so that extensions are registered.
//
ServerPlugin serverPlugin = new ServerPlugin();
List<Plugin> plugins = <Plugin>[];
+ plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+ plugins.add(AnalysisEngine.instance.commandLinePlugin);
+ plugins.add(AnalysisEngine.instance.optionsPlugin);
plugins.add(serverPlugin);
- plugins.addAll(_userDefinedPlugins);
plugins.add(linterPlugin);
plugins.add(linterServerPlugin);
plugins.add(dartCompletionPlugin);
+ plugins.addAll(_userDefinedPlugins);
- // Defer to the extension manager in AE for plugin registration.
- AnalysisEngine.instance.userDefinedPlugins = plugins;
- // Force registration.
- AnalysisEngine.instance.taskManager;
-
+ ExtensionManager manager = new ExtensionManager();
+ manager.processPlugins(plugins);
//
// Create the sockets and start listening for requests.
//
@@ -480,11 +472,6 @@
parser.addOption(CLIENT_ID,
help: "an identifier used to identify the client");
parser.addOption(CLIENT_VERSION, help: "the version of the client");
- parser.addFlag(DISABLE_NEW_TASK_MODEL,
- help: "disable the use of the new task model",
- defaultsTo: false,
- hide: true,
- negatable: false);
parser.addFlag(ENABLE_INCREMENTAL_RESOLUTION_API,
help: "enable using incremental resolution for API changes",
defaultsTo: false,
diff --git a/pkg/analysis_server/lib/src/server/http_server.dart b/pkg/analysis_server/lib/src/server/http_server.dart
index c047d1f..9afabda 100644
--- a/pkg/analysis_server/lib/src/server/http_server.dart
+++ b/pkg/analysis_server/lib/src/server/http_server.dart
@@ -2,16 +2,14 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library http.server;
+library analysis_server.src.server.http_server;
import 'dart:async';
import 'dart:io';
import 'package:analysis_server/src/channel/web_socket_channel.dart';
-import 'package:analysis_server/src/get_handler.dart';
import 'package:analysis_server/src/socket_server.dart';
-import 'package:analysis_server/src/status/get_handler.dart' as newHandler;
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analysis_server/src/status/get_handler.dart';
/**
* Instances of the class [HttpServer] implement a simple HTTP server. The
@@ -36,11 +34,6 @@
GetHandler getHandler;
/**
- * An object that can handle GET requests when the new task model is in use.
- */
- newHandler.GetHandler newGetHandler;
-
- /**
* Future that is completed with the HTTP server once it is running.
*/
Future<HttpServer> _server;
@@ -89,17 +82,10 @@
* Handle a GET request received by the HTTP server.
*/
void _handleGetRequest(HttpRequest request) {
- if (AnalysisEngine.instance.useTaskModel) {
- if (newGetHandler == null) {
- newGetHandler = new newHandler.GetHandler(socketServer, _printBuffer);
- }
- newGetHandler.handleGetRequest(request);
- } else {
- if (getHandler == null) {
- getHandler = new GetHandler(socketServer, _printBuffer);
- }
- getHandler.handleGetRequest(request);
+ if (getHandler == null) {
+ getHandler = new GetHandler(socketServer, _printBuffer);
}
+ getHandler.handleGetRequest(request);
}
/**
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
index 46e20aa..29f463b 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
@@ -87,6 +87,23 @@
}
/**
+ * Determine if the completion target is the label for a named argument.
+ */
+bool _isEditingNamedArgLabel(DartCompletionRequest request) {
+ AstNode node = request.target.containingNode;
+ if (node is ArgumentList) {
+ var entity = request.target.entity;
+ if (entity is NamedExpression) {
+ int offset = request.offset;
+ if (entity.offset <= offset && offset < entity.end) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+/**
* Determine if the completion target is an emtpy argument list.
*/
bool _isEmptyArgList(DartCompletionRequest request) {
@@ -134,7 +151,7 @@
}
// Resolve the target expression to determine the arguments
- await request.resolveIdentifier(targetId);
+ await request.resolveExpression(targetId);
// Gracefully degrade if the element could not be resolved
// e.g. target changed, completion aborted
targetId = _getTargetId(request.target.containingNode);
@@ -171,32 +188,35 @@
}
void _addArgListSuggestion(Iterable<ParameterElement> requiredParam) {
- StringBuffer completion = new StringBuffer('(');
- List<String> paramNames = new List<String>();
- List<String> paramTypes = new List<String>();
- for (ParameterElement param in requiredParam) {
- String name = param.name;
- if (name != null && name.length > 0) {
- if (completion.length > 1) {
- completion.write(', ');
- }
- completion.write(name);
- paramNames.add(name);
- paramTypes.add(_getParamType(param));
- }
- }
- completion.write(')');
- CompletionSuggestion suggestion = new CompletionSuggestion(
- CompletionSuggestionKind.ARGUMENT_LIST,
- DART_RELEVANCE_HIGH,
- completion.toString(),
- completion.length,
- 0,
- false,
- false);
- suggestion.parameterNames = paramNames;
- suggestion.parameterTypes = paramTypes;
- suggestions.add(suggestion);
+ // DEPRECATED... argument lists are no longer suggested.
+ // See https://github.com/dart-lang/sdk/issues/25197
+
+ // StringBuffer completion = new StringBuffer('(');
+ // List<String> paramNames = new List<String>();
+ // List<String> paramTypes = new List<String>();
+ // for (ParameterElement param in requiredParam) {
+ // String name = param.name;
+ // if (name != null && name.length > 0) {
+ // if (completion.length > 1) {
+ // completion.write(', ');
+ // }
+ // completion.write(name);
+ // paramNames.add(name);
+ // paramTypes.add(_getParamType(param));
+ // }
+ // }
+ // completion.write(')');
+ // CompletionSuggestion suggestion = new CompletionSuggestion(
+ // CompletionSuggestionKind.ARGUMENT_LIST,
+ // DART_RELEVANCE_HIGH,
+ // completion.toString(),
+ // completion.length,
+ // 0,
+ // false,
+ // false);
+ // suggestion.parameterNames = paramNames;
+ // suggestion.parameterTypes = paramTypes;
+ // suggestions.add(suggestion);
}
void _addDefaultParamSuggestions(Iterable<ParameterElement> parameters) {
@@ -233,7 +253,7 @@
_addArgListSuggestion(requiredParam);
return;
}
- if (_isAppendingToArgList(request)) {
+ if (_isEditingNamedArgLabel(request) || _isAppendingToArgList(request)) {
if (requiredCount == 0 || requiredCount < _argCount(request)) {
_addDefaultParamSuggestions(parameters);
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
index cba3bd4..a08b8bb 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
@@ -26,20 +26,6 @@
return EMPTY_LIST;
}
- // Partially resolve the compilation unit
- CompilationUnit unit = await request.resolveDeclarationsInScope();
- // Gracefully degrade if the compilation unit could not be resolved
- // e.g. detached part file or source change
- if (unit == null) {
- return EMPTY_LIST;
- }
-
- // Check the target since resolution may have changed it
- node = request.target.containingNode;
- if (node is! Combinator) {
- return EMPTY_LIST;
- }
-
// Build list of suggestions
var directive = node.getAncestor((parent) => parent is NamespaceDirective);
if (directive is NamespaceDirective) {
@@ -47,7 +33,7 @@
if (library != null) {
LibraryElementSuggestionBuilder builder =
new LibraryElementSuggestionBuilder(
- request, CompletionSuggestionKind.IDENTIFIER, false, false);
+ library, CompletionSuggestionKind.IDENTIFIER, false, false);
library.visitChildren(builder);
return builder.suggestions;
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index 6f182d8..a635b8c 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -18,10 +18,12 @@
import 'package:analyzer/src/context/context.dart'
show AnalysisFutureHelper, AnalysisContextImpl;
import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/engine.dart' hide AnalysisContextImpl;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/task/dart.dart';
+import 'package:analysis_server/src/services/completion/optype.dart';
/**
* [DartCompletionManager] determines if a completion request is Dart specific
@@ -30,24 +32,17 @@
class DartCompletionManager implements CompletionContributor {
@override
Future<List<CompletionSuggestion>> computeSuggestions(
- CompletionRequest request) {
- if (AnalysisEngine.isDartFileName(request.source.shortName)) {
- return _computeDartSuggestions(
- new DartCompletionRequestImpl.forRequest(request));
+ CompletionRequest request) async {
+ if (!AnalysisEngine.isDartFileName(request.source.shortName)) {
+ return EMPTY_LIST;
}
- return new Future.value();
- }
- /**
- * Return a [Future] that completes with a list of suggestions
- * for the given completion [request].
- */
- Future<List<CompletionSuggestion>> _computeDartSuggestions(
- DartCompletionRequest request) async {
// Request Dart specific completions from each contributor
+ DartCompletionRequestImpl dartRequest =
+ await DartCompletionRequestImpl.from(request);
List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
for (DartCompletionContributor c in dartCompletionPlugin.contributors) {
- suggestions.addAll(await c.computeSuggestions(request));
+ suggestions.addAll(await c.computeSuggestions(dartRequest));
}
return suggestions;
}
@@ -59,115 +54,139 @@
class DartCompletionRequestImpl extends CompletionRequestImpl
implements DartCompletionRequest {
/**
- * The cached completion target or `null` if not computed yet.
+ * Return a [Future] that completes with a newly created completion request
+ * based on the given [request].
*/
- CompletionTarget _target;
+ static Future<DartCompletionRequest> from(CompletionRequest request) async {
+ Source source = request.source;
+ AnalysisContext context = request.context;
+ CompilationUnit unit = request.context.computeResult(source, PARSED_UNIT);
- /**
- * `true` if [resolveDeclarationsInScope] has partially resolved the unit
- * referenced by [target], else `false`.
- */
- bool _haveResolveDeclarationsInScope = false;
+ Source libSource;
+ if (unit.directives.any((d) => d is PartOfDirective)) {
+ List<Source> libraries = context.getLibrariesContaining(source);
+ if (libraries.isNotEmpty) {
+ libSource = libraries[0];
+ }
+ } else {
+ libSource = source;
+ }
- /**
- * Initialize a newly created completion request based on the given request.
- */
- factory DartCompletionRequestImpl.forRequest(CompletionRequest request) {
+ // Most (all?) contributors need declarations in scope to be resolved
+ if (libSource != null) {
+ unit = await new AnalysisFutureHelper<CompilationUnit>(context,
+ new LibrarySpecificUnit(libSource, source), RESOLVED_UNIT3)
+ .computeAsync();
+ }
+
return new DartCompletionRequestImpl._(
request.context,
request.resourceProvider,
request.searchEngine,
+ libSource,
request.source,
- request.offset);
+ request.offset,
+ unit);
}
DartCompletionRequestImpl._(
AnalysisContext context,
ResourceProvider resourceProvider,
SearchEngine searchEngine,
+ this.librarySource,
Source source,
- int offset)
- : super(context, resourceProvider, searchEngine, source, offset);
+ int offset,
+ CompilationUnit unit)
+ : super(context, resourceProvider, searchEngine, source, offset) {
+ _updateTargets(unit);
+ }
+
+ /**
+ * The [DartType] for Object in dart:core
+ */
+ InterfaceType _objectType;
@override
- CompletionTarget get target {
- if (_target == null) {
- CompilationUnit unit = context.computeResult(source, PARSED_UNIT);
- _target = new CompletionTarget.forOffset(unit, offset);
+ Expression dotTarget;
+
+ @override
+ Source librarySource;
+
+ OpType _opType;
+
+ @override
+ CompletionTarget target;
+
+ @override
+ bool get includeIdentifiers {
+ if (_opType == null) {
+ _opType = new OpType.forCompletion(target, offset);
}
- return _target;
+ return !_opType.isPrefixed &&
+ (_opType.includeReturnValueSuggestions ||
+ _opType.includeTypeNameSuggestions ||
+ _opType.includeVoidReturnSuggestions ||
+ _opType.includeConstructorSuggestions);
}
@override
- Future<CompilationUnit> resolveDeclarationsInScope() async {
+ LibraryElement get libraryElement {
+ //TODO(danrubel) build the library element rather than all the declarations
CompilationUnit unit = target.unit;
- if (_haveResolveDeclarationsInScope) {
- return unit;
- }
-
- // Determine the library source
- Source librarySource;
- if (unit.directives.any((d) => d is PartOfDirective)) {
- List<Source> libraries = context.getLibrariesContaining(source);
- if (libraries.isEmpty) {
- return null;
+ if (unit != null) {
+ CompilationUnitElement elem = unit.element;
+ if (elem != null) {
+ return elem.library;
}
- librarySource = libraries[0];
- } else {
- librarySource = source;
}
-
- // Resolve declarations in the target unit
- CompilationUnit resolvedUnit =
- await new AnalysisFutureHelper<CompilationUnit>(
- context,
- new LibrarySpecificUnit(librarySource, source),
- RESOLVED_UNIT3).computeAsync();
-
- // TODO(danrubel) determine if the underlying source has been modified
- // in a way that invalidates the completion request
- // and return null
-
- // Gracefully degrade if unit cannot be resolved
- if (resolvedUnit == null) {
- return null;
- }
-
- // Recompute the target for the newly resolved unit
- _target = new CompletionTarget.forOffset(resolvedUnit, offset);
- _haveResolveDeclarationsInScope = true;
- return resolvedUnit;
+ return null;
}
@override
- Future resolveIdentifier(SimpleIdentifier identifier) async {
- if (identifier.bestElement != null) {
+ InterfaceType get objectType {
+ if (_objectType == null) {
+ Source coreUri = context.sourceFactory.forUri('dart:core');
+ LibraryElement coreLib = context.getLibraryElement(coreUri);
+ _objectType = coreLib.getType('Object').type;
+ }
+ return _objectType;
+ }
+
+ @override
+ Future<List<Directive>> resolveDirectives() async {
+ CompilationUnit libUnit;
+ if (librarySource == source) {
+ libUnit = target.unit;
+ } else if (librarySource != null) {
+ // TODO(danrubel) only resolve the directives
+ libUnit = await new AnalysisFutureHelper<CompilationUnit>(
+ context,
+ new LibrarySpecificUnit(librarySource, librarySource),
+ RESOLVED_UNIT3)
+ .computeAsync();
+ }
+ return libUnit?.directives;
+ }
+
+ @override
+ Future resolveExpression(Expression expression) async {
+ // Return immediately if the expression has already been resolved
+ if (expression.propagatedType != null) {
return;
}
- //TODO(danrubel) resolve the expression or containing method
+ // Gracefully degrade if librarySource cannot be determined
+ if (librarySource == null) {
+ return;
+ }
+
+ // Resolve declarations in the target unit
+ // TODO(danrubel) resolve the expression or containing method
// rather than the entire complilation unit
-
- CompilationUnit unit = target.unit;
-
- // Determine the library source
- Source librarySource;
- if (unit.directives.any((d) => d is PartOfDirective)) {
- List<Source> libraries = context.getLibrariesContaining(source);
- if (libraries.isEmpty) {
- return;
- }
- librarySource = libraries[0];
- } else {
- librarySource = source;
- }
-
- // Resolve declarations in the target unit
CompilationUnit resolvedUnit =
- await new AnalysisFutureHelper<CompilationUnit>(
- context,
- new LibrarySpecificUnit(librarySource, source),
- RESOLVED_UNIT).computeAsync();
+ await new AnalysisFutureHelper<CompilationUnit>(context,
+ new LibrarySpecificUnit(librarySource, source), RESOLVED_UNIT)
+ .computeAsync();
// TODO(danrubel) determine if the underlying source has been modified
// in a way that invalidates the completion request
@@ -179,7 +198,35 @@
}
// Recompute the target for the newly resolved unit
- _target = new CompletionTarget.forOffset(resolvedUnit, offset);
- _haveResolveDeclarationsInScope = true;
+ _updateTargets(resolvedUnit);
+ }
+
+ /**
+ * Update the completion [target] and [dotTarget] based on the given [unit].
+ */
+ void _updateTargets(CompilationUnit unit) {
+ _opType = null;
+ dotTarget = null;
+ target = new CompletionTarget.forOffset(unit, offset);
+ AstNode node = target.containingNode;
+ if (node is MethodInvocation) {
+ if (identical(node.methodName, target.entity)) {
+ dotTarget = node.realTarget;
+ } else if (node.isCascaded && node.operator.offset + 1 == target.offset) {
+ dotTarget = node.realTarget;
+ }
+ }
+ if (node is PropertyAccess) {
+ if (identical(node.propertyName, target.entity)) {
+ dotTarget = node.realTarget;
+ } else if (node.isCascaded && node.operator.offset + 1 == target.offset) {
+ dotTarget = node.realTarget;
+ }
+ }
+ if (node is PrefixedIdentifier) {
+ if (identical(node.identifier, target.entity)) {
+ dotTarget = node.prefix;
+ }
+ }
}
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
index f708685..3c16a7d 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
@@ -20,19 +20,6 @@
@override
Future<List<CompletionSuggestion>> computeSuggestions(
DartCompletionRequest request) async {
- if (request.target.containingNode is! FieldFormalParameter) {
- return EMPTY_LIST;
- }
-
- // Partially resolve the compilation unit
- CompilationUnit unit = await request.resolveDeclarationsInScope();
- // Gracefully degrade if the compilation unit could not be resolved
- // e.g. detached part file or source change
- if (unit == null) {
- return EMPTY_LIST;
- }
-
- // Recompute the target since resolution may have changed it
AstNode node = request.target.containingNode;
if (node is! FieldFormalParameter) {
return EMPTY_LIST;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/inherited_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/inherited_contributor.dart
index fdfb353..2ab41e3 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/inherited_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/inherited_contributor.dart
@@ -26,26 +26,10 @@
@override
Future<List<CompletionSuggestion>> computeSuggestions(
DartCompletionRequest request) async {
- // Determine if the target looks like a partial identifier
- // inside a class declaration
SimpleIdentifier targetId = _getTargetId(request.target);
if (targetId == null) {
return EMPTY_LIST;
}
-
- // Partially resolve the compilation unit
- CompilationUnit unit = await request.resolveDeclarationsInScope();
- // Gracefully degrade if the compilation unit could not be resolved
- // e.g. detached part file or source change
- if (unit == null) {
- return EMPTY_LIST;
- }
-
- // Recompute the target since resolution may have changed it
- targetId = _getTargetId(request.target);
- if (targetId == null) {
- return EMPTY_LIST;
- }
ClassDeclaration classDecl =
targetId.getAncestor((p) => p is ClassDeclaration);
if (classDecl == null) {
@@ -65,7 +49,7 @@
// Gracefully degrade if the overridden element has not been resolved.
if (element.returnType != null) {
CompletionSuggestion suggestion =
- _buildSuggestion(request, targetId, unit, element);
+ _buildSuggestion(request, targetId, element);
if (suggestion != null) {
suggestions.add(suggestion);
}
@@ -119,13 +103,10 @@
* Build a suggestion to replace [targetId] in the given [unit]
* with an override of the given [element].
*/
- CompletionSuggestion _buildSuggestion(
- DartCompletionRequest request,
- SimpleIdentifier targetId,
- CompilationUnit unit,
- ExecutableElement element) {
- String completion =
- _buildRepacementText(request.source, targetId, unit, element);
+ CompletionSuggestion _buildSuggestion(DartCompletionRequest request,
+ SimpleIdentifier targetId, ExecutableElement element) {
+ String completion = _buildRepacementText(
+ request.source, targetId, request.target.unit, element);
if (completion == null || completion.length == 0) {
return null;
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 57beb27..28de09b 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -13,7 +13,11 @@
import 'package:analyzer/src/generated/scanner.dart';
const ASYNC = 'async';
+const ASYNC_STAR = 'async*';
const AWAIT = 'await';
+const SYNC_STAR = 'sync*';
+const YIELD = 'yield';
+const YIELD_STAR = 'yield*';
/**
* A contributor for calculating `completion.getSuggestions` request results
@@ -47,8 +51,19 @@
@override
visitArgumentList(ArgumentList node) {
- if (entity == node.rightParenthesis ||
- (entity is SimpleIdentifier && node.arguments.contains(entity))) {
+ if (entity == node.rightParenthesis) {
+ _addExpressionKeywords(node);
+ Token previous = (entity as Token).previous;
+ if (previous.isSynthetic) {
+ previous = previous.previous;
+ }
+ if (previous.lexeme == ')') {
+ _addSuggestion2(ASYNC);
+ _addSuggestion2(ASYNC_STAR);
+ _addSuggestion2(SYNC_STAR);
+ }
+ }
+ if (entity is SimpleIdentifier && node.arguments.contains(entity)) {
_addExpressionKeywords(node);
}
}
@@ -69,6 +84,8 @@
}
if (previous.lexeme == ')' && next.lexeme == '{') {
_addSuggestion2(ASYNC);
+ _addSuggestion2(ASYNC_STAR);
+ _addSuggestion2(SYNC_STAR);
}
}
}
@@ -92,6 +109,8 @@
ClassMember previous = index > 0 ? node.members[index - 1] : null;
if (previous is MethodDeclaration && previous.body is EmptyFunctionBody) {
_addSuggestion2(ASYNC);
+ _addSuggestion2(ASYNC_STAR);
+ _addSuggestion2(SYNC_STAR);
}
} else {
_addClassDeclarationKeywords(node);
@@ -138,6 +157,8 @@
previousMember.functionExpression is FunctionExpression &&
previousMember.functionExpression.body is EmptyFunctionBody) {
_addSuggestion2(ASYNC, relevance: DART_RELEVANCE_HIGH);
+ _addSuggestion2(ASYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+ _addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH);
}
_addCompilationUnitKeywords();
}
@@ -200,8 +221,13 @@
@override
visitFunctionExpression(FunctionExpression node) {
if (entity == node.body) {
- if (!node.body.isAsynchronous) {
+ FunctionBody body = node.body;
+ if (!body.isAsynchronous) {
_addSuggestion2(ASYNC, relevance: DART_RELEVANCE_HIGH);
+ if (body is! ExpressionFunctionBody) {
+ _addSuggestion2(ASYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+ _addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+ }
}
if (node.body is EmptyFunctionBody &&
node.parent is FunctionDeclaration &&
@@ -266,8 +292,14 @@
if (node.body is EmptyFunctionBody) {
_addClassBodyKeywords();
_addSuggestion2(ASYNC);
+ _addSuggestion2(ASYNC_STAR);
+ _addSuggestion2(SYNC_STAR);
} else {
_addSuggestion2(ASYNC, relevance: DART_RELEVANCE_HIGH);
+ if (node.body is! ExpressionFunctionBody) {
+ _addSuggestion2(ASYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+ _addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+ }
}
}
}
@@ -433,6 +465,10 @@
}
if (_inAsyncMethodOrFunction(node)) {
_addSuggestion2(AWAIT);
+ } else if (_inAsyncStarOrSyncStarMethodOrFunction(node)) {
+ _addSuggestion2(AWAIT);
+ _addSuggestion2(YIELD);
+ _addSuggestion2(YIELD_STAR);
}
if (_inLoop(node)) {
_addSuggestions([Keyword.BREAK, Keyword.CONTINUE]);
@@ -481,7 +517,12 @@
bool _inAsyncMethodOrFunction(AstNode node) {
FunctionBody body = node.getAncestor((n) => n is FunctionBody);
- return body != null && body.isAsynchronous;
+ return body != null && body.isAsynchronous && body.star == null;
+ }
+
+ bool _inAsyncStarOrSyncStarMethodOrFunction(AstNode node) {
+ FunctionBody body = node.getAncestor((n) => n is FunctionBody);
+ return body != null && body.keyword != null && body.star != null;
}
bool _inCatchClause(Block node) =>
@@ -506,7 +547,7 @@
bool _inForLoop(AstNode node) =>
node.getAncestor((p) => p is ForStatement || p is ForEachStatement) !=
- null;
+ null;
bool _inLoop(AstNode node) =>
_inDoLoop(node) || _inForLoop(node) || _inWhileLoop(node);
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
new file mode 100644
index 0000000..7ecbc64
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
@@ -0,0 +1,90 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library services.completion.contributor.dart.library_member;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+
+import '../../../protocol_server.dart'
+ show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating prefixed import library member suggestions
+ * `completion.getSuggestions` request results.
+ */
+class LibraryMemberContributor extends DartCompletionContributor {
+ @override
+ Future<List<CompletionSuggestion>> computeSuggestions(
+ DartCompletionRequest request) async {
+ // Determine if the target looks like a library prefix
+ if (request.dotTarget is! SimpleIdentifier) {
+ return EMPTY_LIST;
+ }
+
+ // Resolve the expression and the containing library
+ await request.resolveExpression(request.dotTarget);
+
+ // Recompute the target since resolution may have changed it
+ Expression targetId = request.dotTarget;
+ if (targetId is SimpleIdentifier && !request.target.isCascade) {
+ Element elem = targetId.bestElement;
+ if (elem is PrefixElement) {
+ List<Directive> directives = await request.resolveDirectives();
+ LibraryElement containingLibrary = request.libraryElement;
+ // Gracefully degrade if the library or directives
+ // could not be determined (e.g. detached part file or source change)
+ if (containingLibrary != null && directives != null) {
+ return _buildSuggestions(
+ request, elem, containingLibrary, directives);
+ }
+ }
+ }
+ return EMPTY_LIST;
+ }
+
+ List<CompletionSuggestion> _buildSuggestions(
+ DartCompletionRequest request,
+ PrefixElement elem,
+ LibraryElement containingLibrary,
+ List<Directive> directives) {
+ List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+ for (Directive directive in directives) {
+ if (directive is ImportDirective) {
+ if (directive.prefix != null) {
+ if (directive.prefix.name == elem.name) {
+ LibraryElement library = directive.uriElement;
+
+ // Suggest elements from the imported library
+ if (library != null) {
+ AstNode parent = request.target.containingNode.parent;
+ bool isConstructor = parent.parent is ConstructorName;
+ bool typesOnly = parent is TypeName;
+ bool instCreation = typesOnly && isConstructor;
+ LibraryElementSuggestionBuilder builder =
+ new LibraryElementSuggestionBuilder(
+ containingLibrary,
+ CompletionSuggestionKind.INVOCATION,
+ typesOnly,
+ instCreation);
+ library.visitChildren(builder);
+ suggestions.addAll(builder.suggestions);
+
+ // If the import is 'deferred' then suggest 'loadLibrary'
+ if (directive.deferredKeyword != null) {
+ FunctionElement loadLibFunct = library.loadLibraryFunction;
+ suggestions.add(createSuggestion(loadLibFunct));
+ }
+ }
+ }
+ }
+ }
+ }
+ return suggestions;
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
new file mode 100644
index 0000000..791c122
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library services.completion.contributor.dart.library_prefix;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+
+import '../../../protocol_server.dart'
+ show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating prefixed import library member suggestions
+ * `completion.getSuggestions` request results.
+ */
+class LibraryPrefixContributor extends DartCompletionContributor {
+ @override
+ Future<List<CompletionSuggestion>> computeSuggestions(
+ DartCompletionRequest request) async {
+ if (!request.includeIdentifiers) {
+ return EMPTY_LIST;
+ }
+
+ List<Directive> directives = await request.resolveDirectives();
+ if (directives == null) {
+ return EMPTY_LIST;
+ }
+
+ List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+ for (Directive directive in directives) {
+ if (directive is ImportDirective) {
+ SimpleIdentifier prefix = directive.prefix;
+ ImportElement element = directive.element;
+ if (prefix != null && element != null) {
+ String completion = prefix.name;
+ LibraryElement libElem = element.importedLibrary;
+ if (completion != null && completion.length > 0 && libElem != null) {
+ CompletionSuggestion suggestion = createSuggestion(libElem,
+ completion: completion,
+ kind: CompletionSuggestionKind.IDENTIFIER);
+ if (suggestion != null) {
+ suggestions.add(suggestion);
+ }
+ }
+ }
+ }
+ }
+ return suggestions;
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
new file mode 100644
index 0000000..86640d9
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
@@ -0,0 +1,83 @@
+// 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 services.completion.contributor.dart.named_constructor;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+
+/**
+ * A contributor for calculating named constructor suggestions
+ * such as suggesting `bar` in `new Foo.bar()`.
+ */
+class NamedConstructorContributor extends DartCompletionContributor {
+ @override
+ Future<List<CompletionSuggestion>> computeSuggestions(
+ DartCompletionRequest request) async {
+ // Determine if the target looks like a named constructor.
+ AstNode parsedNode = request.target.containingNode;
+ SimpleIdentifier targetId;
+ if (parsedNode is ConstructorName) {
+ TypeName type = parsedNode.type;
+ if (type != null) {
+ targetId = type.name;
+ }
+ } else if (parsedNode is PrefixedIdentifier) {
+ // Some PrefixedIdentifier nodes are transformed into
+ // ConstructorName nodes during the resolution process.
+ targetId = parsedNode.prefix;
+ }
+ if (targetId == null) {
+ return EMPTY_LIST;
+ }
+
+ // Resolve the target to determine the type
+ await request.resolveExpression(targetId);
+
+ // Recompute the target since resolution may have changed it
+ AstNode node = request.target.containingNode;
+ LibraryElement libElem = request.libraryElement;
+ if (libElem == null) {
+ return EMPTY_LIST;
+ }
+
+ // Build the list of suggestions
+ if (node is ConstructorName) {
+ TypeName typeName = node.type;
+ if (typeName != null) {
+ DartType type = typeName.type;
+ if (type != null) {
+ Element classElem = type.element;
+ if (classElem is ClassElement) {
+ return _buildSuggestions(libElem, classElem);
+ }
+ }
+ }
+ }
+ return EMPTY_LIST;
+ }
+
+ List<CompletionSuggestion> _buildSuggestions(
+ LibraryElement libElem, ClassElement classElem) {
+ bool isLocalClassDecl = classElem.library == libElem;
+ List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+ for (ConstructorElement elem in classElem.constructors) {
+ if (isLocalClassDecl || !elem.isPrivate) {
+ String name = elem.name;
+ if (name != null) {
+ CompletionSuggestion s = createSuggestion(elem, completion: name);
+ if (s != null) {
+ suggestions.add(s);
+ }
+ }
+ }
+ }
+ return suggestions;
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
new file mode 100644
index 0000000..d1d2816
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
@@ -0,0 +1,143 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library services.completion.contributor.dart.static_member;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+
+import '../../../protocol_server.dart'
+ show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating static member invocation / access suggestions
+ * `completion.getSuggestions` request results.
+ */
+class StaticMemberContributor extends DartCompletionContributor {
+ @override
+ Future<List<CompletionSuggestion>> computeSuggestions(
+ DartCompletionRequest request) async {
+ // Determine if the target looks like a static method invocation,
+ // or a static property access
+ if (request.dotTarget is! Identifier || request.target.isCascade) {
+ return EMPTY_LIST;
+ }
+
+ // Resolve the expression and the containing library
+ await request.resolveExpression(request.dotTarget);
+
+ // Recompute the target since resolution may have changed it
+ Expression targetId = request.dotTarget;
+ if (targetId is Identifier && !request.target.isCascade) {
+ Element elem = targetId.bestElement;
+ if (elem is ClassElement) {
+ LibraryElement containingLibrary = request.libraryElement;
+ // Gracefully degrade if the library could not be determined
+ // e.g. detached part file or source change
+ if (containingLibrary == null) {
+ return EMPTY_LIST;
+ }
+
+ _SuggestionBuilder builder = new _SuggestionBuilder(containingLibrary);
+ elem.accept(builder);
+ return builder.suggestions;
+ }
+ }
+ return EMPTY_LIST;
+ }
+}
+
+/**
+ * This class visits elements in a class and provides suggestions based upon
+ * the visible static members in that class.
+ */
+class _SuggestionBuilder extends GeneralizingElementVisitor {
+ /**
+ * The library containing the unit in which the completion is requested.
+ */
+ final LibraryElement containingLibrary;
+
+ /**
+ * A collection of completion suggestions.
+ */
+ final List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+
+ _SuggestionBuilder(this.containingLibrary);
+
+ @override
+ visitClassElement(ClassElement element) {
+ element.visitChildren(this);
+ }
+
+ @override
+ visitElement(Element element) {
+ // ignored
+ }
+
+ @override
+ visitFieldElement(FieldElement element) {
+ if (element.isStatic) {
+ _addSuggestion(element);
+ }
+ }
+
+ @override
+ visitMethodElement(MethodElement element) {
+ if (element.isStatic && !element.isOperator) {
+ _addSuggestion(element);
+ }
+ }
+
+ @override
+ visitPropertyAccessorElement(PropertyAccessorElement element) {
+ if (element.isStatic) {
+ _addSuggestion(element);
+ }
+ }
+
+ /**
+ * Add a suggestion based upon the given element.
+ */
+ void _addSuggestion(Element element) {
+ if (element.isPrivate) {
+ if (element.library != containingLibrary) {
+ // Do not suggest private members for imported libraries
+ return;
+ }
+ }
+ if (element.isSynthetic) {
+ if ((element is PropertyAccessorElement) ||
+ element is FieldElement && !_isSpecialEnumField(element)) {
+ return;
+ }
+ }
+ String completion = element.displayName;
+ if (completion == null || completion.length <= 0) {
+ return;
+ }
+ CompletionSuggestion suggestion =
+ createSuggestion(element, completion: completion);
+ if (suggestion != null) {
+ suggestions.add(suggestion);
+ }
+ }
+
+ /**
+ * Determine if the given element is one of the synthetic enum accessors
+ * for which we should generate a suggestion.
+ */
+ bool _isSpecialEnumField(FieldElement element) {
+ Element parent = element.enclosingElement;
+ if (parent is ClassElement && parent.isEnum) {
+ if (element.name == 'values') {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index fa0cf95..0e395fa 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -112,9 +112,9 @@
CompletionSuggestionKind get kind;
/**
- * Return the request on which the builder is operating.
+ * Return the library in which the completion is requested.
*/
- DartCompletionRequest get request;
+ LibraryElement get containingLibrary;
/**
* Add a suggestion based upon the given element.
@@ -122,13 +122,7 @@
void addSuggestion(Element element,
{String prefix, int relevance: DART_RELEVANCE_DEFAULT}) {
if (element.isPrivate) {
- LibraryElement elementLibrary = element.library;
- CompilationUnitElement unitElem = request.target.unit.element;
- if (unitElem == null) {
- return;
- }
- LibraryElement unitLibrary = unitElem.library;
- if (elementLibrary != unitLibrary) {
+ if (element.library != containingLibrary) {
return;
}
}
@@ -173,18 +167,17 @@
/**
* This class visits elements in a library and provides suggestions based upon
- * the visible members in that library. Clients should call
- * [LibraryElementSuggestionBuilder.suggestionsFor].
+ * the visible members in that library.
*/
class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor
with ElementSuggestionBuilder {
- final DartCompletionRequest request;
+ final LibraryElement containingLibrary;
final CompletionSuggestionKind kind;
final bool typesOnly;
final bool instCreation;
LibraryElementSuggestionBuilder(
- this.request, this.kind, this.typesOnly, this.instCreation);
+ this.containingLibrary, this.kind, this.typesOnly, this.instCreation);
@override
visitClassElement(ClassElement element) {
@@ -244,19 +237,4 @@
addSuggestion(element);
}
}
-
- /**
- * Add suggestions for the visible members in the given library
- */
- static void suggestionsFor(
- DartCompletionRequest request,
- CompletionSuggestionKind kind,
- LibraryElement library,
- bool typesOnly,
- bool instCreation) {
- if (library != null) {
- library.visitChildren(new LibraryElementSuggestionBuilder(
- request, kind, typesOnly, instCreation));
- }
- }
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
new file mode 100644
index 0000000..8915a65
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -0,0 +1,412 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library services.completion.contributor.dart.type_member;
+
+import 'dart:async';
+import 'dart:collection';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analysis_server/src/services/completion/local_declaration_visitor.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+
+import '../../../protocol_server.dart'
+ show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating instance invocation / access suggestions
+ * `completion.getSuggestions` request results.
+ */
+class TypeMemberContributor extends DartCompletionContributor {
+ @override
+ Future<List<CompletionSuggestion>> computeSuggestions(
+ DartCompletionRequest request) async {
+ // Determine if the target looks like a prefixed identifier,
+ // a method invocation, or a property access
+ Expression parsedExpression = request.dotTarget;
+ if (parsedExpression == null) {
+ return EMPTY_LIST;
+ }
+
+ // Resolve the expression and the containing library
+ await request.resolveExpression(parsedExpression);
+ LibraryElement containingLibrary = request.libraryElement;
+ // Gracefully degrade if the library element could not be resolved
+ // e.g. detached part file or source change
+ if (containingLibrary == null) {
+ return EMPTY_LIST;
+ }
+
+ // Recompute the target since resolution may have changed it
+ Expression expression = request.dotTarget;
+ if (expression == null || expression.isSynthetic) {
+ return EMPTY_LIST;
+ }
+ if (expression is Identifier) {
+ Element elem = expression.bestElement;
+ if (elem is ClassElement) {
+ // Suggestions provided by StaticMemberContributor
+ return EMPTY_LIST;
+ }
+ if (elem is PrefixElement) {
+ // Suggestions provided by LibraryMemberContributor
+ return EMPTY_LIST;
+ }
+ }
+
+ // Determine the target expression's type
+ DartType type = expression.bestType;
+ if (type.isDynamic) {
+ // If the expression does not provide a good type
+ // then attempt to get a better type from the element
+ if (expression is Identifier) {
+ Element elem = expression.bestElement;
+ if (elem is FunctionTypedElement) {
+ type = elem.returnType;
+ } else if (elem is ParameterElement) {
+ type = elem.type;
+ } else if (elem is LocalVariableElement) {
+ type = elem.type;
+ }
+ if (type.isDynamic && expression is SimpleIdentifier) {
+ // If the element does not provide a good type
+ // then attempt to get a better type from a local declaration
+ _LocalBestTypeVisitor visitor =
+ new _LocalBestTypeVisitor(expression.name, request.offset);
+ if (visitor.visit(expression) && visitor.typeFound != null) {
+ type = visitor.typeFound;
+ }
+ }
+ }
+ }
+ String containingMethodName;
+ if (expression is SuperExpression && type is InterfaceType) {
+ // Suggest members from superclass if target is "super"
+ type = (type as InterfaceType).superclass;
+ // Determine the name of the containing method because
+ // the most likely completion is a super expression with same name
+ MethodDeclaration containingMethod =
+ expression.getAncestor((p) => p is MethodDeclaration);
+ if (containingMethod != null) {
+ SimpleIdentifier id = containingMethod.name;
+ if (id != null) {
+ containingMethodName = id.name;
+ }
+ }
+ }
+ if (type.isDynamic) {
+ // Suggest members from object if target is "dynamic"
+ type = request.objectType;
+ }
+
+ // Build the suggestions
+ if (type is InterfaceType) {
+ _SuggestionBuilder builder = new _SuggestionBuilder(containingLibrary);
+ builder.buildSuggestions(type, containingMethodName);
+ return builder.suggestions.toList();
+ }
+ return EMPTY_LIST;
+ }
+}
+
+/**
+ * An [AstVisitor] which looks for a declaration with the given name
+ * and if found, tries to determine a type for that declaration.
+ */
+class _LocalBestTypeVisitor extends LocalDeclarationVisitor {
+ /**
+ * The name for the declaration to be found.
+ */
+ final String targetName;
+
+ /**
+ * The best type for the found declaration,
+ * or `null` if no declaration found or failed to determine a type.
+ */
+ DartType typeFound;
+
+ /**
+ * Construct a new instance to search for a declaration
+ */
+ _LocalBestTypeVisitor(this.targetName, int offset) : super(offset);
+
+ @override
+ void declaredClass(ClassDeclaration declaration) {
+ if (declaration.name.name == targetName) {
+ // no type
+ finished();
+ }
+ }
+
+ @override
+ void declaredClassTypeAlias(ClassTypeAlias declaration) {
+ if (declaration.name.name == targetName) {
+ // no type
+ finished();
+ }
+ }
+
+ @override
+ void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
+ if (varDecl.name.name == targetName) {
+ // Type provided by the element in computeFull above
+ finished();
+ }
+ }
+
+ @override
+ void declaredFunction(FunctionDeclaration declaration) {
+ if (declaration.name.name == targetName) {
+ TypeName typeName = declaration.returnType;
+ if (typeName != null) {
+ typeFound = typeName.type;
+ }
+ finished();
+ }
+ }
+
+ @override
+ void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
+ if (declaration.name.name == targetName) {
+ TypeName typeName = declaration.returnType;
+ if (typeName != null) {
+ typeFound = typeName.type;
+ }
+ finished();
+ }
+ }
+
+ @override
+ void declaredLabel(Label label, bool isCaseLabel) {
+ if (label.label.name == targetName) {
+ // no type
+ finished();
+ }
+ }
+
+ @override
+ void declaredLocalVar(SimpleIdentifier name, TypeName type) {
+ if (name.name == targetName) {
+ typeFound = name.bestType;
+ finished();
+ }
+ }
+
+ @override
+ void declaredMethod(MethodDeclaration declaration) {
+ if (declaration.name.name == targetName) {
+ TypeName typeName = declaration.returnType;
+ if (typeName != null) {
+ typeFound = typeName.type;
+ }
+ finished();
+ }
+ }
+
+ @override
+ void declaredParam(SimpleIdentifier name, TypeName type) {
+ if (name.name == targetName) {
+ // Type provided by the element in computeFull above
+ finished();
+ }
+ }
+
+ @override
+ void declaredTopLevelVar(
+ VariableDeclarationList varList, VariableDeclaration varDecl) {
+ if (varDecl.name.name == targetName) {
+ // Type provided by the element in computeFull above
+ finished();
+ }
+ }
+}
+
+/**
+ * This class provides suggestions based upon the visible instance members in
+ * an interface type.
+ */
+class _SuggestionBuilder {
+ /**
+ * Enumerated value indicating that we have not generated any completions for
+ * a given identifier yet.
+ */
+ static const int _COMPLETION_TYPE_NONE = 0;
+
+ /**
+ * Enumerated value indicating that we have generated a completion for a
+ * getter.
+ */
+ static const int _COMPLETION_TYPE_GETTER = 1;
+
+ /**
+ * Enumerated value indicating that we have generated a completion for a
+ * setter.
+ */
+ static const int _COMPLETION_TYPE_SETTER = 2;
+
+ /**
+ * Enumerated value indicating that we have generated a completion for a
+ * field, a method, or a getter/setter pair.
+ */
+ static const int _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET = 3;
+
+ /**
+ * The library containing the unit in which the completion is requested.
+ */
+ final LibraryElement containingLibrary;
+
+ /**
+ * Map indicating, for each possible completion identifier, whether we have
+ * already generated completions for a getter, setter, or both. The "both"
+ * case also handles the case where have generated a completion for a method
+ * or a field.
+ *
+ * Note: the enumerated values stored in this map are intended to be bitwise
+ * compared.
+ */
+ Map<String, int> _completionTypesGenerated = new HashMap<String, int>();
+
+ /**
+ * Map from completion identifier to completion suggestion
+ */
+ Map<String, CompletionSuggestion> _suggestionMap =
+ <String, CompletionSuggestion>{};
+
+ _SuggestionBuilder(this.containingLibrary);
+
+ Iterable<CompletionSuggestion> get suggestions => _suggestionMap.values;
+
+ /**
+ * Add a suggestion based upon the given element, provided that it is not
+ * shadowed by a previously added suggestion.
+ */
+ void _addSuggestion(Element element,
+ {int relevance: DART_RELEVANCE_DEFAULT}) {
+ if (element.isPrivate) {
+ if (element.library != containingLibrary) {
+ // Do not suggest private members for imported libraries
+ return;
+ }
+ }
+ String identifier = element.displayName;
+ int alreadyGenerated = _completionTypesGenerated.putIfAbsent(
+ identifier, () => _COMPLETION_TYPE_NONE);
+ if (element is MethodElement) {
+ // Anything shadows a method.
+ if (alreadyGenerated != _COMPLETION_TYPE_NONE) {
+ return;
+ }
+ _completionTypesGenerated[identifier] =
+ _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
+ } else if (element is PropertyAccessorElement) {
+ if (element.isGetter) {
+ // Getters, fields, and methods shadow a getter.
+ if ((alreadyGenerated & _COMPLETION_TYPE_GETTER) != 0) {
+ return;
+ }
+ _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_GETTER;
+ } else {
+ // Setters, fields, and methods shadow a setter.
+ if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) {
+ return;
+ }
+ _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER;
+ }
+ } else if (element is FieldElement) {
+ // Fields and methods shadow a field. A getter/setter pair shadows a
+ // field, but a getter or setter by itself doesn't.
+ if (alreadyGenerated == _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET) {
+ return;
+ }
+ _completionTypesGenerated[identifier] =
+ _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
+ } else {
+ // Unexpected element type; skip it.
+ assert(false);
+ return;
+ }
+ CompletionSuggestion suggestion =
+ createSuggestion(element, relevance: relevance);
+ if (suggestion != null) {
+ _suggestionMap[suggestion.completion] = suggestion;
+ }
+ }
+
+ /**
+ * Return completion suggestions for 'dot' completions on the given [type].
+ * If the 'dot' completion is a super expression, then [containingMethodName]
+ * is the name of the method in which the completion is requested.
+ */
+ void buildSuggestions(InterfaceType type, String containingMethodName) {
+ // Visit all of the types in the class hierarchy, collecting possible
+ // completions. If multiple elements are found that complete to the same
+ // identifier, addSuggestion will discard all but the first (with a few
+ // exceptions to handle getter/setter pairs).
+ List<InterfaceType> types = _getTypeOrdering(type);
+ for (InterfaceType targetType in types) {
+ for (MethodElement method in targetType.methods) {
+ // Exclude static methods when completion on an instance
+ if (!method.isStatic) {
+ // Boost the relevance of a super expression
+ // calling a method of the same name as the containing method
+ _addSuggestion(method,
+ relevance: method.name == containingMethodName
+ ? DART_RELEVANCE_HIGH
+ : DART_RELEVANCE_DEFAULT);
+ }
+ }
+ for (PropertyAccessorElement propertyAccessor in targetType.accessors) {
+ if (!propertyAccessor.isStatic) {
+ if (propertyAccessor.isSynthetic) {
+ // Avoid visiting a field twice
+ if (propertyAccessor.isGetter) {
+ _addSuggestion(propertyAccessor.variable);
+ }
+ } else {
+ _addSuggestion(propertyAccessor);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Get a list of [InterfaceType]s that should be searched to find the
+ * possible completions for an object having type [type].
+ */
+ List<InterfaceType> _getTypeOrdering(InterfaceType type) {
+ // Candidate completions can come from [type] as well as any types above it
+ // in the class hierarchy (including mixins, superclasses, and interfaces).
+ // If a given completion identifier shows up in multiple types, we should
+ // use the element that is nearest in the superclass chain, so we will
+ // visit [type] first, then its mixins, then its superclass, then its
+ // superclass's mixins, etc., and only afterwards visit interfaces.
+ //
+ // We short-circuit loops in the class hierarchy by keeping track of the
+ // classes seen (not the interfaces) so that we won't be fooled by nonsense
+ // like "class C<T> extends C<List<T>> {}"
+ List<InterfaceType> result = <InterfaceType>[];
+ Set<ClassElement> classesSeen = new HashSet<ClassElement>();
+ List<InterfaceType> typesToVisit = <InterfaceType>[type];
+ while (typesToVisit.isNotEmpty) {
+ InterfaceType nextType = typesToVisit.removeLast();
+ if (!classesSeen.add(nextType.element)) {
+ // Class had already been seen, so ignore this type.
+ continue;
+ }
+ result.add(nextType);
+ // typesToVisit is a stack, so push on the interfaces first, then the
+ // superclass, then the mixins. This will ensure that they are visited
+ // in the reverse order.
+ typesToVisit.addAll(nextType.interfaces);
+ if (nextType.superclass != null) {
+ typesToVisit.add(nextType.superclass);
+ }
+ typesToVisit.addAll(nextType.mixins);
+ }
+ return result;
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
index ebf87fe..7e849b1 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
@@ -116,10 +116,19 @@
if (resContext.isRelative(dirPath)) {
String sourceDirPath = resContext.dirname(source.fullName);
if (resContext.isAbsolute(sourceDirPath)) {
- dirPath = resContext.join(sourceDirPath, dirPath);
+ dirPath = resContext.normalize(resContext.join(sourceDirPath, dirPath));
} else {
return;
}
+ // Do not suggest relative paths reaching outside the 'lib' directory.
+ bool srcInLib = resContext.split(sourceDirPath).contains('lib');
+ bool dstInLib = resContext.split(dirPath).contains('lib');
+ if (srcInLib && !dstInLib) {
+ return;
+ }
+ }
+ if (dirPath.endsWith('\\.')) {
+ dirPath = dirPath.substring(0, dirPath.length - 1);
}
Resource dir = resProvider.getResource(dirPath);
diff --git a/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart b/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
index 2fbe91e..be84372 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
@@ -31,12 +31,6 @@
String _importKey;
/**
- * Library prefix suggestions based upon imports,
- * or `null` if nothing has been cached.
- */
- List<CompletionSuggestion> libraryPrefixSuggestions;
-
- /**
* Type suggestions based upon imports,
* or `null` if nothing has been cached.
*/
@@ -114,7 +108,6 @@
Future<bool> computeImportInfo(CompilationUnit unit,
SearchEngine searchEngine, bool shouldWaitForLowPrioritySuggestions) {
importedTypeSuggestions = <CompletionSuggestion>[];
- libraryPrefixSuggestions = <CompletionSuggestion>[];
otherImportedSuggestions = <CompletionSuggestion>[];
importedConstructorSuggestions = <CompletionSuggestion>[];
importedVoidReturnSuggestions = <CompletionSuggestion>[];
@@ -240,8 +233,9 @@
} else {
// Exclude elements from prefixed imports
// because they are provided by PrefixedElementContributor
- _addLibraryPrefixSuggestion(importElem);
- excludedLibs.add(importElem.importedLibrary);
+ // Suggested by LibraryPrefixContributor
+ // _addLibraryPrefixSuggestion(importElem);
+ // excludedLibs.add(importElem.importedLibrary);
}
}
} else if (directive is PartDirective) {
@@ -257,27 +251,6 @@
}
}
- void _addLibraryPrefixSuggestion(ImportElement importElem) {
- CompletionSuggestion suggestion = null;
- String completion = importElem.prefix.displayName;
- if (completion != null && completion.length > 0) {
- suggestion = new CompletionSuggestion(
- CompletionSuggestionKind.INVOCATION,
- DART_RELEVANCE_DEFAULT,
- completion,
- completion.length,
- 0,
- importElem.isDeprecated,
- false);
- LibraryElement lib = importElem.importedLibrary;
- if (lib != null) {
- suggestion.element = convertElement(lib);
- }
- libraryPrefixSuggestions.add(suggestion);
- _importedCompletions.add(suggestion.completion);
- }
- }
-
/**
* Add suggestions for all top level elements in the context
* excluding those elemnents for which suggestions have already been added.
diff --git a/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart
index 06bbe66..4f793ec 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart
@@ -18,11 +18,10 @@
import 'package:analysis_server/src/services/completion/imported_reference_contributor.dart';
import 'package:analysis_server/src/services/completion/local_reference_contributor.dart';
import 'package:analysis_server/src/services/completion/optype.dart';
-import 'package:analysis_server/src/services/completion/prefixed_element_contributor.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisContextImpl;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/scanner.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -99,7 +98,7 @@
//new KeywordContributor(),
//new ArgListContributor(),
// new CombinatorContributor(),
- new PrefixedElementContributor(),
+ // new PrefixedElementContributor(),
//new UriContributor(),
// TODO(brianwilkerson) Use the completion contributor extension point
// to add the contributor below (and eventually, all the contributors).
diff --git a/pkg/analysis_server/lib/src/services/completion/imported_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/imported_reference_contributor.dart
index b283ce9..f2a9cfa 100644
--- a/pkg/analysis_server/lib/src/services/completion/imported_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/imported_reference_contributor.dart
@@ -143,7 +143,6 @@
}
DartCompletionCache cache = request.cache;
_addFilteredSuggestions(filterText, cache.importedConstructorSuggestions);
- _addFilteredSuggestions(filterText, cache.libraryPrefixSuggestions);
}
/**
@@ -258,7 +257,6 @@
DartCompletionCache cache = request.cache;
if (optype.includeTypeNameSuggestions) {
_addFilteredSuggestions(filterText, cache.importedTypeSuggestions);
- _addFilteredSuggestions(filterText, cache.libraryPrefixSuggestions);
}
if (optype.includeReturnValueSuggestions) {
_addFilteredSuggestions(filterText, cache.otherImportedSuggestions);
diff --git a/pkg/analysis_server/lib/src/services/completion/optype.dart b/pkg/analysis_server/lib/src/services/completion/optype.dart
index 3408e96..768b0d3 100644
--- a/pkg/analysis_server/lib/src/services/completion/optype.dart
+++ b/pkg/analysis_server/lib/src/services/completion/optype.dart
@@ -129,6 +129,14 @@
}
}
+@override
+ void visitAssertStatement(AssertStatement node) {
+ if (identical(entity, node.condition)) {
+ optype.includeReturnValueSuggestions = true;
+ optype.includeTypeNameSuggestions = true;
+ }
+ }
+
void visitAssignmentExpression(AssignmentExpression node) {
if (identical(entity, node.rightHandSide)) {
optype.includeReturnValueSuggestions = true;
diff --git a/pkg/analysis_server/lib/src/services/completion/prefixed_element_contributor.dart b/pkg/analysis_server/lib/src/services/completion/prefixed_element_contributor.dart
deleted file mode 100644
index b6fe585..0000000
--- a/pkg/analysis_server/lib/src/services/completion/prefixed_element_contributor.dart
+++ /dev/null
@@ -1,370 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.completion.contributor.dart.invocation;
-
-import 'dart:async';
-
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/local_declaration_visitor.dart';
-import 'package:analysis_server/src/services/completion/local_suggestion_builder.dart'
- hide createSuggestion;
-import 'package:analysis_server/src/services/completion/optype.dart';
-import 'package:analysis_server/src/services/completion/suggestion_builder.dart';
-import 'package:analysis_server/src/services/completion/suggestion_builder.dart'
- show createSuggestion;
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-
-import '../../protocol_server.dart'
- show CompletionSuggestion, CompletionSuggestionKind;
-
-/**
- * A contributor for calculating invocation / access suggestions
- * `completion.getSuggestions` request results.
- */
-class PrefixedElementContributor extends DartCompletionContributor {
- SuggestionBuilder builder;
-
- @override
- bool computeFast(DartCompletionRequest request) {
- OpType optype = request.optype;
- if (optype.isPrefixed) {
- builder = request.target.containingNode
- .accept(new _InvocationAstVisitor(request));
- if (builder != null) {
- return builder.computeFast(request.target.containingNode);
- }
- }
-
- return true;
- }
-
- @override
- Future<bool> computeFull(DartCompletionRequest request) {
- if (builder != null) {
- return builder.computeFull(request.target.containingNode);
- }
- return new Future.value(false);
- }
-}
-
-class _ExpressionSuggestionBuilder implements SuggestionBuilder {
- final DartCompletionRequest request;
-
- _ExpressionSuggestionBuilder(this.request);
-
- @override
- bool computeFast(AstNode node) {
- return false;
- }
-
- @override
- Future<bool> computeFull(AstNode node) {
- if (node is MethodInvocation) {
- node = (node as MethodInvocation).realTarget;
- } else if (node is PropertyAccess) {
- node = (node as PropertyAccess).realTarget;
- }
- if (node is Identifier) {
- Element elem = node.bestElement;
- if (elem is ClassElement || elem is PrefixElement) {
- elem.accept(new _PrefixedIdentifierSuggestionBuilder(request));
- return new Future.value(true);
- }
- }
- if (node is Expression) {
- String containingMethodName;
- bool isSuper = node is SuperExpression;
- if (isSuper) {
- MethodDeclaration containingMethod =
- node.getAncestor((p) => p is MethodDeclaration);
- if (containingMethod != null) {
- SimpleIdentifier id = containingMethod.name;
- if (id != null) {
- containingMethodName = id.name;
- }
- }
- }
- InterfaceTypeSuggestionBuilder.suggestionsFor(request, node.bestType,
- isSuper: isSuper, containingMethodName: containingMethodName);
- return new Future.value(true);
- }
- return new Future.value(false);
- }
-}
-
-/**
- * An [AstNode] vistor for determining which suggestion builder
- * should be used to build invocation/access suggestions.
- */
-class _InvocationAstVisitor extends GeneralizingAstVisitor<SuggestionBuilder> {
- final DartCompletionRequest request;
-
- _InvocationAstVisitor(this.request);
-
- @override
- SuggestionBuilder visitConstructorName(ConstructorName node) {
- // some PrefixedIdentifier nodes are transformed into
- // ConstructorName nodes during the resolution process.
- return new _PrefixedIdentifierSuggestionBuilder(request);
- }
-
- @override
- SuggestionBuilder visitMethodInvocation(MethodInvocation node) {
- return new _ExpressionSuggestionBuilder(request);
- }
-
- @override
- SuggestionBuilder visitNode(AstNode node) {
- return null;
- }
-
- @override
- SuggestionBuilder visitPrefixedIdentifier(PrefixedIdentifier node) {
- // some PrefixedIdentifier nodes are transformed into
- // ConstructorName nodes during the resolution process.
- return new _PrefixedIdentifierSuggestionBuilder(request);
- }
-
- @override
- SuggestionBuilder visitPropertyAccess(PropertyAccess node) {
- return new _ExpressionSuggestionBuilder(request);
- }
-}
-
-/**
- * An [AstVisitor] which looks for a declaration with the given name
- * and if found, tries to determine a type for that declaration.
- */
-class _LocalBestTypeVisitor extends LocalDeclarationVisitor {
- /**
- * The name for the declaration to be found.
- */
- final String targetName;
-
- /**
- * The best type for the found declaration,
- * or `null` if no declaration found or failed to determine a type.
- */
- DartType typeFound;
-
- /**
- * Construct a new instance to search for a declaration
- */
- _LocalBestTypeVisitor(this.targetName, int offset) : super(offset);
-
- @override
- void declaredClass(ClassDeclaration declaration) {
- if (declaration.name.name == targetName) {
- // no type
- finished();
- }
- }
-
- @override
- void declaredClassTypeAlias(ClassTypeAlias declaration) {
- if (declaration.name.name == targetName) {
- // no type
- finished();
- }
- }
-
- @override
- void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
- if (varDecl.name.name == targetName) {
- // Type provided by the element in computeFull above
- finished();
- }
- }
-
- @override
- void declaredFunction(FunctionDeclaration declaration) {
- if (declaration.name.name == targetName) {
- TypeName typeName = declaration.returnType;
- if (typeName != null) {
- typeFound = typeName.type;
- }
- finished();
- }
- }
-
- @override
- void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
- if (declaration.name.name == targetName) {
- TypeName typeName = declaration.returnType;
- if (typeName != null) {
- typeFound = typeName.type;
- }
- finished();
- }
- }
-
- @override
- void declaredLabel(Label label, bool isCaseLabel) {
- if (label.label.name == targetName) {
- // no type
- finished();
- }
- }
-
- @override
- void declaredLocalVar(SimpleIdentifier name, TypeName type) {
- if (name.name == targetName) {
- typeFound = name.bestType;
- finished();
- }
- }
-
- @override
- void declaredMethod(MethodDeclaration declaration) {
- if (declaration.name.name == targetName) {
- TypeName typeName = declaration.returnType;
- if (typeName != null) {
- typeFound = typeName.type;
- }
- finished();
- }
- }
-
- @override
- void declaredParam(SimpleIdentifier name, TypeName type) {
- if (name.name == targetName) {
- // Type provided by the element in computeFull above
- finished();
- }
- }
-
- @override
- void declaredTopLevelVar(
- VariableDeclarationList varList, VariableDeclaration varDecl) {
- if (varDecl.name.name == targetName) {
- // Type provided by the element in computeFull above
- finished();
- }
- }
-}
-
-/**
- * An [Element] visitor for determining the appropriate invocation/access
- * suggestions based upon the element for which the completion is requested.
- */
-class _PrefixedIdentifierSuggestionBuilder
- extends GeneralizingElementVisitor<Future<bool>>
- implements SuggestionBuilder {
- final DartCompletionRequest request;
-
- _PrefixedIdentifierSuggestionBuilder(this.request);
-
- @override
- bool computeFast(AstNode node) {
- return false;
- }
-
- @override
- Future<bool> computeFull(AstNode node) {
- if (node is ConstructorName) {
- // some PrefixedIdentifier nodes are transformed into
- // ConstructorName nodes during the resolution process.
- return new NamedConstructorSuggestionBuilder(request).computeFull(node);
- }
- if (node is PrefixedIdentifier) {
- SimpleIdentifier prefix = node.prefix;
- if (prefix != null) {
- Element element = prefix.bestElement;
- DartType type = prefix.bestType;
- if (element is! ClassElement) {
- if (type == null || type.isDynamic) {
- //
- // Given `g. int y = 0;`, the parser interprets `g` as a prefixed
- // identifier with no type.
- // If the user is requesting completions for `g`,
- // then check for a function, getter, or similar with a type.
- //
- _LocalBestTypeVisitor visitor =
- new _LocalBestTypeVisitor(prefix.name, request.offset);
- if (visitor.visit(prefix)) {
- type = visitor.typeFound;
- }
- }
- if (type != null && !type.isDynamic) {
- InterfaceTypeSuggestionBuilder.suggestionsFor(request, type);
- return new Future.value(true);
- }
- }
- if (element != null) {
- return element.accept(this);
- }
- }
- }
- return new Future.value(false);
- }
-
- @override
- Future<bool> visitClassElement(ClassElement element) {
- if (element != null) {
- InterfaceType type = element.type;
- if (type != null) {
- StaticClassElementSuggestionBuilder.suggestionsFor(
- request, type.element);
- }
- }
- return new Future.value(false);
- }
-
- @override
- Future<bool> visitElement(Element element) {
- return new Future.value(false);
- }
-
- @override
- Future<bool> visitPrefixElement(PrefixElement element) {
- bool modified = false;
- // Find the import directive with the given prefix
- for (Directive directive in request.unit.directives) {
- if (directive is ImportDirective) {
- if (directive.prefix != null) {
- if (directive.prefix.name == element.name) {
- // Suggest elements from the imported library
- LibraryElement library = directive.uriElement;
- AstNode node = request.target.containingNode;
- bool typesOnly = node.parent is TypeName;
- bool instCreation =
- typesOnly && node.parent.parent is ConstructorName;
- LibraryElementSuggestionBuilder.suggestionsFor(
- request,
- CompletionSuggestionKind.INVOCATION,
- library,
- typesOnly,
- instCreation);
- modified = true;
- if (directive.deferredKeyword != null) {
- FunctionElement loadLibFunct = library.loadLibraryFunction;
- request.addSuggestion(createSuggestion(loadLibFunct));
- }
- }
- }
- }
- }
- return new Future.value(modified);
- }
-
- @override
- Future<bool> visitPropertyAccessorElement(PropertyAccessorElement element) {
- if (element != null) {
- PropertyInducingElement elemVar = element.variable;
- if (elemVar != null) {
- InterfaceTypeSuggestionBuilder.suggestionsFor(request, elemVar.type);
- }
- return new Future.value(true);
- }
- return new Future.value(false);
- }
-
- @override
- Future<bool> visitVariableElement(VariableElement element) {
- InterfaceTypeSuggestionBuilder.suggestionsFor(request, element.type);
- return new Future.value(true);
- }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
index 573dc4b..4379e7f 100644
--- a/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
@@ -5,7 +5,6 @@
library services.completion.suggestion.builder;
import 'dart:async';
-import 'dart:collection';
import 'package:analysis_server/src/protocol_server.dart'
hide Element, ElementKind;
@@ -14,7 +13,6 @@
import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart' as engine;
export 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'
show createSuggestion;
@@ -174,421 +172,6 @@
}
/**
- * This class provides suggestions based upon the visible instance members in
- * an interface type. Clients should call
- * [InterfaceTypeSuggestionBuilder.suggestionsFor].
- */
-class InterfaceTypeSuggestionBuilder {
- /**
- * Enumerated value indicating that we have not generated any completions for
- * a given identifier yet.
- */
- static const int _COMPLETION_TYPE_NONE = 0;
-
- /**
- * Enumerated value indicating that we have generated a completion for a
- * getter.
- */
- static const int _COMPLETION_TYPE_GETTER = 1;
-
- /**
- * Enumerated value indicating that we have generated a completion for a
- * setter.
- */
- static const int _COMPLETION_TYPE_SETTER = 2;
-
- /**
- * Enumerated value indicating that we have generated a completion for a
- * field, a method, or a getter/setter pair.
- */
- static const int _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET = 3;
-
- final DartCompletionRequest request;
-
- /**
- * Map indicating, for each possible completion identifier, whether we have
- * already generated completions for a getter, setter, or both. The "both"
- * case also handles the case where have generated a completion for a method
- * or a field.
- *
- * Note: the enumerated values stored in this map are intended to be bitwise
- * compared.
- */
- Map<String, int> _completionTypesGenerated = new HashMap<String, int>();
-
- InterfaceTypeSuggestionBuilder(this.request);
-
- CompletionSuggestionKind get kind => CompletionSuggestionKind.INVOCATION;
-
- /**
- * Add a suggestion based upon the given element, provided that it is not
- * shadowed by a previously added suggestion.
- */
- void addSuggestion(Element element, {int relevance: DART_RELEVANCE_DEFAULT}) {
- if (element.isPrivate) {
- LibraryElement elementLibrary = element.library;
- LibraryElement unitLibrary = request.unit.element.library;
- if (elementLibrary != unitLibrary) {
- return;
- }
- }
- String identifier = element.displayName;
- int alreadyGenerated = _completionTypesGenerated.putIfAbsent(
- identifier, () => _COMPLETION_TYPE_NONE);
- if (element is MethodElement) {
- // Anything shadows a method.
- if (alreadyGenerated != _COMPLETION_TYPE_NONE) {
- return;
- }
- _completionTypesGenerated[identifier] =
- _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
- } else if (element is PropertyAccessorElement) {
- if (element.isGetter) {
- // Getters, fields, and methods shadow a getter.
- if ((alreadyGenerated & _COMPLETION_TYPE_GETTER) != 0) {
- return;
- }
- _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_GETTER;
- } else {
- // Setters, fields, and methods shadow a setter.
- if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) {
- return;
- }
- _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER;
- }
- } else if (element is FieldElement) {
- // Fields and methods shadow a field. A getter/setter pair shadows a
- // field, but a getter or setter by itself doesn't.
- if (alreadyGenerated == _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET) {
- return;
- }
- _completionTypesGenerated[identifier] =
- _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
- } else {
- // Unexpected element type; skip it.
- assert(false);
- return;
- }
- CompletionSuggestion suggestion =
- createSuggestion(element, kind: kind, relevance: relevance);
- if (suggestion != null) {
- request.addSuggestion(suggestion);
- }
- }
-
- void _buildSuggestions(InterfaceType type, LibraryElement library,
- bool isSuper, String containingMethodName) {
- if (isSuper) {
- // Suggest members from superclass if the target is "super"
- type = type.superclass;
- if (type == null) {
- return;
- }
- }
- // Visit all of the types in the class hierarchy, collecting possible
- // completions. If multiple elements are found that complete to the same
- // identifier, addSuggestion will discard all but the first (with a few
- // exceptions to handle getter/setter pairs).
- List<InterfaceType> types = _getTypeOrdering(type);
- for (InterfaceType targetType in types) {
- for (MethodElement method in targetType.methods) {
- // Exclude static methods when completion on an instance
- if (!method.isStatic) {
- addSuggestion(method,
- relevance: method.name == containingMethodName
- ? DART_RELEVANCE_HIGH
- : DART_RELEVANCE_DEFAULT);
- }
- }
- for (PropertyAccessorElement propertyAccessor in targetType.accessors) {
- if (!propertyAccessor.isStatic) {
- if (propertyAccessor.isSynthetic) {
- // Avoid visiting a field twice
- if (propertyAccessor.isGetter) {
- addSuggestion(propertyAccessor.variable);
- }
- } else {
- addSuggestion(propertyAccessor);
- }
- }
- }
- }
- }
-
- /**
- * Get a list of [InterfaceType]s that should be searched to find the
- * possible completions for an object having type [type].
- */
- List<InterfaceType> _getTypeOrdering(InterfaceType type) {
- // Candidate completions can come from [type] as well as any types above it
- // in the class hierarchy (including mixins, superclasses, and interfaces).
- // If a given completion identifier shows up in multiple types, we should
- // use the element that is nearest in the superclass chain, so we will
- // visit [type] first, then its mixins, then its superclass, then its
- // superclass's mixins, etc., and only afterwards visit interfaces.
- //
- // We short-circuit loops in the class hierarchy by keeping track of the
- // classes seen (not the interfaces) so that we won't be fooled by nonsense
- // like "class C<T> extends C<List<T>> {}"
- List<InterfaceType> result = <InterfaceType>[];
- Set<ClassElement> classesSeen = new HashSet<ClassElement>();
- List<InterfaceType> typesToVisit = <InterfaceType>[type];
- while (typesToVisit.isNotEmpty) {
- InterfaceType nextType = typesToVisit.removeLast();
- if (!classesSeen.add(nextType.element)) {
- // Class had already been seen, so ignore this type.
- continue;
- }
- result.add(nextType);
- // typesToVisit is a stack, so push on the interfaces first, then the
- // superclass, then the mixins. This will ensure that they are visited
- // in the reverse order.
- typesToVisit.addAll(nextType.interfaces);
- if (nextType.superclass != null) {
- typesToVisit.add(nextType.superclass);
- }
- typesToVisit.addAll(nextType.mixins);
- }
- return result;
- }
-
- /**
- * Add suggestions for the visible members in the given interface
- */
- static void suggestionsFor(DartCompletionRequest request, DartType type,
- {bool isSuper: false, String containingMethodName: null}) {
- CompilationUnit compilationUnit =
- request.target.containingNode.getAncestor((n) => n is CompilationUnit);
- CompilationUnitElement unitElem = compilationUnit.element;
- if (unitElem == null) {
- engine.AnalysisEngine.instance.logger
- .logInformation('Completion expected resolved AST');
- return;
- }
- LibraryElement library = unitElem.library;
- if (type is DynamicTypeImpl) {
- type = request.cache.objectClassElement.type;
- }
- if (type is InterfaceType) {
- new InterfaceTypeSuggestionBuilder(request)
- ._buildSuggestions(type, library, isSuper, containingMethodName);
- }
- }
-}
-
-/**
- * This class visits elements in a library and provides suggestions based upon
- * the visible members in that library. Clients should call
- * [LibraryElementSuggestionBuilder.suggestionsFor].
- */
-class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor
- with ElementSuggestionBuilder {
- final DartCompletionRequest request;
- final CompletionSuggestionKind kind;
- final bool typesOnly;
- final bool instCreation;
-
- LibraryElementSuggestionBuilder(
- this.request, this.kind, this.typesOnly, this.instCreation);
-
- @override
- visitClassElement(ClassElement element) {
- if (instCreation) {
- element.visitChildren(this);
- } else {
- addSuggestion(element);
- }
- }
-
- @override
- visitCompilationUnitElement(CompilationUnitElement element) {
- element.visitChildren(this);
- LibraryElement containingLibrary = element.library;
- if (containingLibrary != null) {
- for (var lib in containingLibrary.exportedLibraries) {
- lib.visitChildren(this);
- }
- }
- }
-
- @override
- visitConstructorElement(ConstructorElement element) {
- if (instCreation) {
- ClassElement classElem = element.enclosingElement;
- if (classElem != null) {
- String prefix = classElem.name;
- if (prefix != null && prefix.length > 0) {
- addSuggestion(element, prefix: prefix);
- }
- }
- }
- }
-
- @override
- visitElement(Element element) {
- // ignored
- }
-
- @override
- visitFunctionElement(FunctionElement element) {
- if (!typesOnly) {
- addSuggestion(element);
- }
- }
-
- @override
- visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
- if (!instCreation) {
- addSuggestion(element);
- }
- }
-
- @override
- visitTopLevelVariableElement(TopLevelVariableElement element) {
- if (!typesOnly) {
- addSuggestion(element);
- }
- }
-
- /**
- * Add suggestions for the visible members in the given library
- */
- static void suggestionsFor(
- DartCompletionRequest request,
- CompletionSuggestionKind kind,
- LibraryElement library,
- bool typesOnly,
- bool instCreation) {
- if (library != null) {
- library.visitChildren(new LibraryElementSuggestionBuilder(
- request, kind, typesOnly, instCreation));
- }
- }
-}
-
-/**
- * This class visits elements in a class and provides suggestions based upon
- * the visible named constructors in that class.
- */
-class NamedConstructorSuggestionBuilder extends GeneralizingElementVisitor
- with ElementSuggestionBuilder
- implements SuggestionBuilder {
- final DartCompletionRequest request;
-
- NamedConstructorSuggestionBuilder(this.request);
-
- @override
- CompletionSuggestionKind get kind => CompletionSuggestionKind.INVOCATION;
-
- @override
- bool computeFast(AstNode node) {
- return false;
- }
-
- @override
- Future<bool> computeFull(AstNode node) {
- if (node is SimpleIdentifier) {
- node = node.parent;
- }
- if (node is ConstructorName) {
- TypeName typeName = node.type;
- if (typeName != null) {
- DartType type = typeName.type;
- if (type != null) {
- if (type.element is ClassElement) {
- type.element.accept(this);
- }
- return new Future.value(true);
- }
- }
- }
- return new Future.value(false);
- }
-
- @override
- visitClassElement(ClassElement element) {
- element.visitChildren(this);
- }
-
- @override
- visitConstructorElement(ConstructorElement element) {
- addSuggestion(element);
- }
-
- @override
- visitElement(Element element) {
- // ignored
- }
-}
-
-/**
- * This class visits elements in a class and provides suggestions based upon
- * the visible static members in that class. Clients should call
- * [StaticClassElementSuggestionBuilder.suggestionsFor].
- */
-class StaticClassElementSuggestionBuilder extends GeneralizingElementVisitor
- with ElementSuggestionBuilder {
- final DartCompletionRequest request;
-
- StaticClassElementSuggestionBuilder(this.request);
-
- @override
- CompletionSuggestionKind get kind => CompletionSuggestionKind.INVOCATION;
-
- @override
- visitClassElement(ClassElement element) {
- element.visitChildren(this);
- element.allSupertypes.forEach((InterfaceType type) {
- type.element.visitChildren(this);
- });
- }
-
- @override
- visitElement(Element element) {
- // ignored
- }
-
- @override
- visitFieldElement(FieldElement element) {
- if (!element.isStatic) {
- return;
- }
- addSuggestion(element);
- }
-
- @override
- visitMethodElement(MethodElement element) {
- if (!element.isStatic) {
- return;
- }
- if (element.isOperator) {
- return;
- }
- addSuggestion(element);
- }
-
- @override
- visitPropertyAccessorElement(PropertyAccessorElement element) {
- if (!element.isStatic) {
- return;
- }
- addSuggestion(element);
- }
-
- /**
- * Add suggestions for the visible members in the given class
- */
- static void suggestionsFor(DartCompletionRequest request, Element element) {
- if (element == DynamicElementImpl.instance) {
- element = request.cache.objectClassElement;
- }
- if (element is ClassElement) {
- return element.accept(new StaticClassElementSuggestionBuilder(request));
- }
- }
-}
-
-/**
* Common interface implemented by suggestion builders.
*/
abstract class SuggestionBuilder {
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 c6f1c02..00c48a3 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -413,8 +413,8 @@
if (token is DocumentationCommentToken &&
token.type == TokenType.SINGLE_LINE_COMMENT) {
sb.append(prefix);
- sb.append(' * ');
- sb.append(token.lexeme.substring('/// '.length));
+ sb.append(' *');
+ sb.append(token.lexeme.substring('///'.length));
sb.append(eol);
} else {
return;
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 f068b3b..18465d0 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -453,11 +453,7 @@
PartDirective directive = node.parent;
Source partSource = directive.source;
CompilationUnit partUnit;
- if (AnalysisEngine.instance.useTaskModel) {
- partUnit = context.getResolvedCompilationUnit2(partSource, partSource);
- } else {
- partUnit = context.getResolvedCompilationUnit2(partSource, unitSource);
- }
+ partUnit = context.getResolvedCompilationUnit2(partSource, partSource);
if (partUnit != null) {
CorrectionUtils partUtils = new CorrectionUtils(partUnit);
CorrectionUtils_InsertDesc desc = partUtils.getInsertDescTop();
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
index ad42a6e..f238cd5 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
@@ -59,6 +59,7 @@
unitElement = unit.element;
selectionRange = new SourceRange(selectionOffset, selectionLength);
utils = new CorrectionUtils(unit);
+ file = unitElement.source.fullName;
}
@override
@@ -117,6 +118,7 @@
} else {
occurrences = [selectionRange];
}
+ occurrences.sort((a, b) => a.offset - b.offset);
// If the whole expression of a statement is selected, like '1 + 2',
// then convert it into a variable declaration statement.
if (wholeStatementExpression && occurrences.length == 1) {
@@ -127,36 +129,53 @@
doSourceChange_addElementEdit(change, unitElement, edit);
return new Future.value(change);
}
+ // prepare positions
+ List<Position> positions = <Position>[];
+ int occurrencesShift = 0;
+ void addPosition(int offset) {
+ positions.add(new Position(file, offset));
+ }
// add variable declaration
{
- String declarationSource;
+ String declarationCode;
+ int nameOffsetInDeclarationCode;
if (stringLiteralPart != null) {
- declarationSource = "var $name = '$stringLiteralPart';";
+ declarationCode = 'var ';
+ nameOffsetInDeclarationCode = declarationCode.length;
+ declarationCode += "$name = '$stringLiteralPart';";
} else {
String keyword = _declarationKeyword;
- String initializerSource = utils.getRangeText(selectionRange);
- declarationSource = "$keyword $name = $initializerSource;";
+ String initializerCode = utils.getRangeText(selectionRange);
+ declarationCode = '$keyword ';
+ nameOffsetInDeclarationCode = declarationCode.length;
+ declarationCode += '$name = $initializerCode;';
}
- String eol = utils.endOfLine;
// prepare location for declaration
AstNode target = _findDeclarationTarget(occurrences);
+ String eol = utils.endOfLine;
// insert variable declaration
if (target is Statement) {
String prefix = utils.getNodePrefix(target);
SourceEdit edit =
- new SourceEdit(target.offset, 0, declarationSource + eol + prefix);
+ new SourceEdit(target.offset, 0, declarationCode + eol + prefix);
doSourceChange_addElementEdit(change, unitElement, edit);
+ addPosition(edit.offset + nameOffsetInDeclarationCode);
+ occurrencesShift = edit.replacement.length;
} else if (target is ExpressionFunctionBody) {
String prefix = utils.getNodePrefix(target.parent);
String indent = utils.getIndent(1);
- String declStatement = prefix + indent + declarationSource + eol;
- String exprStatement = prefix + indent + 'return ';
Expression expr = target.expression;
- doSourceChange_addElementEdit(
- change,
- unitElement,
- new SourceEdit(target.offset, expr.offset - target.offset,
- '{' + eol + declStatement + exprStatement));
+ {
+ String code = '{' + eol + prefix + indent;
+ addPosition(
+ target.offset + code.length + nameOffsetInDeclarationCode);
+ code += declarationCode + eol;
+ code += prefix + indent + 'return ';
+ SourceEdit edit =
+ new SourceEdit(target.offset, expr.offset - target.offset, code);
+ occurrencesShift = target.offset + code.length - expr.offset;
+ doSourceChange_addElementEdit(change, unitElement, edit);
+ }
doSourceChange_addElementEdit(change, unitElement,
new SourceEdit(expr.end, 0, ';' + eol + prefix + '}'));
}
@@ -165,12 +184,23 @@
String occurrenceReplacement = name;
if (stringLiteralPart != null) {
occurrenceReplacement = "\${$name}";
+ occurrencesShift += 2;
}
// replace occurrences with variable reference
for (SourceRange range in occurrences) {
SourceEdit edit = newSourceEdit_range(range, occurrenceReplacement);
+ addPosition(range.offset + occurrencesShift);
+ occurrencesShift += name.length - range.length;
doSourceChange_addElementEdit(change, unitElement, edit);
}
+ // add the linked group
+ change.addLinkedEditGroup(new LinkedEditGroup(
+ positions,
+ name.length,
+ names
+ .map((name) => new LinkedEditSuggestion(
+ name, LinkedEditSuggestionKind.VARIABLE))
+ .toList()));
// done
return new Future.value(change);
}
@@ -194,8 +224,9 @@
selectionRange = new SourceRange(offset, end - offset);
}
// get covering node
- AstNode coveringNode = new NodeLocator(
- selectionRange.offset, selectionRange.end).searchWithin(unit);
+ AstNode coveringNode =
+ new NodeLocator(selectionRange.offset, selectionRange.end)
+ .searchWithin(unit);
// compute covering expressions
for (AstNode node = coveringNode;
node is Expression || node is ArgumentList;
diff --git a/pkg/analysis_server/lib/src/status/element_writer.dart b/pkg/analysis_server/lib/src/status/element_writer.dart
index fd73cef..24c922d 100644
--- a/pkg/analysis_server/lib/src/status/element_writer.dart
+++ b/pkg/analysis_server/lib/src/status/element_writer.dart
@@ -7,7 +7,7 @@
import 'dart:collection';
import 'dart:convert';
-import 'package:analysis_server/src/get_handler.dart';
+import 'package:analysis_server/src/status/get_handler.dart';
import 'package:analysis_server/src/status/tree_writer.dart';
import 'package:analyzer/src/generated/element.dart';
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index 05937c0..23126f9 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -24,14 +24,15 @@
import 'package:analysis_server/src/socket_server.dart';
import 'package:analysis_server/src/status/ast_writer.dart';
import 'package:analysis_server/src/status/element_writer.dart';
+import 'package:analysis_server/src/status/validator.dart';
import 'package:analysis_server/src/utilities/average.dart';
import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl;
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart'
- hide AnalysisCache, AnalysisContextImpl, AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -93,6 +94,17 @@
static const String COMMUNICATION_PERFORMANCE_PATH = '/perf/communication';
/**
+ * The path used to request diagnostic information for a single context.
+ */
+ static const String CONTEXT_DIAGNOSTICS_PATH = '/diagnostic/context';
+
+ /**
+ * The path used to request running a validation report for a single context.
+ */
+ static const String CONTEXT_VALIDATION_DIAGNOSTICS_PATH =
+ '/diagnostic/contextValidation';
+
+ /**
* The path used to request information about a specific context.
*/
static const String CONTEXT_PATH = '/context';
@@ -221,7 +233,7 @@
*/
void handleGetRequest(HttpRequest request) {
String path = request.uri.path;
- if (path == STATUS_PATH) {
+ if (path == '/' || path == STATUS_PATH) {
_returnServerStatus(request);
} else if (path == ANALYSIS_PERFORMANCE_PATH) {
_returnAnalysisPerformance(request);
@@ -235,6 +247,10 @@
_returnCompletionInfo(request);
} else if (path == COMMUNICATION_PERFORMANCE_PATH) {
_returnCommunicationPerformance(request);
+ } else if (path == CONTEXT_DIAGNOSTICS_PATH) {
+ _returnContextDiagnostics(request);
+ } else if (path == CONTEXT_VALIDATION_DIAGNOSTICS_PATH) {
+ _returnContextValidationDiagnostics(request);
} else if (path == CONTEXT_PATH) {
_returnContextInfo(request);
} else if (path == DIAGNOSTIC_PATH) {
@@ -973,6 +989,34 @@
}
/**
+ * Return a response displaying diagnostic information for a single context.
+ */
+ void _returnContextDiagnostics(HttpRequest request) {
+ AnalysisServer analysisServer = _server.analysisServer;
+ if (analysisServer == null) {
+ return _returnFailure(request, 'Analysis server is not running');
+ }
+ String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+ if (contextFilter == null) {
+ return _returnFailure(
+ request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+ }
+ Folder folder = _findFolder(analysisServer, contextFilter);
+ if (folder == null) {
+ return _returnFailure(request, 'Invalid context: $contextFilter');
+ }
+
+ InternalAnalysisContext context = analysisServer.folderMap[folder];
+
+ _writeResponse(request, (StringBuffer buffer) {
+ _writePage(buffer, 'Analysis Server - Context Diagnostics',
+ ['Context: $contextFilter'], (StringBuffer buffer) {
+ _writeContextDiagnostics(buffer, context);
+ });
+ });
+ }
+
+ /**
* Return a response containing information about a single source file in the
* cache.
*/
@@ -1032,9 +1076,6 @@
explicitNames.sort();
implicitNames.sort();
- AnalysisDriver driver = (context as AnalysisContextImpl).driver;
- List<WorkItem> workItems = driver.currentWorkOrder?.workItems;
-
_overlayContents.clear();
context.visitContentCache((String fullName, int stamp, String contents) {
_overlayContents[fullName] = contents;
@@ -1065,69 +1106,54 @@
_writePage(
buffer, 'Analysis Server - Context', ['Context: $contextFilter'],
(StringBuffer buffer) {
- buffer.write('<h3>Most Recently Perfomed Tasks</h3>');
- AnalysisTask.LAST_TASKS.forEach((String description) {
- buffer.write('<p>$description</p>');
- });
-
- String _describe(WorkItem item) {
- if (item == null) {
- return 'None';
- }
- return '${item.descriptor?.name} computing ${item.spawningResult?.name} for ${item.target?.toString()}';
- }
-
- buffer.write('<h3>Work Items</h3>');
- buffer.write(
- '<p><b>Current:</b> ${_describe(driver.currentWorkOrder?.current)}</p>');
- if (workItems != null) {
- buffer.writeAll(workItems.reversed
- .map((item) => '<p>${_describe(item)}</p>')
- ?.toList());
- }
-
buffer.write('<h3>Configuration</h3>');
- AnalysisOptionsImpl options = context.analysisOptions;
- buffer.write('<p><b>Options</b></p>');
- buffer.write('<p>');
- _writeOption(
- buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
- _writeOption(buffer, 'Cache size', options.cacheSize);
- _writeOption(
- buffer, 'Enable generic methods', options.enableGenericMethods);
- _writeOption(buffer, 'Enable strict call checks',
- options.enableStrictCallChecks);
- _writeOption(buffer, 'Enable super mixins', options.enableSuperMixins);
- _writeOption(buffer, 'Generate dart2js hints', options.dart2jsHint);
- _writeOption(buffer, 'Generate errors in implicit files',
- options.generateImplicitErrors);
- _writeOption(
- buffer, 'Generate errors in SDK files', options.generateSdkErrors);
- _writeOption(buffer, 'Generate hints', options.hint);
- _writeOption(buffer, 'Incremental resolution', options.incremental);
- _writeOption(buffer, 'Incremental resolution with API changes',
- options.incrementalApi);
- _writeOption(buffer, 'Preserve comments', options.preserveComments);
- _writeOption(buffer, 'Strong mode', options.strongMode);
- _writeOption(buffer, 'Strong mode hints', options.strongModeHints,
- last: true);
- buffer.write('</p>');
-
- List<Linter> lints = context.getConfigurationData(CONFIGURED_LINTS_KEY);
- buffer.write('<p><b>Lints</b></p>');
- if (lints.isEmpty) {
- buffer.write('<p><none></p>');
- } else {
- for (Linter lint in lints) {
- buffer.write('<p> ${lint.runtimeType}</p>');
+ _writeTwoColumns(buffer, (StringBuffer buffer) {
+ AnalysisOptionsImpl options = context.analysisOptions;
+ buffer.write('<p><b>Options</b></p>');
+ buffer.write('<p>');
+ _writeOption(
+ buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
+ _writeOption(buffer, 'Cache size', options.cacheSize);
+ _writeOption(
+ buffer, 'Enable generic methods', options.enableGenericMethods);
+ _writeOption(buffer, 'Enable strict call checks',
+ options.enableStrictCallChecks);
+ _writeOption(
+ buffer, 'Enable super mixins', options.enableSuperMixins);
+ _writeOption(buffer, 'Generate dart2js hints', options.dart2jsHint);
+ _writeOption(buffer, 'Generate errors in implicit files',
+ options.generateImplicitErrors);
+ _writeOption(buffer, 'Generate errors in SDK files',
+ options.generateSdkErrors);
+ _writeOption(buffer, 'Generate hints', options.hint);
+ _writeOption(buffer, 'Incremental resolution', options.incremental);
+ _writeOption(buffer, 'Incremental resolution with API changes',
+ options.incrementalApi);
+ _writeOption(buffer, 'Preserve comments', options.preserveComments);
+ _writeOption(buffer, 'Strong mode', options.strongMode);
+ _writeOption(buffer, 'Strong mode hints', options.strongModeHints,
+ last: true);
+ buffer.write('</p>');
+ }, (StringBuffer buffer) {
+ List<Linter> lints =
+ context.getConfigurationData(CONFIGURED_LINTS_KEY);
+ buffer.write('<p><b>Lints</b></p>');
+ if (lints.isEmpty) {
+ buffer.write('<p>none</p>');
+ } else {
+ for (Linter lint in lints) {
+ buffer.write('<p>');
+ buffer.write(lint.runtimeType);
+ buffer.write('</p>');
+ }
}
- }
- List<ErrorFilter> errorFilters =
- context.getConfigurationData(CONFIGURED_ERROR_FILTERS);
- int filterCount = errorFilters?.length ?? 0;
- buffer.write('<p><b>Error Filter count</b>: $filterCount</p>');
+ List<ErrorProcessor> errorProcessors =
+ context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+ int processorCount = errorProcessors?.length ?? 0;
+ buffer.write('<p><b>Error Processor count</b>: $processorCount</p>');
+ });
_writeFiles(buffer, 'Priority Files', priorityNames);
_writeFiles(buffer, 'Explicitly Analyzed Files', explicitNames);
@@ -1135,12 +1161,59 @@
buffer.write('<h3>Exceptions</h3>');
if (exceptions.isEmpty) {
- buffer.write('<p>None</p>');
+ buffer.write('<p>none</p>');
} else {
exceptions.forEach((CaughtException exception) {
_writeException(buffer, exception);
});
}
+
+ buffer.write('<h3>Targets Without Entries</h3>');
+ bool foundEntry = false;
+ MapIterator<AnalysisTarget, CacheEntry> iterator =
+ context.analysisCache.iterator(context: context);
+ while (iterator.moveNext()) {
+ if (iterator.value == null) {
+ foundEntry = true;
+ buffer.write('<p>');
+ buffer.write(iterator.key.toString());
+ buffer.write(' (');
+ buffer.write(iterator.key.runtimeType.toString());
+ buffer.write(')</p>');
+ }
+ }
+ if (!foundEntry) {
+ buffer.write('<p>none</p>');
+ }
+ });
+ });
+ }
+
+ /**
+ * Return a response displaying the results of running a validation report on
+ * a single context.
+ */
+ void _returnContextValidationDiagnostics(HttpRequest request) {
+ AnalysisServer analysisServer = _server.analysisServer;
+ if (analysisServer == null) {
+ return _returnFailure(request, 'Analysis server is not running');
+ }
+ String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+ if (contextFilter == null) {
+ return _returnFailure(
+ request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+ }
+ Folder folder = _findFolder(analysisServer, contextFilter);
+ if (folder == null) {
+ return _returnFailure(request, 'Invalid context: $contextFilter');
+ }
+
+ InternalAnalysisContext context = analysisServer.folderMap[folder];
+
+ _writeResponse(request, (StringBuffer buffer) {
+ _writePage(buffer, 'Analysis Server - Context Validation Diagnostics',
+ ['Context: $contextFilter'], (StringBuffer buffer) {
+ _writeContextValidationDiagnostics(buffer, context);
});
});
}
@@ -1149,8 +1222,6 @@
* Return a response displaying diagnostic information.
*/
void _returnDiagnosticInfo(HttpRequest request) {
- String value = request.requestedUri.queryParameters['index'];
- int index = value != null ? int.parse(value, onError: (_) => 0) : 0;
_writeResponse(request, (StringBuffer buffer) {
_writePage(buffer, 'Analysis Server - Diagnostic info', [],
(StringBuffer buffer) {
@@ -1332,23 +1403,19 @@
void _returnUnknownRequest(HttpRequest request) {
_writeResponse(request, (StringBuffer buffer) {
_writePage(buffer, 'Analysis Server', [], (StringBuffer buffer) {
- buffer.write('<h3>Pages</h3>');
- buffer.write('<p>');
- buffer.write(makeLink(COMPLETION_PATH, {}, 'Completion data'));
- buffer.write('</p>');
- buffer.write('<p>');
- buffer
- .write(makeLink(COMMUNICATION_PERFORMANCE_PATH, {}, 'Performance'));
- buffer.write('</p>');
- buffer.write('<p>');
- buffer.write(makeLink(STATUS_PATH, {}, 'Server status'));
- buffer.write('</p>');
- buffer.write('<p>');
- buffer.write(makeLink(OVERLAYS_PATH, {}, 'File overlays'));
- buffer.write('</p>');
- buffer.write('<p>');
- buffer.write(makeLink(DIAGNOSTIC_PATH, {}, 'Diagnostic info'));
- buffer.write('</p>');
+ buffer.write('<h3>Unknown page: ');
+ buffer.write(request.uri.path);
+ buffer.write('</h3>');
+ buffer.write('''
+ <p>
+ You have reached an un-recognized page. If you reached this page by
+ following a link from a status page, please report the broken link to
+ the Dart analyzer team:
+ <a>https://github.com/dart-lang/sdk/issues/new</a>.
+ </p><p>
+ If you mistyped the URL, you can correct it or return to
+ ${makeLink(STATUS_PATH, {}, 'the main status page')}.
+ </p>''');
});
});
}
@@ -1374,7 +1441,6 @@
List<Folder> folders = folderMap.keys.toList();
folders.sort((Folder first, Folder second) =>
first.shortName.compareTo(second.shortName));
- AnalysisOptionsImpl options = analysisServer.defaultContextOptions;
ServerOperationQueue operationQueue = analysisServer.operationQueue;
buffer.write('<h3>Analysis Domain</h3>');
@@ -1394,6 +1460,9 @@
buffer.write('<p>Status: Analyzing</p>');
}
}
+ buffer.write('<p>');
+ buffer.write(makeLink(OVERLAYS_PATH, {}, 'All overlay information'));
+ buffer.write('</p>');
buffer.write('<p><b>Analysis Contexts</b></p>');
buffer.write('<p>');
@@ -1407,8 +1476,12 @@
String key = folder.shortName;
buffer.write(makeLink(CONTEXT_PATH, {CONTEXT_QUERY_PARAM: folder.path},
key, _hasException(folderMap[folder])));
+ buffer.write(' <small><b>[');
+ buffer.write(makeLink(CONTEXT_DIAGNOSTICS_PATH,
+ {CONTEXT_QUERY_PARAM: folder.path}, 'diagnostics'));
+ buffer.write(']</b></small>');
if (!folder.getChild('.packages').exists) {
- buffer.write(' <b>[No .packages file]</b>');
+ buffer.write(' <small>[no .packages file]</small>');
}
});
// TODO(brianwilkerson) Add items for the SDK contexts (currently only one).
@@ -1416,9 +1489,9 @@
int freq = AnalysisServer.performOperationDelayFreqency;
String delay = freq > 0 ? '1 ms every $freq ms' : 'off';
- buffer.write('<p><b>perform operation delay:</b> $delay</p>');
buffer.write('<p><b>Performance Data</b></p>');
+ buffer.write('<p>Perform operation delay: $delay</p>');
buffer.write('<p>');
buffer.write(makeLink(ANALYSIS_PERFORMANCE_PATH, {}, 'Task data'));
buffer.write('</p>');
@@ -1531,6 +1604,70 @@
}
/**
+ * Write diagnostic information about the given [context] to the given
+ * [buffer].
+ */
+ void _writeContextDiagnostics(
+ StringBuffer buffer, InternalAnalysisContext context) {
+ AnalysisDriver driver = (context as AnalysisContextImpl).driver;
+ List<WorkItem> workItems = driver.currentWorkOrder?.workItems;
+
+ buffer.write('<p>');
+ buffer.write(makeLink(CONTEXT_VALIDATION_DIAGNOSTICS_PATH,
+ {CONTEXT_QUERY_PARAM: context.name}, 'Run validation'));
+ buffer.write('</p>');
+
+ buffer.write('<h3>Most Recently Perfomed Tasks</h3>');
+ AnalysisTask.LAST_TASKS.forEach((String description) {
+ buffer.write('<p>');
+ buffer.write(description);
+ buffer.write('</p>');
+ });
+
+ void writeWorkItem(StringBuffer buffer, WorkItem item) {
+ if (item == null) {
+ buffer.write('none');
+ } else {
+ buffer.write(item.descriptor?.name);
+ buffer.write(' computing ');
+ buffer.write(item.spawningResult?.name);
+ buffer.write(' for ');
+ buffer.write(item.target);
+ }
+ }
+
+ buffer.write('<h3>Work Items</h3>');
+ buffer.write('<p><b>Current:</b> ');
+ writeWorkItem(buffer, driver.currentWorkOrder?.current);
+ buffer.write('</p>');
+ if (workItems != null) {
+ workItems.reversed.forEach((WorkItem item) {
+ buffer.write('<p>');
+ writeWorkItem(buffer, item);
+ buffer.write('</p>');
+ });
+ }
+ }
+
+ /**
+ * Write diagnostic information about the given [context] to the given
+ * [buffer].
+ */
+ void _writeContextValidationDiagnostics(
+ StringBuffer buffer, InternalAnalysisContext context) {
+ Stopwatch stopwatch = new Stopwatch();
+ stopwatch.start();
+ ValidationResults results = new ValidationResults(context);
+ stopwatch.stop();
+
+ buffer.write('<h3>Validation Results</h3>');
+ buffer.write('<p>Re-analysis took ');
+ buffer.write(stopwatch.elapsedMilliseconds);
+ buffer.write(' ms</p>');
+ results.writeOn(buffer);
+ }
+
+ /**
* Write the status of the diagnostic domain to the given [buffer].
*/
void _writeDiagnosticStatus(StringBuffer buffer) {
@@ -1546,28 +1683,32 @@
buffer.write('<h3>Timing</h3>');
- buffer.write('<p>');
- buffer.write('getDiagnostic (last call): $elapsedMs (ms)');
- buffer.write('<p>');
- buffer.write('getDiagnostic (rolling average): '
- '${_diagnosticCallAverage.value} (ms)');
- buffer.write('<p> ');
+ buffer.write('<p>getDiagnostic (last call): ');
+ buffer.write(elapsedMs);
+ buffer.write(' (ms)</p>');
+ buffer.write('<p>getDiagnostic (rolling average): ');
+ buffer.write(_diagnosticCallAverage.value);
+ buffer.write(' (ms)</p> ');
var json = response.toJson()[Response.RESULT];
List contexts = json['contexts'];
+ contexts.sort((first, second) => first['name'].compareTo(second['name']));
for (var context in contexts) {
- buffer.write('<p>');
- buffer.write('<h3>${context["name"]}</h3>');
- buffer.write('<p>');
- buffer.write('explicitFileCount: ${context["explicitFileCount"]}');
- buffer.write('<p>');
- buffer.write('implicitFileCount: ${context["implicitFileCount"]}');
- buffer.write('<p>');
- buffer.write('workItemQueueLength: ${context["workItemQueueLength"]}');
- buffer.write('<p>');
- buffer.write('workItemQueueLengthAverage: '
- '${context["workItemQueueLengthAverage"]}');
- buffer.write('<p> ');
+ buffer.write('<p><h3>');
+ buffer.write(context['name']);
+ buffer.write('</h3></p>');
+ buffer.write('<p>explicitFileCount: ');
+ buffer.write(context['explicitFileCount']);
+ buffer.write('</p>');
+ buffer.write('<p>implicitFileCount: ');
+ buffer.write(context['implicitFileCount']);
+ buffer.write('</p>');
+ buffer.write('<p>workItemQueueLength: ');
+ buffer.write(context['workItemQueueLength']);
+ buffer.write('</p>');
+ buffer.write('<p>workItemQueueLengthAverage: ');
+ buffer.write(context['workItemQueueLengthAverage']);
+ buffer.write('</p>');
}
}
@@ -1708,6 +1849,8 @@
buffer.write(
'h3 {background-color: #DDDDDD; margin-top: 0em; margin-bottom: 0em;}');
buffer.write('p {margin-top: 0.5em; margin-bottom: 0.5em;}');
+ buffer.write(
+ 'p.commentary {margin-top: 1em; margin-bottom: 1em; margin-left: 2em; font-style: italic;}');
// response.write('span.error {text-decoration-line: underline; text-decoration-color: red; text-decoration-style: wavy;}');
buffer.write(
'table.column {border: 0px solid black; width: 100%; table-layout: fixed;}');
@@ -1868,6 +2011,9 @@
buffer.write(makeLink(
COMMUNICATION_PERFORMANCE_PATH, {}, 'Communication performance'));
buffer.write('</p>');
+ buffer.write('<p>');
+ buffer.write(makeLink(DIAGNOSTIC_PATH, {}, 'General diagnostics'));
+ buffer.write('</p>');
}, (StringBuffer buffer) {
_writeSubscriptionList(buffer, ServerService.VALUES, services);
});
diff --git a/pkg/analysis_server/lib/src/status/tree_writer.dart b/pkg/analysis_server/lib/src/status/tree_writer.dart
index 4b5b3a4..c862a8b 100644
--- a/pkg/analysis_server/lib/src/status/tree_writer.dart
+++ b/pkg/analysis_server/lib/src/status/tree_writer.dart
@@ -2,11 +2,11 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analysis_server.src.status.ast_writer;
+library analysis_server.src.status.tree_writer;
import 'dart:convert';
-import 'package:analysis_server/src/get_handler.dart';
+import 'package:analysis_server/src/status/get_handler.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/java_engine.dart';
diff --git a/pkg/analysis_server/lib/src/status/validator.dart b/pkg/analysis_server/lib/src/status/validator.dart
new file mode 100644
index 0000000..dccf996
--- /dev/null
+++ b/pkg/analysis_server/lib/src/status/validator.dart
@@ -0,0 +1,1787 @@
+// 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 analysis_server.src.status.validator;
+
+import 'dart:collection';
+
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart'
+ show AnalysisEngine, AnalysisResult, CacheState, ChangeSet;
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/src/task/html.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/model.dart';
+import 'package:html/dom.dart' as html;
+
+/**
+ * A class used to compare two element models for equality.
+ */
+class ElementComparator {
+ /**
+ * The buffer to which any discovered differences will be recorded.
+ */
+ final StringBuffer _buffer = new StringBuffer();
+
+ /**
+ * A flag indicating whether a line break should be added the next time data
+ * is written to the [_buffer].
+ */
+ bool _needsLineBreak = false;
+
+ /**
+ * Initialize a newly created comparator.
+ */
+ ElementComparator();
+
+ /**
+ * A textual description of the differences that were found.
+ */
+ String get description => _buffer.toString();
+
+ /**
+ * Return `true` if at least one difference was found between the expected and
+ * actual elements.
+ */
+ bool get hasDifference => _buffer.length > 0;
+
+ /**
+ * Compare the [expected] and [actual] elements. The results of the comparison
+ * can be accessed via the [hasDifference] and [description] getters.
+ */
+ void compareElements(Element expected, Element actual) {
+ if (expected == null) {
+ if (actual != null) {
+ _writeMismatch(expected, actual, (Element element) {
+ return element == null ? 'null' : 'non null ${element.runtimeType}';
+ });
+ }
+ } else if (actual == null) {
+ _writeMismatch(expected, actual, (Element element) {
+ return element == null ? 'null' : 'non null ${element.runtimeType}';
+ });
+ } else if (expected is ClassElement && actual is ClassElement) {
+ _compareClassElements(expected, actual);
+ } else if (expected is CompilationUnitElement &&
+ actual is CompilationUnitElement) {
+ _compareCompilationUnitElements(expected, actual);
+ } else if (expected is ConstructorElement && actual is ConstructorElement) {
+ _compareConstructorElements(expected, actual);
+ } else if (expected is ExportElement && actual is ExportElement) {
+ _compareExportElements(expected, actual);
+ } else if (expected is FieldElement && actual is FieldElement) {
+ _compareFieldElements(expected, actual);
+ } else if (expected is FieldFormalParameterElement &&
+ actual is FieldFormalParameterElement) {
+ _compareFieldFormalParameterElements(expected, actual);
+ } else if (expected is FunctionElement && actual is FunctionElement) {
+ _compareFunctionElements(expected, actual);
+ } else if (expected is FunctionTypeAliasElement &&
+ actual is FunctionTypeAliasElement) {
+ _compareFunctionTypeAliasElements(expected, actual);
+ } else if (expected is ImportElement && actual is ImportElement) {
+ _compareImportElements(expected, actual);
+ } else if (expected is LabelElement && actual is LabelElement) {
+ _compareLabelElements(expected, actual);
+ } else if (expected is LibraryElement && actual is LibraryElement) {
+ _compareLibraryElements(expected, actual);
+ } else if (expected is LocalVariableElement &&
+ actual is LocalVariableElement) {
+ _compareLocalVariableElements(expected, actual);
+ } else if (expected is MethodElement && actual is MethodElement) {
+ _compareMethodElements(expected, actual);
+ } else if (expected is MultiplyDefinedElement &&
+ actual is MultiplyDefinedElement) {
+ _compareMultiplyDefinedElements(expected, actual);
+ } else if (expected is ParameterElement && actual is ParameterElement) {
+ _compareParameterElements(expected, actual);
+ } else if (expected is PrefixElement && actual is PrefixElement) {
+ _comparePrefixElements(expected, actual);
+ } else if (expected is PropertyAccessorElement &&
+ actual is PropertyAccessorElement) {
+ _comparePropertyAccessorElements(expected, actual);
+ } else if (expected is TopLevelVariableElement &&
+ actual is TopLevelVariableElement) {
+ _compareTopLevelVariableElements(expected, actual);
+ } else if (expected is TypeParameterElement &&
+ actual is TypeParameterElement) {
+ _compareTypeParameterElements(expected, actual);
+ } else {
+ _write('Expected an instance of ');
+ _write(expected.runtimeType);
+ _write('; found an instance of ');
+ _writeln(actual.runtimeType);
+ }
+ }
+
+ void _compareClassElements(ClassElement expected, ClassElement actual) {
+ _compareGenericElements(expected, actual);
+ //
+ // Compare attributes.
+ //
+ if (expected.hasReferenceToSuper != actual.hasReferenceToSuper) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ClassElement element) => element.hasReferenceToSuper
+ ? 'a class that references super'
+ : 'a class that does not reference super');
+ }
+ if (expected.isAbstract != actual.isAbstract) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ClassElement element) =>
+ element.isAbstract ? 'an abstract class' : 'a concrete class');
+ }
+ if (expected.isEnum != actual.isEnum ||
+ expected.isMixinApplication != actual.isMixinApplication) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ClassElement element) => element.isEnum
+ ? 'an enum'
+ : (element.isMixinApplication
+ ? 'a mixin application'
+ : 'a class'));
+ }
+ if (expected.isOrInheritsProxy != actual.isOrInheritsProxy) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ClassElement element) => element.isOrInheritsProxy
+ ? 'a class that is marked as a proxy'
+ : 'a class that is not marked as a proxy');
+ }
+ if (expected.isValidMixin != actual.isValidMixin) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ClassElement element) =>
+ element.isValidMixin ? 'a valid mixin' : 'an invalid mixin');
+ }
+ _compareTypes('supertype', expected.supertype, actual.supertype);
+ _compareTypeLists('mixin', expected.mixins, actual.mixins);
+ _compareTypeLists('interface', expected.interfaces, actual.interfaces);
+ //
+ // Compare children.
+ //
+ _compareElementLists(expected.accessors, actual.accessors);
+ _compareElementLists(expected.constructors, actual.constructors);
+ _compareElementLists(expected.fields, actual.fields);
+ _compareElementLists(expected.methods, actual.methods);
+ _compareElementLists(expected.typeParameters, actual.typeParameters);
+ }
+
+ void _compareCompilationUnitElements(
+ CompilationUnitElement expected, CompilationUnitElement actual) {
+ _compareGenericElements(expected, actual);
+ //
+ // Compare children.
+ //
+ _compareElementLists(expected.accessors, actual.accessors);
+ _compareElementLists(expected.enums, actual.enums);
+ _compareElementLists(expected.functions, actual.functions);
+ _compareElementLists(
+ expected.functionTypeAliases, actual.functionTypeAliases);
+ _compareElementLists(expected.topLevelVariables, actual.topLevelVariables);
+ _compareElementLists(expected.types, actual.types);
+ }
+
+ void _compareConstructorElements(
+ ConstructorElement expected, ConstructorElement actual) {
+ _compareExecutableElements(expected, actual, 'constructor');
+ //
+ // Compare attributes.
+ //
+ if (expected.isConst != actual.isConst) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ConstructorElement element) => element.isConst
+ ? 'a const constructor'
+ : 'a non-const constructor');
+ }
+ if (expected.isFactory != actual.isFactory) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ConstructorElement element) => element.isFactory
+ ? 'a factory constructor'
+ : 'a non-factory constructor');
+ }
+ if (expected.periodOffset != actual.periodOffset) {
+ _write('Expected a period offset of ');
+ _write(expected.periodOffset);
+ _write('; found ');
+ _writeln(actual.periodOffset);
+ }
+ if ((expected.redirectedConstructor == null) !=
+ (actual.redirectedConstructor == null)) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ConstructorElement element) => element.redirectedConstructor == null
+ ? 'a redirecting constructor'
+ : 'a non-redirecting constructor');
+ }
+ }
+
+ void _compareElementLists(List expected, List actual) {
+ Set<Element> extraElements = new HashSet<Element>();
+ Map<Element, Element> commonElements = new HashMap<Element, Element>();
+
+ Map<String, Element> expectedElements = new HashMap<String, Element>();
+ for (Element expectedElement in expected) {
+ expectedElements[expectedElement.name] = expectedElement;
+ }
+ for (Element actualElement in actual) {
+ String name = actualElement.name;
+ Element expectedElement = expectedElements[name];
+ if (expectedElement == null) {
+ extraElements.add(actualElement);
+ } else {
+ commonElements[expectedElement] = actualElement;
+ expectedElements.remove(name);
+ }
+ }
+
+ commonElements.forEach((Element expected, Element actual) {
+ compareElements(expected, actual);
+ });
+ void writeElement(Element element) {
+ _write('an instance of ');
+ _write(element.runtimeType);
+ if (element.name == null) {
+ _write(' with no name');
+ } else {
+ _write(' named ');
+ _write(element.name);
+ }
+ }
+ expectedElements.forEach((String name, Element element) {
+ _write('Expected ');
+ writeElement(element);
+ _writeln('; found no match');
+ });
+ extraElements.forEach((Element element) {
+ _write('Expected nothing; found ');
+ writeElement(element);
+ });
+ }
+
+ void _compareExecutableElements(
+ ExecutableElement expected, ExecutableElement actual, String kind) {
+ _compareGenericElements(expected, actual);
+ //
+ // Compare attributes.
+ //
+ if (expected.hasImplicitReturnType != actual.hasImplicitReturnType) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ExecutableElement element) => element.hasImplicitReturnType
+ ? 'an implicit return type'
+ : 'an explicit return type');
+ }
+ if (expected.isAbstract != actual.isAbstract) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ExecutableElement element) =>
+ element.isAbstract ? 'an abstract $kind' : 'a concrete $kind');
+ }
+ if (expected.isAsynchronous != actual.isAsynchronous) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ExecutableElement element) => element.isAsynchronous
+ ? 'an asynchronous $kind'
+ : 'a synchronous $kind');
+ }
+ if (expected.isExternal != actual.isExternal) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ExecutableElement element) => element.isExternal
+ ? 'an external $kind'
+ : 'a non-external $kind');
+ }
+ if (expected.isGenerator != actual.isGenerator) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ExecutableElement element) => element.isGenerator
+ ? 'a generator $kind'
+ : 'a non-generator $kind');
+ }
+ if (expected.isOperator != actual.isOperator) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ExecutableElement element) =>
+ element.isOperator ? 'an operator' : 'a non-operator $kind');
+ }
+ if (expected.isStatic != actual.isStatic) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ExecutableElement element) =>
+ element.isStatic ? 'a static $kind' : 'an instance $kind');
+ }
+ if ((expected.returnType == null) != (actual.returnType == null)) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ExecutableElement element) => element.returnType == null
+ ? 'a $kind with no return type'
+ : 'a $kind with a return type');
+ } else {
+ _compareTypes('return type', expected.returnType, actual.returnType);
+ }
+ //
+ // Compare children.
+ //
+ _compareElementLists(expected.functions, actual.functions);
+ _compareElementLists(expected.labels, actual.labels);
+ _compareElementLists(expected.localVariables, actual.localVariables);
+ _compareElementLists(expected.parameters, actual.parameters);
+ _compareElementLists(expected.typeParameters, actual.typeParameters);
+ }
+
+ void _compareExportElements(ExportElement expected, ExportElement actual) {
+ _compareUriReferencedElements(expected, actual);
+ //
+ // Compare attributes.
+ //
+ if ((expected.exportedLibrary == null) !=
+ (actual.exportedLibrary == null)) {
+ // TODO(brianwilkerson) Check for more than existence?
+ _writeMismatch(
+ expected,
+ actual,
+ (ExportElement element) => element.exportedLibrary == null
+ ? 'unresolved uri'
+ : 'uri resolved to ${element.exportedLibrary.source.fullName}');
+ }
+ //
+ // Compare children.
+ //
+ _compareElementLists(expected.combinators, actual.combinators);
+ }
+
+ void _compareFieldElements(FieldElement expected, FieldElement actual) {
+ _comparePropertyInducingElements(expected, actual, 'field');
+ //
+ // Compare attributes.
+ //
+ if (expected.isEnumConstant != actual.isEnumConstant) {
+ _writeMismatch(
+ expected,
+ actual,
+ (FieldElement element) =>
+ element.isEnumConstant ? 'an enum constant' : 'a normal field');
+ }
+ }
+
+ void _compareFieldFormalParameterElements(
+ FieldFormalParameterElement expected,
+ FieldFormalParameterElement actual) {
+ // TODO(brianwilkerson) Implement this
+ _compareGenericElements(expected, actual);
+ }
+
+ void _compareFunctionElements(
+ FunctionElement expected, FunctionElement actual) {
+ // TODO(brianwilkerson) Implement this
+ _compareGenericElements(expected, actual);
+ }
+
+ void _compareFunctionTypeAliasElements(
+ FunctionTypeAliasElement expected, FunctionTypeAliasElement actual) {
+ // TODO(brianwilkerson) Implement this
+ _compareGenericElements(expected, actual);
+ }
+
+ void _compareGenericElements(Element expected, Element actual) {
+ _compareMetadata(expected.metadata, actual.metadata);
+ if (expected.nameOffset != actual.nameOffset) {
+ _write('Expected name offset of ');
+ _write(expected.nameOffset);
+ _write('; found ');
+ _writeln(actual.nameOffset);
+ }
+ SourceRange expectedRange = expected.docRange;
+ SourceRange actualRange = actual.docRange;
+ if (expectedRange.offset != actualRange.offset ||
+ expectedRange.length != actualRange.length) {
+ _write('Expected documentation range of ');
+ _write(expectedRange);
+ _write('; found ');
+ _writeln(actualRange);
+ }
+ }
+
+ void _compareImportElements(ImportElement expected, ImportElement actual) {
+ _compareUriReferencedElements(expected, actual);
+ //
+ // Compare attributes.
+ //
+ if (expected.isDeferred != actual.isDeferred) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ImportElement element) => element.isDeferred
+ ? 'a deferred import'
+ : 'a non-deferred import');
+ }
+ if ((expected.importedLibrary == null) !=
+ (actual.importedLibrary == null)) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ImportElement element) => element.importedLibrary == null
+ ? 'unresolved uri'
+ : 'uri resolved to ${element.importedLibrary.source.fullName}');
+ }
+ if ((expected.prefix == null) != (actual.prefix == null)) {
+ _writeMismatch(
+ expected,
+ actual,
+ (ImportElement element) => element.prefix == null
+ ? 'no prefix'
+ : 'a prefix named ${element.prefix.name}');
+ }
+ if (expected.prefixOffset != actual.prefixOffset) {
+ _write('Expected a prefix offset of ');
+ _write(expected.prefixOffset);
+ _write('; found ');
+ _writeln(actual.prefixOffset);
+ }
+ //
+ // Compare children.
+ //
+ _compareElementLists(expected.combinators, actual.combinators);
+ }
+
+ void _compareLabelElements(LabelElement expected, LabelElement actual) {
+ // TODO(brianwilkerson) Implement this
+ _compareGenericElements(expected, actual);
+ }
+
+ void _compareLibraryElements(LibraryElement expected, LibraryElement actual) {
+ _compareGenericElements(expected, actual);
+ //
+ // Compare attributes.
+ //
+ // TODO(brianwilkerson) Implement this
+ expected.hasLoadLibraryFunction;
+ expected.name;
+ expected.source;
+ //
+ // Compare children.
+ //
+ _compareElementLists(expected.imports, actual.imports);
+ _compareElementLists(expected.exports, actual.exports);
+ _compareElementLists(expected.units, actual.units);
+ }
+
+ void _compareLocalVariableElements(
+ LocalVariableElement expected, LocalVariableElement actual) {
+ // TODO(brianwilkerson) Implement this
+ _compareGenericElements(expected, actual);
+ }
+
+ void _compareMetadata(
+ List<ElementAnnotation> expected, List<ElementAnnotation> actual) {
+ // TODO(brianwilkerson) Implement this
+ }
+
+ void _compareMethodElements(MethodElement expected, MethodElement actual) {
+ // TODO(brianwilkerson) Implement this
+ _compareExecutableElements(expected, actual, 'method');
+ //
+ // Compare attributes.
+ //
+ if (expected.isStatic != actual.isStatic) {
+ _writeMismatch(
+ expected,
+ actual,
+ (FieldElement element) =>
+ element.isStatic ? 'a static field' : 'an instance field');
+ }
+ }
+
+ void _compareMultiplyDefinedElements(
+ MultiplyDefinedElement expected, MultiplyDefinedElement actual) {
+ // TODO(brianwilkerson) Implement this
+ }
+
+ void _compareParameterElements(
+ ParameterElement expected, ParameterElement actual) {
+ // TODO(brianwilkerson) Implement this
+ _compareGenericElements(expected, actual);
+ }
+
+ void _comparePrefixElements(PrefixElement expected, PrefixElement actual) {
+ // TODO(brianwilkerson) Implement this
+ _compareGenericElements(expected, actual);
+ }
+
+ void _comparePropertyAccessorElements(
+ PropertyAccessorElement expected, PropertyAccessorElement actual) {
+ // TODO(brianwilkerson) Implement this
+ _compareGenericElements(expected, actual);
+ }
+
+ void _comparePropertyInducingElements(PropertyInducingElement expected,
+ PropertyInducingElement actual, String kind) {
+ _compareVariableElements(expected, actual, kind);
+ }
+
+ void _compareTopLevelVariableElements(
+ TopLevelVariableElement expected, TopLevelVariableElement actual) {
+ // TODO(brianwilkerson) Implement this
+ _compareGenericElements(expected, actual);
+ }
+
+ void _compareTypeLists(String descriptor, List<InterfaceType> expected,
+ List<InterfaceType> actual) {
+ int expectedLength = expected.length;
+ if (expectedLength != actual.length) {
+ _write('Expected ');
+ _write(expectedLength);
+ _write(' ');
+ _write(descriptor);
+ _write('s; found ');
+ _write(actual.length);
+ } else {
+ for (int i = 0; i < expectedLength; i++) {
+ _compareTypes(descriptor, expected[i], actual[i]);
+ }
+ }
+ }
+
+ void _compareTypeParameterElements(
+ TypeParameterElement expected, TypeParameterElement actual) {
+ // TODO(brianwilkerson) Implement this
+ _compareGenericElements(expected, actual);
+ expected.bound;
+ }
+
+ void _compareTypes(String descriptor, DartType expected, DartType actual) {
+ void compareNames() {
+ if (expected.name != actual.name) {
+ _write('Expected a ');
+ _write(descriptor);
+ _write(' named ');
+ _write(expected.name);
+ _write('; found a ');
+ _write(descriptor);
+ _write(' named ');
+ _write(actual.name);
+ }
+ }
+ void compareTypeArguments(
+ ParameterizedType expected, ParameterizedType actual) {
+ List<DartType> expectedArguments = expected.typeArguments;
+ List<DartType> actualArguments = actual.typeArguments;
+ int expectedLength = expectedArguments.length;
+ if (expectedLength != actualArguments.length) {
+ _write('Expected ');
+ _write(expectedLength);
+ _write(' type arguments; found ');
+ _write(actualArguments.length);
+ } else {
+ for (int i = 0; i < expectedLength; i++) {
+ _compareTypes(
+ 'type argument', expectedArguments[i], actualArguments[i]);
+ }
+ }
+ }
+
+ if (expected == null) {
+ if (actual != null) {
+ _write('Expected no ');
+ _write(descriptor);
+ _write('; found a ');
+ _write(descriptor);
+ _write(' named ');
+ _write(actual.name);
+ }
+ } else if (actual == null) {
+ _write('Expected a ');
+ _write(descriptor);
+ _write(' named ');
+ _write(expected.name);
+ _write('; found none');
+ } else if ((expected.isBottom && actual.isBottom) ||
+ (expected.isDynamic && actual.isDynamic) ||
+ (expected.isVoid && actual.isVoid)) {
+ // The types are the same
+ } else if (expected is InterfaceType && actual is InterfaceType) {
+ compareNames();
+ compareTypeArguments(expected, actual);
+ } else if (expected is FunctionType && actual is FunctionType) {
+ compareNames();
+ compareTypeArguments(expected, actual);
+ } else if (expected is TypeParameterType && actual is TypeParameterType) {
+ compareNames();
+ _compareTypes('bound', expected.element.bound, actual.element.bound);
+ } else {
+ _write('Expected an instance of ');
+ _write(expected.runtimeType);
+ _write(' named ');
+ _write(expected.name);
+ _write('; found an instance of ');
+ _writeln(actual.runtimeType);
+ _write(' named ');
+ _write(actual.name);
+ }
+ }
+
+ void _compareUriReferencedElements(
+ UriReferencedElement expected, UriReferencedElement actual) {
+ _compareGenericElements(expected, actual);
+ //
+ // Compare attributes.
+ //
+ if (expected.uri != actual.uri) {
+ _write('Expected a uri of ');
+ _write(expected.uri);
+ _write('; found ');
+ _writeln(actual.uri);
+ }
+ if (expected.uriOffset != actual.uriOffset) {
+ _write('Expected a uri offset of ');
+ _write(expected.uriOffset);
+ _write('; found ');
+ _writeln(actual.uriOffset);
+ }
+ }
+
+ void _compareVariableElements(
+ VariableElement expected, VariableElement actual, String kind) {
+ _compareGenericElements(expected, actual);
+ //
+ // Compare attributes.
+ //
+ if ((expected.constantValue == null) != (actual.constantValue == null)) {
+ // TODO(brianwilkerson) Check for more than existence.
+ _writeMismatch(
+ expected,
+ actual,
+ (VariableElement element) => element.constantValue == null
+ ? 'a $kind with no constant value'
+ : 'a $kind with a constant value');
+ }
+ if (expected.hasImplicitType != actual.hasImplicitType) {
+ _writeMismatch(
+ expected,
+ actual,
+ (VariableElement element) => element.hasImplicitType
+ ? 'a $kind with an implicit type'
+ : 'a $kind with an explicit type');
+ }
+ if (expected.isConst != actual.isConst) {
+ _writeMismatch(
+ expected,
+ actual,
+ (VariableElement element) =>
+ element.isConst ? 'a const $kind' : 'a non-const $kind');
+ }
+ if (expected.isFinal != actual.isFinal) {
+ _writeMismatch(
+ expected,
+ actual,
+ (VariableElement element) =>
+ element.isFinal ? 'a final $kind' : 'a non-final $kind');
+ }
+ if (expected.isPotentiallyMutatedInClosure !=
+ actual.isPotentiallyMutatedInClosure) {
+ _writeMismatch(
+ expected,
+ actual,
+ (VariableElement element) => element.isPotentiallyMutatedInClosure
+ ? 'a $kind that is potentially mutated in a closure'
+ : 'a $kind that is not mutated in a closure');
+ }
+ if (expected.isPotentiallyMutatedInScope !=
+ actual.isPotentiallyMutatedInScope) {
+ _writeMismatch(
+ expected,
+ actual,
+ (VariableElement element) => element.isPotentiallyMutatedInScope
+ ? 'a $kind that is potentially mutated in its scope'
+ : 'a $kind that is not mutated in its scope');
+ }
+ if (expected.isStatic != actual.isStatic) {
+ _writeMismatch(
+ expected,
+ actual,
+ (VariableElement element) =>
+ element.isStatic ? 'a static $kind' : 'an instance $kind');
+ }
+ //
+ // Compare children.
+ //
+ compareElements(expected.initializer, actual.initializer);
+ }
+
+ void _write(Object value) {
+ if (_needsLineBreak) {
+ _buffer.write('</p><p>');
+ _needsLineBreak = false;
+ }
+ _buffer.write(value);
+ }
+
+ void _writeln(Object value) {
+ _buffer.write(value);
+ _needsLineBreak = true;
+ }
+
+ /**
+ * Write a simple message explaining that the [expected] and [actual] values
+ * were different, using the [describe] function to describe the values.
+ */
+ void _writeMismatch /*<E>*/ (Object /*=E*/ expected, Object /*=E*/ actual,
+ String describe(Object /*=E*/ value)) {
+ _write('Expected ');
+ _write(describe(expected));
+ _write('; found ');
+ _writeln(describe(actual));
+ }
+}
+
+/**
+ * The comparison of two analyses of the same target.
+ */
+class EntryComparison {
+ /**
+ * The target that was analyzed.
+ */
+ final AnalysisTarget target;
+
+ /**
+ * The cache entry from the original context.
+ */
+ final CacheEntry originalEntry;
+
+ /**
+ * The cache entry from the re-analysis in a cloned context.
+ */
+ final CacheEntry cloneEntry;
+
+ /**
+ * A flag indicating whether the target is obsolete. A target is obsolete if
+ * it is an element in an element model that was replaced at a some point.
+ */
+ bool obsoleteTarget = false;
+
+ /**
+ * A table mapping the results that were computed for the target to
+ * comparisons of the values of those results. The table only contains entries
+ * for results for which the comparison produced interesting data.
+ */
+ Map<ResultDescriptor, ResultComparison> resultMap =
+ new HashMap<ResultDescriptor, ResultComparison>();
+
+ /**
+ * Initialize a newly created comparison of the given [target]'s analysis,
+ * given the [originalEntry] from the original context and the [cloneEntry]
+ * from the cloned context.
+ */
+ EntryComparison(this.target, this.originalEntry, this.cloneEntry) {
+ _performComparison();
+ }
+
+ /**
+ * Return `true` if there is something interesting about the analysis of this
+ * target that should be reported.
+ */
+ bool hasInterestingState() => obsoleteTarget || resultMap.isNotEmpty;
+
+ /**
+ * Write an HTML formatted description of the validation results to the given
+ * [buffer].
+ */
+ void writeOn(StringBuffer buffer) {
+ buffer.write('<p>');
+ buffer.write(target);
+ buffer.write('</p>');
+ buffer.write('<blockquote>');
+ if (obsoleteTarget) {
+ buffer.write('<p><b>This target is obsolete.</b></p>');
+ }
+ List<ResultDescriptor> results = resultMap.keys.toList();
+ results.sort((ResultDescriptor first, ResultDescriptor second) =>
+ first.toString().compareTo(second.toString()));
+ for (ResultDescriptor result in results) {
+ resultMap[result].writeOn(buffer);
+ }
+ buffer.write('</blockquote>');
+ }
+
+ /**
+ * Compare all of the results that were computed in the two contexts, adding
+ * the interesting comparisons to the [resultMap].
+ */
+ void _compareResults() {
+ Set<ResultDescriptor> results = new Set<ResultDescriptor>();
+ results.addAll(originalEntry.nonInvalidResults);
+ results.addAll(cloneEntry.nonInvalidResults);
+
+ for (ResultDescriptor result in results) {
+ ResultComparison difference = new ResultComparison(this, result);
+ if (difference.hasInterestingState()) {
+ resultMap[result] = difference;
+ }
+ }
+ }
+
+ /**
+ * Return `true` if the target of this entry is an obsolete element.
+ */
+ bool _isTargetObsolete() {
+ if (target is Element) {
+ LibraryElement library = (target as Element).library;
+ AnalysisContextImpl context = library.context;
+ CacheEntry entry = context.analysisCache.get(library.source);
+ LibraryElement value = entry.getValue(LIBRARY_ELEMENT);
+ return value != library;
+ }
+ return false;
+ }
+
+ /**
+ * Determine whether or not there is any interesting difference between the
+ * original and cloned contexts.
+ */
+ void _performComparison() {
+ obsoleteTarget = _isTargetObsolete();
+ _compareResults();
+ }
+}
+
+/**
+ * The comparison of the value of a single result computed for a single target.
+ */
+class ResultComparison {
+ /**
+ * The entry for the target for which the result was computed.
+ */
+ final EntryComparison entry;
+
+ /**
+ * The result that was computed for the target.
+ */
+ final ResultDescriptor result;
+
+ /**
+ * A flag indicating whether the state of the result is different.
+ */
+ bool differentStates = false;
+
+ /**
+ * The result of comparing the values of the results, or `null` if the states
+ * are different or if the values are the same.
+ */
+ ValueComparison valueComparison;
+
+ /**
+ * Initialize a newly created result comparison.
+ */
+ ResultComparison(this.entry, this.result) {
+ _performComparison();
+ }
+
+ /**
+ * Return `true` if this object represents a difference between the original
+ * and cloned contexts.
+ */
+ bool hasInterestingState() => differentStates || valueComparison != null;
+
+ /**
+ * Write an HTML formatted description of the validation results to the given
+ * [buffer].
+ */
+ void writeOn(StringBuffer buffer) {
+ buffer.write('<p>');
+ buffer.write(result);
+ buffer.write('</p>');
+ buffer.write('<blockquote>');
+ if (differentStates) {
+ CacheState originalState = entry.originalEntry.getState(result);
+ CacheState cloneState = entry.cloneEntry.getState(result);
+ buffer.write('<p>Original state = ');
+ buffer.write(originalState.name);
+ buffer.write('; clone state = ');
+ buffer.write(cloneState.name);
+ buffer.write('</p>');
+ }
+ if (valueComparison != null) {
+ valueComparison.writeOn(buffer);
+ }
+ buffer.write('</blockquote>');
+ }
+
+ /**
+ * Determine whether the state of the result is different between the
+ * original and cloned contexts.
+ */
+ bool _areStatesDifferent(CacheState originalState, CacheState cloneState) {
+ if (originalState == cloneState) {
+ return false;
+ } else if (originalState == CacheState.FLUSHED &&
+ cloneState == CacheState.VALID) {
+ return false;
+ } else if (originalState == CacheState.VALID &&
+ cloneState == CacheState.FLUSHED) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Determine whether the value of the result is different between the
+ * original and cloned contexts.
+ */
+ void _compareValues(CacheState originalState, CacheState cloneState) {
+ if (originalState != cloneState || originalState != CacheState.VALID) {
+ return null;
+ }
+ ValueComparison comparison = new ValueComparison(
+ entry.originalEntry.getValue(result),
+ entry.cloneEntry.getValue(result));
+ if (comparison.hasInterestingState()) {
+ valueComparison = comparison;
+ }
+ }
+
+ /**
+ * Determine whether or not there is any interesting difference between the
+ * original and cloned contexts.
+ */
+ void _performComparison() {
+ CacheState originalState = entry.originalEntry.getState(result);
+ CacheState cloneState = entry.cloneEntry.getState(result);
+ if (_areStatesDifferent(originalState, cloneState)) {
+ differentStates = true;
+ _compareValues(originalState, cloneState);
+ }
+ }
+}
+
+/**
+ * The results of validating an analysis context.
+ *
+ * Validation is done by re-analyzing all of the explicitly added source in a
+ * new analysis context that is configured to be the same as the original
+ * context.
+ */
+class ValidationResults {
+ /**
+ * A set of targets that were in the original context that were not included
+ * in the re-created context.
+ */
+ Set<AnalysisTarget> extraTargets;
+
+ /**
+ * A set of targets that were in the re-created context that were not included
+ * in the original context.
+ */
+ Set<AnalysisTarget> missingTargets;
+
+ /**
+ * A table, keyed by targets, whose values are comparisons of the analysis of
+ * those targets. The table only contains entries for targets for which the
+ * comparison produced interesting data.
+ */
+ Map<AnalysisTarget, EntryComparison> targetMap =
+ new HashMap<AnalysisTarget, EntryComparison>();
+
+ /**
+ * Initialize a newly created validation result by validating the given
+ * [context].
+ */
+ ValidationResults(AnalysisContextImpl context) {
+ _validate(context);
+ }
+
+ /**
+ * Write an HTML formatted description of the validation results to the given
+ * [buffer].
+ */
+ void writeOn(StringBuffer buffer) {
+ if (extraTargets.isEmpty && missingTargets.isEmpty && targetMap.isEmpty) {
+ buffer.write('<p>No interesting results.</p>');
+ return;
+ }
+ if (extraTargets.isNotEmpty) {
+ buffer.write('<h4>Extra Targets</h4>');
+ buffer.write('<p style="commentary">');
+ buffer.write('Targets that exist in the original context that were not ');
+ buffer.write('re-created in the cloned context.');
+ buffer.write('</p>');
+ _writeTargetList(buffer, extraTargets.toList());
+ }
+ if (missingTargets.isNotEmpty) {
+ buffer.write('<h4>Missing Targets</h4>');
+ buffer.write('<p style="commentary">');
+ buffer.write('Targets that do <b>not</b> exist in the original context ');
+ buffer.write('but do exist in the cloned context.');
+ buffer.write('</p>');
+ _writeTargetList(buffer, missingTargets.toList());
+ }
+ if (targetMap.isNotEmpty) {
+ buffer.write('<h4>Differing Targets</h4>');
+ // TODO(brianwilkerson) Sort the list of targets.
+ for (EntryComparison comparison in targetMap.values) {
+ comparison.writeOn(buffer);
+ }
+ }
+ }
+
+ /**
+ * Analyze all of the explicit sources in the given [context].
+ */
+ void _analyze(AnalysisContextImpl context) {
+ while (true) {
+ AnalysisResult result = context.performAnalysisTask();
+ if (!result.hasMoreWork) {
+ return;
+ }
+ }
+ }
+
+ /**
+ * Create and return a new analysis context that will analyze files in the
+ * same way as the given [context].
+ */
+ AnalysisContextImpl _clone(AnalysisContextImpl context) {
+ AnalysisContextImpl clone = AnalysisEngine.instance.createAnalysisContext();
+
+ clone.analysisOptions = context.analysisOptions;
+ //clone.declaredVariables = context.declaredVariables;
+ clone.sourceFactory = context.sourceFactory.clone();
+ // TODO(brianwilkerson) Check content cache. We either need to copy the
+ // cache into the clone or ensure that the context's cache is empty.
+
+ ChangeSet changeSet = new ChangeSet();
+ for (AnalysisTarget target in context.explicitTargets) {
+ if (target is Source) {
+ changeSet.addedSource(target);
+ }
+ }
+ clone.applyChanges(changeSet);
+ return clone;
+ }
+
+ /**
+ * Compare the results produced in the [original] context to those produced in
+ * the [clone].
+ */
+ void _compareContexts(
+ AnalysisContextImpl original, AnalysisContextImpl clone) {
+ AnalysisCache originalCache = original.analysisCache;
+ AnalysisCache cloneCache = clone.analysisCache;
+ List<AnalysisTarget> originalTargets = _getKeys(original, originalCache);
+ List<AnalysisTarget> cloneTargets = _getKeys(clone, cloneCache);
+
+ extraTargets =
+ new HashSet<AnalysisTarget>(equals: _equal, hashCode: _hashCode);
+ extraTargets.addAll(originalTargets);
+ extraTargets.removeAll(cloneTargets);
+
+ missingTargets =
+ new HashSet<AnalysisTarget>(equals: _equal, hashCode: _hashCode);
+ missingTargets.addAll(cloneTargets);
+ missingTargets.removeAll(originalTargets);
+
+ for (AnalysisTarget cloneTarget in cloneTargets) {
+ if (!missingTargets.contains(cloneTarget)) {
+ AnalysisTarget originalTarget = _find(originalTargets, cloneTarget);
+ CacheEntry originalEntry = originalCache.get(originalTarget);
+ CacheEntry cloneEntry = cloneCache.get(cloneTarget);
+ EntryComparison comparison =
+ new EntryComparison(cloneTarget, originalEntry, cloneEntry);
+ if (comparison.hasInterestingState()) {
+ targetMap[cloneTarget] = comparison;
+ }
+ }
+ }
+ }
+
+ /**
+ * Find the target in the list of [originalTargets] that is equal to the
+ * [cloneTarget].
+ */
+ AnalysisTarget _find(
+ List<AnalysisTarget> originalTargets, AnalysisTarget cloneTarget) {
+ for (AnalysisTarget originalTarget in originalTargets) {
+ if (_equal(originalTarget, cloneTarget)) {
+ return originalTarget;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return a list of the analysis targets in the given [cache] that are owned
+ * by the given [context].
+ */
+ List<AnalysisTarget> _getKeys(
+ AnalysisContextImpl context, AnalysisCache cache) {
+ List<AnalysisTarget> targets = <AnalysisTarget>[];
+ MapIterator<AnalysisTarget, CacheEntry> iterator =
+ cache.iterator(context: context);
+ while (iterator.moveNext()) {
+ targets.add(iterator.key);
+ }
+ return targets;
+ }
+
+ /**
+ * Validate the given [context].
+ */
+ void _validate(AnalysisContextImpl context) {
+ AnalysisContextImpl clone = _clone(context);
+ _analyze(clone);
+ _compareContexts(context, clone);
+ }
+
+ /**
+ * Write the list of [targets] to the [buffer].
+ */
+ void _writeTargetList(StringBuffer buffer, List<AnalysisTarget> targets) {
+ // TODO(brianwilkerson) Sort the list of targets.
+ //targets.sort();
+ for (AnalysisTarget target in targets) {
+ buffer.write('<p>');
+ buffer.write(target);
+ buffer.write(' (');
+ buffer.write(target.runtimeType);
+ buffer.write(')');
+ buffer.write('</p>');
+ }
+ }
+
+ /**
+ * Return `true` if the [first] and [second] objects are equal.
+ */
+ static bool _equal(Object first, Object second) {
+ //
+ // Compare possible null values.
+ //
+ if (first == null) {
+ return second == null;
+ } else if (second == null) {
+ return false;
+ }
+ //
+ // Handle special cases.
+ //
+ if (first is ConstantEvaluationTarget_Annotation &&
+ second is ConstantEvaluationTarget_Annotation) {
+ return _equal(first.source, second.source) &&
+ _equal(first.librarySource, second.librarySource) &&
+ _equal(first.annotation, second.annotation);
+ } else if (first is AstNode && second is AstNode) {
+ return first.runtimeType == second.runtimeType &&
+ first.offset == second.offset &&
+ first.length == second.length;
+ }
+ //
+ // Handle the general case.
+ //
+ return first == second;
+ }
+
+ /**
+ * Return a hash code for the given [object].
+ */
+ static int _hashCode(Object object) {
+ //
+ // Handle special cases.
+ //
+ if (object is ConstantEvaluationTarget_Annotation) {
+ return object.source.hashCode;
+ } else if (object is AstNode) {
+ return object.offset;
+ }
+ //
+ // Handle the general case.
+ //
+ return object.hashCode;
+ }
+}
+
+class ValueComparison {
+ /**
+ * The result value from the original context.
+ */
+ final Object originalValue;
+
+ /**
+ * The result value from the cloned context.
+ */
+ final Object cloneValue;
+
+ /**
+ * A description of the difference between the original and clone values, or
+ * `null` if the values are equal.
+ */
+ String description = null;
+
+ /**
+ * Initialize a newly created value comparison to represents the difference,
+ * if any, between the [originalValue] and the [cloneValue].
+ */
+ ValueComparison(this.originalValue, this.cloneValue) {
+ _performComparison();
+ }
+
+ /**
+ * Return `true` if this object represents a difference between the original
+ * and cloned values.
+ */
+ bool hasInterestingState() => description != null;
+
+ /**
+ * Write an HTML formatted description of the validation results to the given
+ * [buffer].
+ */
+ void writeOn(StringBuffer buffer) {
+ buffer.write('<p>');
+ buffer.write(description);
+ buffer.write('</p>');
+ }
+
+ bool _compareAnalysisErrors(
+ AnalysisError expected, AnalysisError actual, StringBuffer buffer) {
+ if (actual.errorCode == expected.errorCode &&
+ actual.source == expected.source &&
+ actual.offset == expected.offset) {
+ return true;
+ }
+ if (buffer != null) {
+ void write(AnalysisError originalError) {
+ buffer.write('a ');
+ buffer.write(originalError.errorCode.uniqueName);
+ buffer.write(' in ');
+ buffer.write(originalError.source.fullName);
+ buffer.write(' at ');
+ buffer.write(originalError.offset);
+ }
+
+ buffer.write('Expected ');
+ write(expected);
+ buffer.write('; found ');
+ write(actual);
+ }
+ return false;
+ }
+
+ bool _compareAstNodes(AstNode expected, AstNode actual, StringBuffer buffer) {
+ if (AstComparator.equalNodes(actual, expected)) {
+ return true;
+ }
+ if (buffer != null) {
+ // TODO(brianwilkerson) Compute where the difference is rather than just
+ // whether there is a difference.
+ buffer.write('Different AST nodes');
+ }
+ return false;
+ }
+
+ bool _compareConstantEvaluationTargets(ConstantEvaluationTarget expected,
+ ConstantEvaluationTarget actual, StringBuffer buffer) {
+ if (actual is ConstantEvaluationTarget_Annotation) {
+ ConstantEvaluationTarget_Annotation expectedAnnotation = expected;
+ ConstantEvaluationTarget_Annotation actualAnnotation = actual;
+ if (actualAnnotation.source == expectedAnnotation.source &&
+ actualAnnotation.librarySource == expectedAnnotation.librarySource &&
+ actualAnnotation.annotation == expectedAnnotation.annotation) {
+ return true;
+ }
+ if (buffer != null) {
+ void write(ConstantEvaluationTarget_Annotation target) {
+ Annotation annotation = target.annotation;
+ buffer.write(annotation);
+ buffer.write(' at ');
+ buffer.write(annotation.offset);
+ buffer.write(' in ');
+ buffer.write(target.source);
+ buffer.write(' in ');
+ buffer.write(target.librarySource);
+ }
+
+ buffer.write('Expected ');
+ write(expectedAnnotation);
+ buffer.write('; found ');
+ write(actualAnnotation);
+ }
+ return false;
+ }
+ if (buffer != null) {
+ buffer.write('Unknown class of ConstantEvaluationTarget: ');
+ buffer.write(actual.runtimeType);
+ }
+ return false;
+ }
+
+ bool _compareDartScripts(
+ DartScript expected, DartScript actual, StringBuffer buffer) {
+ // TODO(brianwilkerson) Implement this.
+ return true;
+ }
+
+ bool _compareDocuments(
+ html.Document expected, html.Document actual, StringBuffer buffer) {
+ // TODO(brianwilkerson) Implement this.
+ return true;
+ }
+
+ bool _compareElements(Element expected, Element actual, StringBuffer buffer) {
+ ElementComparator comparator = new ElementComparator();
+ comparator.compareElements(expected, actual);
+ if (comparator.hasDifference) {
+ if (buffer != null) {
+ buffer.write(comparator.description);
+ }
+ return false;
+ }
+ return true;
+ }
+
+ bool _compareLibrarySpecificUnits(LibrarySpecificUnit expected,
+ LibrarySpecificUnit actual, StringBuffer buffer) {
+ if (actual.library.fullName == expected.library.fullName &&
+ actual.unit.fullName == expected.unit.fullName) {
+ return true;
+ }
+ if (buffer != null) {
+ buffer.write('Expected ');
+ buffer.write(expected);
+ buffer.write('; found ');
+ buffer.write(actual);
+ }
+ return false;
+ }
+
+ bool _compareLineInfos(
+ LineInfo expected, LineInfo actual, StringBuffer buffer) {
+ // TODO(brianwilkerson) Implement this.
+ return true;
+ }
+
+ bool _compareLists(List expected, List actual, StringBuffer buffer) {
+ int expectedLength = expected.length;
+ int actualLength = actual.length;
+ int left = 0;
+ while (left < expectedLength &&
+ left < actualLength &&
+ _compareObjects(expected[left], actual[left], null)) {
+ left++;
+ }
+ if (left == actualLength) {
+ if (left == expectedLength) {
+ // The lists are the same length and the elements are equal.
+ return true;
+ }
+ if (buffer != null) {
+ buffer.write('Expected a list of length ');
+ buffer.write(expectedLength);
+ buffer.write('; found a list of length ');
+ buffer.write(actualLength);
+ buffer.write(' that was a prefix of the expected list');
+ }
+ return false;
+ } else if (left == expectedLength) {
+ if (buffer != null) {
+ buffer.write('Expected a list of length ');
+ buffer.write(expectedLength);
+ buffer.write('; found a list of length ');
+ buffer.write(actualLength);
+ buffer.write(' that was an extension of the expected list');
+ }
+ return false;
+ }
+ int expectedRight = expectedLength - 1;
+ int actualRight = actualLength - 1;
+ while (expectedRight > left &&
+ actualRight > left &&
+ _compareObjects(expected[expectedRight], actual[actualRight], null)) {
+ actualRight--;
+ expectedRight--;
+ }
+ if (buffer != null) {
+ void write(int left, int right, int length) {
+ buffer.write('the elements (');
+ buffer.write(left);
+ buffer.write('..');
+ buffer.write(right);
+ buffer.write(') in a list of length ');
+ buffer.write(length);
+ }
+
+ buffer.write('Expected ');
+ write(left, expectedRight, expectedLength);
+ buffer.write(' to match ');
+ write(left, actualRight, actualLength);
+ buffer.write(' but they did not');
+ }
+ return false;
+ }
+
+ /**
+ * Return `true` if the [expected] and [actual] objects are equal. If they are
+ * not equal, and the given [buffer] is not `null`, then a description of the
+ * difference will be written to the [buffer].
+ */
+ bool _compareObjects(Object expected, Object actual, StringBuffer buffer) {
+ //
+ // Compare possible null values.
+ //
+ if (actual == null) {
+ if (expected == null) {
+ return true;
+ } else {
+ if (buffer != null) {
+ buffer.write('Expected an instance of ');
+ buffer.write(expected.runtimeType);
+ buffer.write('; found null');
+ }
+ return false;
+ }
+ }
+ Type actualType = actual.runtimeType;
+ if (expected == null) {
+ if (buffer != null) {
+ buffer.write('Expected null; found an instance of ');
+ buffer.write(actualType);
+ }
+ return false;
+ }
+ Type expectedType = expected.runtimeType;
+ //
+ // Compare the types.
+ //
+ if (expectedType != actualType) {
+ if (buffer != null) {
+ buffer.write('Expected an instance of ');
+ buffer.write(expectedType);
+ buffer.write('; found an instance of ');
+ buffer.write(actualType);
+ }
+ return false;
+ }
+ //
+ // Compare non-null values of the same type.
+ //
+ if (actual is bool) {
+ return _comparePrimitives(expected, actual, buffer);
+ } else if (actual is int) {
+ return _comparePrimitives(expected, actual, buffer);
+ } else if (actual is String) {
+ return _compareStrings(expected, actual, buffer);
+ } else if (actual is List) {
+ return _compareLists(expected, actual, buffer);
+ } else if (actual is AnalysisError) {
+ return _compareAnalysisErrors(expected, actual, buffer);
+ } else if (actual is AstNode) {
+ return _compareAstNodes(expected, actual, buffer);
+ } else if (actual is DartScript) {
+ return _compareDartScripts(expected, actual, buffer);
+ } else if (actual is html.Document) {
+ return _compareDocuments(expected, actual, buffer);
+ } else if (actual is Element) {
+ return _compareElements(expected, actual, buffer);
+ } else if (actual is LibrarySpecificUnit) {
+ return _compareLibrarySpecificUnits(expected, actual, buffer);
+ } else if (actual is LineInfo) {
+ return _compareLineInfos(expected, actual, buffer);
+ } else if (actual is ReferencedNames) {
+ return _compareReferencedNames(expected, actual, buffer);
+ } else if (actual is Source) {
+ return _compareSources(expected, actual, buffer);
+ } else if (actual is SourceKind) {
+ return _comparePrimitives(expected, actual, buffer);
+ } else if (actual is Token) {
+ return _compareTokenStreams(expected, actual, buffer);
+ } else if (actual is TypeProvider) {
+ return true;
+ } else if (actual is UsedLocalElements) {
+ return _compareUsedLocalElements(expected, actual, buffer);
+ } else if (actual is UsedImportedElements) {
+ return _compareUsedImportedElements(expected, actual, buffer);
+ } else if (actual is ConstantEvaluationTarget) {
+ return _compareConstantEvaluationTargets(expected, actual, buffer);
+ }
+ if (buffer != null) {
+ buffer.write('Cannot compare values of type ');
+ buffer.write(actualType);
+ }
+ return false;
+ }
+
+ bool _comparePrimitives(Object expected, Object actual, StringBuffer buffer) {
+ if (actual == expected) {
+ return true;
+ }
+ if (buffer != null) {
+ buffer.write('Expected ');
+ buffer.write(expected);
+ buffer.write('; found ');
+ buffer.write(actual);
+ }
+ return false;
+ }
+
+ bool _compareReferencedNames(
+ ReferencedNames expected, ReferencedNames actual, StringBuffer buffer) {
+ Set<String> expectedNames = expected.names;
+ Map<String, Set<String>> expectedUserToDependsOn = expected.userToDependsOn;
+ Set<String> expectedKeys = expectedUserToDependsOn.keys.toSet();
+
+ Set<String> actualNames = actual.names;
+ Map<String, Set<String>> actualUserToDependsOn = actual.userToDependsOn;
+ Set<String> actualKeys = actualUserToDependsOn.keys.toSet();
+
+ Set<String> missingNames = expectedNames.difference(actualNames);
+ Set<String> extraNames = actualNames.difference(expectedNames);
+ Set<String> missingKeys = expectedKeys.difference(actualKeys);
+ Set<String> extraKeys = actualKeys.difference(expectedKeys);
+ Map<String, List<Set<String>>> mismatchedDependencies =
+ new HashMap<String, List<Set<String>>>();
+ Set<String> commonKeys = expectedKeys.intersection(actualKeys);
+ for (String key in commonKeys) {
+ Set<String> expectedDependencies = expectedUserToDependsOn[key];
+ Set<String> actualDependencies = actualUserToDependsOn[key];
+ Set<String> missingDependencies =
+ expectedDependencies.difference(actualDependencies);
+ Set<String> extraDependencies =
+ actualDependencies.difference(expectedDependencies);
+ if (missingDependencies.isNotEmpty || extraDependencies.isNotEmpty) {
+ mismatchedDependencies[key] = [missingDependencies, extraDependencies];
+ }
+ }
+
+ if (missingNames.isEmpty &&
+ extraNames.isEmpty &&
+ missingKeys.isEmpty &&
+ extraKeys.isEmpty &&
+ mismatchedDependencies.isEmpty) {
+ return true;
+ }
+ if (buffer != null) {
+ void write(String title, Set<String> names) {
+ buffer.write(names.length);
+ buffer.write(' ');
+ buffer.write(title);
+ buffer.write(': {');
+ bool first = true;
+ for (String name in names) {
+ if (first) {
+ first = false;
+ } else {
+ buffer.write(', ');
+ }
+ buffer.write(name);
+ }
+ buffer.write('}');
+ }
+ bool needsNewline = false;
+ if (missingNames.isNotEmpty) {
+ buffer.write('Has ');
+ write('missing names', missingNames);
+ needsNewline = true;
+ }
+ if (extraNames.isNotEmpty) {
+ if (needsNewline) {
+ buffer.write('</p><p>');
+ }
+ buffer.write('Has ');
+ write('extra names', extraNames);
+ needsNewline = true;
+ }
+ if (missingKeys.isNotEmpty) {
+ if (needsNewline) {
+ buffer.write('</p><p>');
+ }
+ buffer.write('Has ');
+ write('missing keys', missingKeys);
+ needsNewline = true;
+ }
+ if (extraKeys.isNotEmpty) {
+ if (needsNewline) {
+ buffer.write('</p><p>');
+ }
+ buffer.write('Has ');
+ write('extra keys', extraKeys);
+ needsNewline = true;
+ }
+ mismatchedDependencies.forEach((String key, List<Set<String>> value) {
+ Set<String> missingDependencies = value[0];
+ Set<String> extraDependencies = value[1];
+ if (needsNewline) {
+ buffer.write('</p><p>');
+ }
+ buffer.write('The key ');
+ buffer.write(key);
+ buffer.write(' has ');
+ bool needsConjunction = false;
+ if (missingNames.isNotEmpty) {
+ write('missing dependencies', missingDependencies);
+ needsConjunction = true;
+ }
+ if (extraNames.isNotEmpty) {
+ if (needsConjunction) {
+ buffer.write(' and ');
+ }
+ write('extra dependencies', extraDependencies);
+ }
+ needsNewline = true;
+ });
+ }
+ return true;
+ }
+
+ bool _compareSources(Source expected, Source actual, StringBuffer buffer) {
+ if (actual.fullName == expected.fullName) {
+ return true;
+ }
+ if (buffer != null) {
+ buffer.write('Expected a source for ');
+ buffer.write(expected.fullName);
+ buffer.write('; found a source for ');
+ buffer.write(actual.fullName);
+ }
+ return false;
+ }
+
+ bool _compareStrings(String expected, String actual, StringBuffer buffer) {
+ if (actual == expected) {
+ return true;
+ }
+ int expectedLength = expected.length;
+ int actualLength = actual.length;
+ int left = 0;
+ while (left < actualLength &&
+ left < expectedLength &&
+ actual.codeUnitAt(left) == expected.codeUnitAt(left)) {
+ left++;
+ }
+ if (left == actualLength) {
+ if (buffer != null) {
+ buffer.write('Expected ...[');
+ buffer.write(expected.substring(left));
+ buffer.write(']; found ...[]');
+ }
+ return false;
+ } else if (left == expectedLength) {
+ if (buffer != null) {
+ buffer.write('Expected ...[]; found ...[');
+ buffer.write(actual.substring(left));
+ buffer.write(']');
+ }
+ return false;
+ }
+ int actualRight = actualLength - 1;
+ int expectedRight = expectedLength - 1;
+ while (actualRight > left &&
+ expectedRight > left &&
+ actual.codeUnitAt(actualRight) == expected.codeUnitAt(expectedRight)) {
+ actualRight--;
+ expectedRight--;
+ }
+ if (buffer != null) {
+ void write(String string, int left, int right) {
+ buffer.write('...[');
+ buffer.write(string.substring(left, right));
+ buffer.write(']... (');
+ buffer.write(left);
+ buffer.write('..');
+ buffer.write(right);
+ buffer.write(')');
+ }
+
+ buffer.write('Expected ');
+ write(expected, left, expectedRight);
+ buffer.write('; found ');
+ write(actual, left, actualRight);
+ }
+ return false;
+ }
+
+ bool _compareTokenStreams(Token expected, Token actual, StringBuffer buffer) {
+ bool equals(Token originalToken, Token cloneToken) {
+ return originalToken.type == cloneToken.type &&
+ originalToken.offset == cloneToken.offset &&
+ originalToken.lexeme == cloneToken.lexeme;
+ }
+
+ Token actualLeft = actual;
+ Token expectedLeft = expected;
+ while (actualLeft.type != TokenType.EOF &&
+ expectedLeft.type != TokenType.EOF &&
+ equals(actualLeft, expectedLeft)) {
+ actualLeft = actualLeft.next;
+ expectedLeft = expectedLeft.next;
+ }
+ if (actualLeft.type == TokenType.EOF &&
+ expectedLeft.type == TokenType.EOF) {
+ return true;
+ }
+ if (buffer != null) {
+ void write(Token token) {
+ buffer.write(token.type);
+ buffer.write(' at ');
+ buffer.write(token.offset);
+ buffer.write(' (');
+ buffer.write(token.lexeme);
+ buffer.write(')');
+ }
+
+ buffer.write('Expected ');
+ write(expectedLeft);
+ buffer.write('; found ');
+ write(actualLeft);
+ }
+ return false;
+ }
+
+ bool _compareUsedImportedElements(UsedImportedElements expected,
+ UsedImportedElements actual, StringBuffer buffer) {
+ // TODO(brianwilkerson) Implement this.
+ return true;
+ }
+
+ bool _compareUsedLocalElements(UsedLocalElements expected,
+ UsedLocalElements actual, StringBuffer buffer) {
+ // TODO(brianwilkerson) Implement this.
+ return true;
+ }
+
+ /**
+ * Determine whether or not there is any interesting difference between the
+ * original and cloned values.
+ */
+ void _performComparison() {
+ StringBuffer buffer = new StringBuffer();
+ if (!_compareObjects(cloneValue, originalValue, buffer)) {
+ description = buffer.toString();
+ }
+ }
+}
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 8049890..d96edc0 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -75,6 +75,10 @@
}
}
+ void processRequiredPlugins() {
+ AnalysisEngine.instance.processRequiredPlugins();
+ }
+
CompilationUnit resolveDartUnit(Source unitSource, Source librarySource) {
return context.resolveCompilationUnit2(unitSource, librarySource);
}
@@ -84,6 +88,7 @@
}
void setUp() {
+ processRequiredPlugins();
setupResourceProvider();
resourceResolver = new ResourceUriResolver(provider);
packageMap = new Map<String, List<Folder>>();
@@ -121,28 +126,12 @@
}
@override
- void logError2(String message, Object exception) {
- print(message);
- if (exception != null) {
- print(exception);
- }
- }
-
- @override
void logInformation(String message, [CaughtException exception]) {
print(message);
if (exception != null) {
print(exception);
}
}
-
- @override
- void logInformation2(String message, Object exception) {
- print(message);
- if (exception != null) {
- print(exception);
- }
- }
}
/**
diff --git a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
index 966559b..a24b811 100644
--- a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
@@ -23,9 +23,6 @@
@reflectiveTest
class AnalysisOptionsFileNotificationTest extends AbstractAnalysisTest {
- /// Cached model state in case tests need to set task model to on/off.
- bool wasTaskModelEnabled;
-
Map<String, List<AnalysisError>> filesErrors = {};
final testSource = '''
@@ -78,13 +75,10 @@
void setUp() {
super.setUp();
server.handlers = [new AnalysisDomainHandler(server)];
- wasTaskModelEnabled = AnalysisEngine.instance.useTaskModel;
- AnalysisEngine.instance.useTaskModel = true;
}
@override
void tearDown() {
- AnalysisEngine.instance.useTaskModel = wasTaskModelEnabled;
filesErrors[optionsFilePath] = [];
filesErrors[testFile] = [];
super.tearDown();
@@ -108,10 +102,10 @@
await waitForTasksFinished();
// Verify options file.
- expect(optionsFileErrors, hasLength(0));
+ expect(optionsFileErrors, isEmpty);
// Verify test file.
- expect(testFileErrors, hasLength(0));
+ expect(testFileErrors, isEmpty);
}
test_error_filter_removed() async {
@@ -132,10 +126,10 @@
await waitForTasksFinished();
// Verify options file.
- expect(optionsFileErrors, hasLength(0));
+ expect(optionsFileErrors, isEmpty);
// Verify test file.
- expect(testFileErrors, hasLength(0));
+ expect(testFileErrors, isEmpty);
addOptionsFile('''
analyzer:
@@ -147,7 +141,7 @@
await waitForTasksFinished();
// Verify options file.
- expect(optionsFileErrors, hasLength(0));
+ expect(optionsFileErrors, isEmpty);
// Verify test file.
expect(testFileErrors, hasLength(1));
diff --git a/pkg/analysis_server/test/analysis/notification_errors_test.dart b/pkg/analysis_server/test/analysis/notification_errors_test.dart
index dbbe7af..02b05ec 100644
--- a/pkg/analysis_server/test/analysis/notification_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_errors_test.dart
@@ -25,9 +25,6 @@
class NotificationErrorsTest extends AbstractAnalysisTest {
Map<String, List<AnalysisError>> filesErrors = {};
- /// Cached model state in case tests need to set task model to on/off.
- bool wasTaskModelEnabled;
-
void processNotification(Notification notification) {
if (notification.event == ANALYSIS_ERRORS) {
var decoded = new AnalysisErrorsParams.fromNotification(notification);
@@ -39,13 +36,6 @@
void setUp() {
super.setUp();
server.handlers = [new AnalysisDomainHandler(server),];
- wasTaskModelEnabled = AnalysisEngine.instance.useTaskModel;
- }
-
- @override
- void tearDown() {
- AnalysisEngine.instance.useTaskModel = wasTaskModelEnabled;
- super.tearDown();
}
test_importError() async {
@@ -66,9 +56,6 @@
}
test_lintError() async {
- // Requires task model.
- AnalysisEngine.instance.useTaskModel = true;
-
var camelCaseTypesLintName = 'camel_case_types';
addFile(
diff --git a/pkg/analysis_server/test/analysis/update_content_test.dart b/pkg/analysis_server/test/analysis/update_content_test.dart
index 6fbc5d8..3e09632 100644
--- a/pkg/analysis_server/test/analysis/update_content_test.dart
+++ b/pkg/analysis_server/test/analysis/update_content_test.dart
@@ -107,11 +107,7 @@
server.updateContent('2', {testFile: new RemoveContentOverlay()});
// Validate that at the end the unit was indexed.
await server.onAnalysisComplete;
- if (AnalysisEngine.instance.useTaskModel) {
- verify(server.index.index(anyObject, testUnitMatcher)).times(3);
- } else {
- verify(server.index.index(anyObject, testUnitMatcher)).times(2);
- }
+ verify(server.index.index(anyObject, testUnitMatcher)).times(3);
}
test_multiple_contexts() async {
@@ -136,8 +132,9 @@
library baz;
f(int i) {}
''');
- Request request = new AnalysisSetAnalysisRootsParams(
- ['/project1', '/project2'], []).toRequest('0');
+ Request request =
+ new AnalysisSetAnalysisRootsParams(['/project1', '/project2'], [])
+ .toRequest('0');
handleSuccessfulRequest(request);
{
await server.onAnalysisComplete;
@@ -166,8 +163,9 @@
String filePath = '/User/project1/test.dart';
Folder folder1 = resourceProvider.newFolder('/User/project1');
Folder folder2 = resourceProvider.newFolder('/User/project2');
- Request request = new AnalysisSetAnalysisRootsParams(
- [folder1.path, folder2.path], []).toRequest('0');
+ Request request =
+ new AnalysisSetAnalysisRootsParams([folder1.path, folder2.path], [])
+ .toRequest('0');
handleSuccessfulRequest(request);
// exactly 2 contexts
expect(server.folderMap, hasLength(2));
@@ -274,6 +272,4 @@
}
}
-class _MockIndex extends TypedMock implements Index {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _MockIndex extends TypedMock implements Index {}
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index de27610..5c0616e 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -97,22 +97,27 @@
}
AnalysisServer createAnalysisServer(Index index) {
+ //
+ // Collect plugins
+ //
ServerPlugin serverPlugin = new ServerPlugin();
- // TODO(pq): this convoluted extension registry dance needs cleanup.
- List<Plugin> plugins = <Plugin>[
- serverPlugin,
- linterPlugin,
- linterServerPlugin,
- dartCompletionPlugin,
- ];
- // Accessing `taskManager` ensures that AE plugins are registered.
- AnalysisEngine.instance.taskManager;
- plugins.addAll(AnalysisEngine.instance.supportedPlugins);
+ List<Plugin> plugins = <Plugin>[];
+ plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+ plugins.add(AnalysisEngine.instance.commandLinePlugin);
+ plugins.add(AnalysisEngine.instance.optionsPlugin);
+ plugins.add(serverPlugin);
+ plugins.add(dartCompletionPlugin);
+ plugins.add(linterPlugin);
+ plugins.add(linterServerPlugin);
addServerPlugins(plugins);
- // process plugins
+ //
+ // Process plugins
+ //
ExtensionManager manager = new ExtensionManager();
manager.processPlugins(plugins);
- // create server
+ //
+ // Create server
+ //
return new AnalysisServer(
serverChannel,
resourceProvider,
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index 58179eb..e9a1663 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -21,6 +21,7 @@
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:typed_mock/typed_mock.dart';
import 'package:unittest/unittest.dart';
@@ -119,23 +120,31 @@
});
}
+ void processRequiredPlugins() {
+ List<Plugin> plugins = <Plugin>[];
+ plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+ plugins.add(AnalysisEngine.instance.optionsPlugin);
+ plugins.add(server.serverPlugin);
+
+ ExtensionManager manager = new ExtensionManager();
+ manager.processPlugins(plugins);
+ }
+
void setUp() {
channel = new MockServerChannel();
resourceProvider = new MemoryResourceProvider();
packageMapProvider = new MockPackageMapProvider();
- ExtensionManager manager = new ExtensionManager();
- ServerPlugin serverPlugin = new ServerPlugin();
- manager.processPlugins([serverPlugin]);
server = new AnalysisServer(
channel,
resourceProvider,
packageMapProvider,
null,
- serverPlugin,
+ new ServerPlugin(),
new AnalysisServerOptions(),
new MockSdk(),
InstrumentationService.NULL_SERVICE,
rethrowExceptions: true);
+ processRequiredPlugins();
}
Future test_contextDisposed() {
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index 0d5ea53..86defe8 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -1895,8 +1895,7 @@
main() {
B.!1;
}''',
- <String>["1+FIELD_B", "1-FIELD_A", "1+methodB", "1-methodA"],
- failingTests: '1');
+ <String>["1+FIELD_B", "1-FIELD_A", "1+methodB", "1-methodA"]);
buildTests(
'testCompletion_propertyAccess_whenInstanceTarget',
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 9f51368..082f28d 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -11,12 +11,18 @@
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/source/embedder.dart';
+import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/services/lint.dart';
+import 'package:linter/src/plugin/linter_plugin.dart';
+import 'package:linter/src/rules/avoid_as.dart';
import 'package:package_config/packages.dart';
import 'package:path/path.dart';
+import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
@@ -67,6 +73,37 @@
String projPath = '/my/proj';
+ AnalysisError missing_return =
+ new AnalysisError(new TestSource(), 0, 1, HintCode.MISSING_RETURN, [
+ ['x']
+ ]);
+
+ AnalysisError invalid_assignment_error =
+ new AnalysisError(new TestSource(), 0, 1, HintCode.INVALID_ASSIGNMENT, [
+ ['x'],
+ ['y']
+ ]);
+
+ AnalysisError unused_local_variable = new AnalysisError(
+ new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
+ ['x']
+ ]);
+
+ List<ErrorProcessor> get errorProcessors => callbacks.currentContext
+ .getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+
+ List<Linter> get lints => getLints(callbacks.currentContext);
+
+ AnalysisOptions get options => callbacks.currentContext.analysisOptions;
+
+ void deleteFile(List<String> pathComponents) {
+ String filePath = posix.joinAll(pathComponents);
+ resourceProvider.deleteFile(filePath);
+ }
+
+ ErrorProcessor getProcessor(AnalysisError error) =>
+ ErrorProcessor.getProcessor(callbacks.currentContext, error);
+
String newFile(List<String> pathComponents, [String content = '']) {
String filePath = posix.joinAll(pathComponents);
resourceProvider.newFile(filePath, content);
@@ -79,11 +116,22 @@
return folderPath;
}
+ void processRequiredPlugins() {
+ List<Plugin> plugins = <Plugin>[];
+ plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+ plugins.add(AnalysisEngine.instance.commandLinePlugin);
+ plugins.add(AnalysisEngine.instance.optionsPlugin);
+ plugins.add(linterPlugin);
+ ExtensionManager manager = new ExtensionManager();
+ manager.processPlugins(plugins);
+ }
+
UriResolver providePackageResolver(Folder folder) {
return packageResolver;
}
void setUp() {
+ processRequiredPlugins();
resourceProvider = new MemoryResourceProvider();
packageMapProvider = new MockPackageMapProvider();
manager = new ContextManagerImpl(resourceProvider, providePackageResolver,
@@ -93,6 +141,99 @@
resourceProvider.newFolder(projPath);
}
+ test_analysis_options_file_delete() async {
+ // Setup .analysis_options
+ newFile(
+ [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+ r'''
+embedder_libs:
+ "dart:foobar": "../sdk_ext/entry.dart"
+analyzer:
+ language:
+ enableGenericMethods: true
+ errors:
+ unused_local_variable: false
+linter:
+ rules:
+ - camel_case_types
+''');
+
+ // Setup context.
+ manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+ await pumpEventQueue();
+
+ // Verify options were set.
+ expect(errorProcessors, hasLength(1));
+ expect(lints, hasLength(1));
+ expect(options.enableGenericMethods, isTrue);
+
+ // Remove options.
+ deleteFile([projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE]);
+ await pumpEventQueue();
+
+ // Verify defaults restored.
+ expect(errorProcessors, isEmpty);
+ expect(lints, isEmpty);
+ expect(options.enableGenericMethods, isFalse);
+ }
+
+ test_analysis_options_file_delete_with_embedder() async {
+ // Setup _embedder.yaml.
+ String libPath = newFolder([projPath, LIB_NAME]);
+ newFile(
+ [libPath, '_embedder.yaml'],
+ r'''
+analyzer:
+ strong-mode: true
+ errors:
+ missing_return: false
+linter:
+ rules:
+ - avoid_as
+''');
+
+ // Setup .packages file
+ newFile(
+ [projPath, '.packages'],
+ r'''
+test_pack:lib/''');
+
+ // Setup .analysis_options
+ newFile(
+ [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+ r'''
+analyzer:
+ language:
+ enableGenericMethods: true
+ errors:
+ unused_local_variable: false
+linter:
+ rules:
+ - camel_case_types
+''');
+
+ // Setup context.
+ manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+ await pumpEventQueue();
+
+ // Verify options were set.
+ expect(options.enableGenericMethods, isTrue);
+ expect(options.strongMode, isTrue);
+ expect(errorProcessors, hasLength(2));
+ expect(lints, hasLength(2));
+
+ // Remove options.
+ deleteFile([projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE]);
+ await pumpEventQueue();
+
+ // Verify defaults restored.
+ expect(options.enableGenericMethods, isFalse);
+ expect(lints, hasLength(1));
+ expect(lints.first, new isInstanceOf<AvoidAs>());
+ expect(errorProcessors, hasLength(1));
+ expect(getProcessor(missing_return).severity, isNull);
+ }
+
test_analysis_options_parse_failure() async {
// Create files.
String libPath = newFolder([projPath, LIB_NAME]);
@@ -154,6 +295,11 @@
strong-mode: true
language:
enableSuperMixins: true
+ errors:
+ missing_return: false
+linter:
+ rules:
+ - avoid_as
''');
// Setup .packages file
newFile(
@@ -172,6 +318,9 @@
enableGenericMethods: true
errors:
unused_local_variable: false
+linter:
+ rules:
+ - camel_case_types
''');
// Setup context.
@@ -186,25 +335,31 @@
var context = contexts[0];
// Verify options.
- // * from `_embedder.yaml`:
+ // * from `_embedder.yaml`:
expect(context.analysisOptions.strongMode, isTrue);
expect(context.analysisOptions.enableSuperMixins, isTrue);
- // * from `.analysis_options`:
+ // * from `.analysis_options`:
expect(context.analysisOptions.enableGenericMethods, isTrue);
- // verify tests are excluded
+ // * verify tests are excluded
expect(callbacks.currentContextFilePaths[projPath].keys,
['/my/proj/sdk_ext/entry.dart']);
// Verify filter setup.
- List<ErrorFilter> filters =
- callbacks.currentContext.getConfigurationData(CONFIGURED_ERROR_FILTERS);
- expect(filters, hasLength(1));
+ expect(errorProcessors, hasLength(2));
+
+ // * (embedder.)
+ expect(getProcessor(missing_return).severity, isNull);
+
+ // * (options.)
+ expect(getProcessor(unused_local_variable).severity, isNull);
+
+ // Verify lints.
+ var lintNames = lints.map((lint) => lint.name);
+
expect(
- filters.first(new AnalysisError(
- new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
- ['x']
- ])),
- isTrue);
+ lintNames,
+ unorderedEquals(
+ ['avoid_as' /* embedder */, 'camel_case_types' /* options */]));
// Sanity check embedder libs.
var source = context.sourceFactory.forUri('dart:foobar');
@@ -268,16 +423,8 @@
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// Verify filter setup.
- List<ErrorFilter> filters =
- callbacks.currentContext.getConfigurationData(CONFIGURED_ERROR_FILTERS);
- expect(filters, isNotNull);
- expect(filters, hasLength(1));
- expect(
- filters.first(new AnalysisError(
- new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
- ['x']
- ])),
- isTrue);
+ expect(errorProcessors, hasLength(1));
+ expect(getProcessor(unused_local_variable).severity, isNull);
}
test_error_filter_analysis_option_multiple_filters() async {
@@ -288,30 +435,16 @@
analyzer:
errors:
invalid_assignment: ignore
- unused_local_variable: ignore
+ unused_local_variable: error
''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// Verify filter setup.
- List<ErrorFilter> filters =
- callbacks.currentContext.getConfigurationData(CONFIGURED_ERROR_FILTERS);
- expect(filters, isNotNull);
- expect(filters, hasLength(2));
+ expect(errorProcessors, hasLength(2));
- var unused_error = new AnalysisError(
- new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
- ['x']
- ]);
-
- var invalid_assignment_error =
- new AnalysisError(new TestSource(), 0, 1, HintCode.INVALID_ASSIGNMENT, [
- ['x'],
- ['y']
- ]);
-
- expect(filters.any((filter) => filter(unused_error)), isTrue);
- expect(filters.any((filter) => filter(invalid_assignment_error)), isTrue);
+ expect(getProcessor(invalid_assignment_error).severity, isNull);
+ expect(getProcessor(unused_local_variable).severity, ErrorSeverity.ERROR);
}
test_error_filter_analysis_option_synonyms() async {
@@ -328,10 +461,8 @@
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// Verify filter setup.
- List<ErrorFilter> filters =
- callbacks.currentContext.getConfigurationData(CONFIGURED_ERROR_FILTERS);
- expect(filters, isNotNull);
- expect(filters, hasLength(2));
+ expect(errorProcessors, isNotNull);
+ expect(errorProcessors, hasLength(2));
}
test_error_filter_analysis_option_unpsecified() async {
@@ -347,9 +478,7 @@
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// Verify filter setup.
- List<ErrorFilter> filters =
- callbacks.currentContext.getConfigurationData(CONFIGURED_ERROR_FILTERS);
- expect(filters, isEmpty);
+ expect(errorProcessors, isEmpty);
}
test_ignoreFilesInPackagesFolder() {
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 2c6fc7b..b7f4b34 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -119,6 +119,22 @@
expect(serverRef.getResolvedCompilationUnits(fileB), isEmpty);
});
});
+
+ test('not absolute', () async {
+ var response = testSetAnalysisRoots([], ['foo/bar']);
+ expect(
+ response,
+ isResponseFailure(
+ '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+ });
+
+ test('not normalized', () async {
+ var response = testSetAnalysisRoots([], ['/foo/../bar']);
+ expect(
+ response,
+ isResponseFailure(
+ '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+ });
});
group('included', () {
@@ -147,6 +163,22 @@
await server.onAnalysisComplete;
expect(serverRef.getResolvedCompilationUnits(fileB), hasLength(1));
});
+
+ test('not absolute', () async {
+ var response = testSetAnalysisRoots(['foo/bar'], []);
+ expect(
+ response,
+ isResponseFailure(
+ '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+ });
+
+ test('not normalized', () async {
+ var response = testSetAnalysisRoots(['/foo/../bar'], []);
+ expect(
+ response,
+ isResponseFailure(
+ '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+ });
});
});
@@ -167,8 +199,9 @@
resourceProvider.newFile('/p2/b.dart', 'library b;');
resourceProvider.newFile('/p2/c.dart', 'library c;');
- var setRootsRequest = new AnalysisSetAnalysisRootsParams(
- ['/p1', '/p2'], []).toRequest('0');
+ var setRootsRequest =
+ new AnalysisSetAnalysisRootsParams(['/p1', '/p2'], [])
+ .toRequest('0');
var setRootsResponse = handler.handleRequest(setRootsRequest);
expect(setRootsResponse, isResponseSuccess('0'));
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 888b7cc..619136b 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -29,6 +29,7 @@
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
@@ -52,13 +53,23 @@
int requestCount = 0;
String testFile2 = '/project/bin/test2.dart';
- /// Cached model state in case tests need to set task model to on/off.
- bool wasTaskModelEnabled;
-
AnalysisServer createAnalysisServer(Index index) {
- ExtensionManager manager = new ExtensionManager();
+ //
+ // Collect plugins
+ //
ServerPlugin serverPlugin = new ServerPlugin();
- manager.processPlugins([serverPlugin]);
+ List<Plugin> plugins = <Plugin>[];
+ plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+ plugins.add(serverPlugin);
+ addServerPlugins(plugins);
+ //
+ // Process plugins
+ //
+ ExtensionManager manager = new ExtensionManager();
+ manager.processPlugins(plugins);
+ //
+ // Create the server
+ //
return new Test_AnalysisServer(
super.serverChannel,
super.resourceProvider,
@@ -85,8 +96,6 @@
@override
void setUp() {
super.setUp();
- wasTaskModelEnabled = AnalysisEngine.instance.useTaskModel;
- AnalysisEngine.instance.useTaskModel = true;
createProject();
analysisDomain = handler;
completionDomain = new Test_CompletionDomainHandler(server);
@@ -99,7 +108,6 @@
super.tearDown();
analysisDomain = null;
completionDomain = null;
- AnalysisEngine.instance.useTaskModel = wasTaskModelEnabled;
}
/**
@@ -464,12 +472,25 @@
expect(replacementOffset, equals(completionOffset));
expect(replacementLength, equals(0));
assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo');
assertNoResult('HtmlElement');
assertNoResult('test');
});
}
+ test_imports_prefixed2() {
+ addTestFile('''
+ import 'dart:html' as foo;
+ main() {foo.^}
+ ''');
+ return getSuggestions().then((_) {
+ expect(replacementOffset, equals(completionOffset));
+ expect(replacementLength, equals(0));
+ assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement');
+ assertNoResult('test');
+ });
+ }
+
test_invocation() {
addTestFile('class A {b() {}} main() {A a; a.^}');
return getSuggestions().then((_) {
@@ -632,6 +653,16 @@
});
}
+ test_static() {
+ addTestFile('class A {static b() {} c() {}} main() {A.^}');
+ return getSuggestions().then((_) {
+ expect(replacementOffset, equals(completionOffset));
+ expect(replacementLength, equals(0));
+ assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
+ assertNoResult('c');
+ });
+ }
+
test_topLevel() {
addTestFile('''
typedef foo();
diff --git a/pkg/analysis_server/test/domain_diagnostic_test.dart b/pkg/analysis_server/test/domain_diagnostic_test.dart
index 444e6cf..f234463 100644
--- a/pkg/analysis_server/test/domain_diagnostic_test.dart
+++ b/pkg/analysis_server/test/domain_diagnostic_test.dart
@@ -10,7 +10,9 @@
import 'package:analysis_server/src/plugin/server_plugin.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/generated/engine.dart';
import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
import 'package:unittest/unittest.dart';
import 'mock_sdk.dart';
@@ -25,11 +27,25 @@
initializeTestEnvironment();
setUp(() {
+ //
+ // Collect plugins
+ //
+ ServerPlugin serverPlugin = new ServerPlugin();
+ List<Plugin> plugins = <Plugin>[];
+ plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+ plugins.add(AnalysisEngine.instance.commandLinePlugin);
+ plugins.add(AnalysisEngine.instance.optionsPlugin);
+ plugins.add(serverPlugin);
+ //
+ // Process plugins
+ //
+ ExtensionManager manager = new ExtensionManager();
+ manager.processPlugins(plugins);
+ //
+ // Create the server
+ //
var serverChannel = new MockServerChannel();
resourceProvider = new MemoryResourceProvider();
- ExtensionManager manager = new ExtensionManager();
- ServerPlugin serverPlugin = new ServerPlugin();
- manager.processPlugins([serverPlugin]);
server = new AnalysisServer(
serverChannel,
resourceProvider,
@@ -42,10 +58,6 @@
handler = new DiagnosticDomainHandler(server);
});
- tearDown(() {
- handler.sampler?.stop();
- });
-
group('DiagnosticDomainHandler', () {
test('getDiagnostics', () async {
String file = '/project/bin/test.dart';
@@ -68,7 +80,6 @@
expect(context['explicitFileCount'], fileCount);
expect(context['implicitFileCount'], 0);
expect(context['workItemQueueLength'], isNotNull);
- expect(context['workItemQueueLengthAverage'], isNotNull);
});
test('getDiagnostics - (no root)', () async {
diff --git a/pkg/analysis_server/test/edit/sort_members_test.dart b/pkg/analysis_server/test/edit/sort_members_test.dart
index 8bae43f..a955360 100644
--- a/pkg/analysis_server/test/edit/sort_members_test.dart
+++ b/pkg/analysis_server/test/edit/sort_members_test.dart
@@ -34,8 +34,7 @@
handler = new EditDomainHandler(server);
}
- Future test_BAD_doesNotExist() async {
- await waitForTasksFinished();
+ test_BAD_doesNotExist() async {
Request request =
new EditSortMembersParams('/no/such/file.dart').toRequest('0');
Response response = handler.handleRequest(request);
@@ -43,21 +42,19 @@
isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_INVALID_FILE));
}
- Future test_BAD_hasParseError() async {
+ test_BAD_hasParseError() async {
addTestFile('''
main() {
print()
}
''');
- await waitForTasksFinished();
Request request = new EditSortMembersParams(testFile).toRequest('0');
Response response = handler.handleRequest(request);
expect(response,
isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_PARSE_ERRORS));
}
- Future test_BAD_notDartFile() async {
- await waitForTasksFinished();
+ test_BAD_notDartFile() async {
Request request =
new EditSortMembersParams('/not-a-Dart-file.txt').toRequest('0');
Response response = handler.handleRequest(request);
@@ -65,7 +62,21 @@
isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_INVALID_FILE));
}
- Future test_OK_classMembers_method() {
+ test_OK_afterWaitForAnalysis() async {
+ addTestFile('''
+class C {}
+class A {}
+class B {}
+''');
+ await waitForTasksFinished();
+ return _assertSorted(r'''
+class A {}
+class B {}
+class C {}
+''');
+ }
+
+ test_OK_classMembers_method() async {
addTestFile('''
class A {
c() {}
@@ -82,7 +93,7 @@
''');
}
- Future test_OK_directives() {
+ test_OK_directives() async {
addTestFile('''
library lib;
@@ -133,7 +144,7 @@
''');
}
- Future test_OK_unitMembers_class() {
+ test_OK_unitMembers_class() async {
addTestFile('''
class C {}
class A {}
@@ -147,7 +158,6 @@
}
Future _assertSorted(String expectedCode) async {
- await waitForTasksFinished();
_requestSort();
String resultCode = SourceEdit.applySequence(testCode, fileEdit.edits);
expect(resultCode, expectedCode);
diff --git a/pkg/analysis_server/test/integration/integration_tests.dart b/pkg/analysis_server/test/integration/integration_tests.dart
index 5004f86..f4dcfeb 100644
--- a/pkg/analysis_server/test/integration/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/integration_tests.dart
@@ -11,7 +11,6 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/constants.dart';
-import 'package:analysis_server/src/server/driver.dart' as analysisServer;
import 'package:path/path.dart';
import 'package:unittest/unittest.dart';
@@ -597,7 +596,6 @@
{bool debugServer: false,
int diagnosticPort,
bool profileServer: false,
- bool newTaskModel: true,
bool useAnalysisHighlight2: false}) {
if (_process != null) {
throw new Exception('Process already started');
@@ -627,9 +625,6 @@
if (useAnalysisHighlight2) {
arguments.add('--useAnalysisHighlight2');
}
- if (!newTaskModel) {
- arguments.add('--${analysisServer.Driver.DISABLE_NEW_TASK_MODEL}');
- }
// print('Launching $serverPath');
// print('$dartBinary ${arguments.join(' ')}');
return Process.start(dartBinary, arguments).then((Process process) {
diff --git a/pkg/analysis_server/test/integration/protocol_matchers.dart b/pkg/analysis_server/test/integration/protocol_matchers.dart
index 2a0cd06..6266cb9 100644
--- a/pkg/analysis_server/test/integration/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/protocol_matchers.dart
@@ -1307,7 +1307,6 @@
* "explicitFileCount": int
* "implicitFileCount": int
* "workItemQueueLength": int
- * "workItemQueueLengthAverage": String
* "cacheEntryExceptions": List<String>
* }
*/
@@ -1317,7 +1316,6 @@
"explicitFileCount": isInt,
"implicitFileCount": isInt,
"workItemQueueLength": isInt,
- "workItemQueueLengthAverage": isString,
"cacheEntryExceptions": isListOf(isString)
}));
@@ -2104,6 +2102,7 @@
* GET_REACHABLE_SOURCES_INVALID_FILE
* INVALID_ANALYSIS_ROOT
* INVALID_EXECUTION_CONTEXT
+ * INVALID_FILE_PATH_FORMAT
* INVALID_OVERLAY_CHANGE
* INVALID_PARAMETER
* INVALID_REQUEST
@@ -2130,6 +2129,7 @@
"GET_REACHABLE_SOURCES_INVALID_FILE",
"INVALID_ANALYSIS_ROOT",
"INVALID_EXECUTION_CONTEXT",
+ "INVALID_FILE_PATH_FORMAT",
"INVALID_OVERLAY_CHANGE",
"INVALID_PARAMETER",
"INVALID_REQUEST",
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index 99be8fc..5aaec99 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -6,7 +6,7 @@
import 'package:analyzer/file_system/file_system.dart' as resource;
import 'package:analyzer/file_system/memory_file_system.dart' as resource;
-import 'package:analyzer/src/context/context.dart' as newContext;
+import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -219,11 +219,7 @@
@override
AnalysisContext get context {
if (_analysisContext == null) {
- if (AnalysisEngine.instance.useTaskModel) {
- _analysisContext = new newContext.SdkAnalysisContext();
- } else {
- _analysisContext = new SdkAnalysisContext();
- }
+ _analysisContext = new SdkAnalysisContext();
SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
_analysisContext.sourceFactory = factory;
ChangeSet changeSet = new ChangeSet();
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index 428f53b..efc19fd 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -72,23 +72,19 @@
class MockAnalysisContext extends StringTypedMock implements AnalysisContext {
MockAnalysisContext(String name) : super(name);
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class MockClassElement extends TypedMock implements ClassElement {
final ElementKind kind = ElementKind.CLASS;
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class MockCompilationUnitElement extends TypedMock
implements CompilationUnitElement {
final ElementKind kind = ElementKind.COMPILATION_UNIT;
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class MockConstructorElement extends TypedMock implements ConstructorElement {
final kind = ElementKind.CONSTRUCTOR;
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class MockElement extends StringTypedMock implements Element {
@@ -99,55 +95,39 @@
@override
String get name => _toString;
-
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class MockFieldElement extends TypedMock implements FieldElement {
final ElementKind kind = ElementKind.FIELD;
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class MockFunctionElement extends TypedMock implements FunctionElement {
final ElementKind kind = ElementKind.FUNCTION;
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class MockFunctionTypeAliasElement extends TypedMock
implements FunctionTypeAliasElement {
final ElementKind kind = ElementKind.FUNCTION_TYPE_ALIAS;
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-class MockHtmlElement extends TypedMock implements HtmlElement {
- final ElementKind kind = ElementKind.HTML;
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class MockImportElement extends TypedMock implements ImportElement {
final ElementKind kind = ElementKind.IMPORT;
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class MockLibraryElement extends TypedMock implements LibraryElement {
final ElementKind kind = ElementKind.LIBRARY;
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class MockLocalVariableElement extends TypedMock
implements LocalVariableElement {
final ElementKind kind = ElementKind.LOCAL_VARIABLE;
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
-class MockLogger extends TypedMock implements Logger {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockLogger extends TypedMock implements Logger {}
class MockMethodElement extends StringTypedMock implements MethodElement {
final kind = ElementKind.METHOD;
MockMethodElement([String name = 'method']) : super(name);
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
/**
@@ -192,14 +172,12 @@
class MockParameterElement extends TypedMock implements ParameterElement {
final ElementKind kind = ElementKind.PARAMETER;
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class MockPropertyAccessorElement extends TypedMock
implements PropertyAccessorElement {
final ElementKind kind;
MockPropertyAccessorElement(this.kind);
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
/**
@@ -255,7 +233,7 @@
if (_closed) {
throw new Exception('sendRequest after connection closed');
}
- // Wrap send request in future to simulate websocket
+ // Wrap send request in future to simulate WebSocket.
new Future(() => requestController.add(request));
return waitForResponse(request);
}
@@ -267,7 +245,7 @@
return;
}
responsesReceived.add(response);
- // Wrap send response in future to simulate websocket
+ // Wrap send response in future to simulate WebSocket.
new Future(() => responseController.add(response));
}
@@ -342,19 +320,16 @@
class MockSource extends StringTypedMock implements Source {
MockSource([String name = 'mocked.dart']) : super(name);
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class MockTopLevelVariableElement extends TypedMock
implements TopLevelVariableElement {
final ElementKind kind = ElementKind.TOP_LEVEL_VARIABLE;
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class MockTypeParameterElement extends TypedMock
implements TypeParameterElement {
final ElementKind kind = ElementKind.TYPE_PARAMETER;
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class NoResponseException implements Exception {
diff --git a/pkg/analysis_server/test/operation/operation_queue_test.dart b/pkg/analysis_server/test/operation/operation_queue_test.dart
index ed7fbca..e6926c9 100644
--- a/pkg/analysis_server/test/operation/operation_queue_test.dart
+++ b/pkg/analysis_server/test/operation/operation_queue_test.dart
@@ -36,8 +36,6 @@
class AnalysisContextMock extends TypedMock implements InternalAnalysisContext {
List<Source> prioritySources = <Source>[];
-
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class AnalysisServerMock extends TypedMock implements AnalysisServer {
@@ -48,13 +46,9 @@
final SearchEngine searchEngine;
AnalysisServerMock({this.resourceProvider, this.searchEngine});
-
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
-class ServerContextManagerMock extends TypedMock implements ContextManager {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class ServerContextManagerMock extends TypedMock implements ContextManager {}
@reflectiveTest
class ServerOperationQueueTest {
@@ -230,21 +224,15 @@
ServerOperationPriority get priority {
return ServerOperationPriority.ANALYSIS_NOTIFICATION;
}
-
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class _ServerOperationMock extends TypedMock implements ServerOperation {
final AnalysisContext context;
_ServerOperationMock([this.context]);
-
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
-class _SourceMock extends TypedMock implements Source {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _SourceMock extends TypedMock implements Source {}
class _SourceSensitiveOperationMock extends TypedMock
implements SourceSensitiveOperation {
@@ -257,8 +245,6 @@
return ServerOperationPriority.ANALYSIS_NOTIFICATION;
}
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
@override
bool shouldBeDiscardedOnSourceChange(Source source) {
return source == this.source;
diff --git a/pkg/analysis_server/test/plugin/set_analysis_domain_test.dart b/pkg/analysis_server/test/plugin/set_analysis_domain_test.dart
index 592b8dd..a92c943 100644
--- a/pkg/analysis_server/test/plugin/set_analysis_domain_test.dart
+++ b/pkg/analysis_server/test/plugin/set_analysis_domain_test.dart
@@ -25,9 +25,7 @@
main() {
initializeTestEnvironment();
- if (AnalysisEngine.instance.useTaskModel) {
- defineReflectiveTests(SetAnalysisDomainTest);
- }
+ defineReflectiveTests(SetAnalysisDomainTest);
}
/**
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index 5f503b6..a210a94 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -26,9 +26,7 @@
defineReflectiveTests(EnumTest);
}
-class AnalysisErrorMock extends TypedMock implements engine.AnalysisError {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class AnalysisErrorMock extends TypedMock implements engine.AnalysisError {}
@reflectiveTest
class AnalysisErrorTest {
diff --git a/pkg/analysis_server/test/services/completion/completion_test_util.dart b/pkg/analysis_server/test/services/completion/completion_test_util.dart
index 63180b7..7812fd8 100644
--- a/pkg/analysis_server/test/services/completion/completion_test_util.dart
+++ b/pkg/analysis_server/test/services/completion/completion_test_util.dart
@@ -16,7 +16,6 @@
import 'package:analysis_server/src/services/completion/dart_completion_cache.dart';
import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
import 'package:analysis_server/src/services/completion/imported_reference_contributor.dart';
-import 'package:analysis_server/src/services/completion/prefixed_element_contributor.dart';
import 'package:analysis_server/src/services/index/index.dart';
import 'package:analysis_server/src/services/index/local_memory_index.dart';
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
@@ -356,29 +355,6 @@
return cs;
}
- CompletionSuggestion assertSuggestNamedConstructor(
- String name, String returnType,
- [int relevance = DART_RELEVANCE_DEFAULT,
- CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
- if (contributor is PrefixedElementContributor) {
- CompletionSuggestion cs =
- assertSuggest(name, csKind: kind, relevance: relevance);
- protocol.Element element = cs.element;
- expect(element, isNotNull);
- expect(element.kind, equals(protocol.ElementKind.CONSTRUCTOR));
- expect(element.name, equals(name));
- String param = element.parameters;
- expect(param, isNotNull);
- expect(param[0], equals('('));
- expect(param[param.length - 1], equals(')'));
- expect(element.returnType, equals(returnType));
- assertHasParameterInfo(cs);
- return cs;
- } else {
- return assertNotSuggested(name);
- }
- }
-
CompletionSuggestion assertSuggestParameter(String name, String returnType,
{int relevance: DART_RELEVANCE_PARAMETER}) {
return assertNotSuggested(name);
@@ -660,11 +636,7 @@
CompletionSuggestion assertSuggestInvocationClass(String name,
[int relevance = DART_RELEVANCE_DEFAULT]) {
- if (contributor is PrefixedElementContributor) {
- return assertSuggestClass(name, relevance: relevance);
- } else {
- return assertNotSuggested(name);
- }
+ return assertNotSuggested(name);
}
CompletionSuggestion assertSuggestInvocationField(String name, String type,
@@ -675,42 +647,24 @@
CompletionSuggestion assertSuggestInvocationGetter(
String name, String returnType,
{int relevance: DART_RELEVANCE_DEFAULT, bool isDeprecated: false}) {
- if (contributor is PrefixedElementContributor) {
- return assertSuggestGetter(name, returnType,
- relevance: relevance, isDeprecated: isDeprecated);
- } else {
- return assertNotSuggested(name);
- }
+ return assertNotSuggested(name);
}
CompletionSuggestion assertSuggestInvocationMethod(
String name, String declaringType, String returnType,
{int relevance: DART_RELEVANCE_DEFAULT}) {
- if (contributor is PrefixedElementContributor) {
- return assertSuggestMethod(name, declaringType, returnType,
- relevance: relevance);
- } else {
- return assertNotSuggested(name);
- }
+ return assertNotSuggested(name);
}
CompletionSuggestion assertSuggestInvocationSetter(String name,
[int relevance = DART_RELEVANCE_DEFAULT]) {
- if (contributor is PrefixedElementContributor) {
- return assertSuggestSetter(name);
- } else {
- return assertNotSuggested(name);
- }
+ return assertNotSuggested(name);
}
CompletionSuggestion assertSuggestInvocationTopLevelVar(
String name, String returnType,
[int relevance = DART_RELEVANCE_DEFAULT]) {
- if (contributor is PrefixedElementContributor) {
- return assertSuggestTopLevelVar(name, returnType, relevance);
- } else {
- return assertNotSuggested(name);
- }
+ return assertNotSuggested(name);
}
CompletionSuggestion assertSuggestLocalClass(String name,
@@ -1336,7 +1290,8 @@
assertSuggestImportedClass('EE');
// hidden element suggested as low relevance
//assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
- assertSuggestLibraryPrefix('g');
+ // Suggested by LibraryPrefixContributor
+ assertNotSuggested('g');
assertNotSuggested('G');
//assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
assertSuggestImportedClass('Object');
@@ -1447,7 +1402,8 @@
assertSuggestImportedClass('EE');
// hidden element suggested as low relevance
//assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
- assertSuggestLibraryPrefix('g');
+ // Suggested by LibraryPrefixContributor
+ assertNotSuggested('g');
assertNotSuggested('G');
//assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
assertSuggestImportedClass('Object');
@@ -1570,7 +1526,8 @@
assertSuggestImportedClass('EE');
// hidden element suggested as low relevance
//assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
- assertSuggestLibraryPrefix('g');
+ // Suggested by LibraryPrefixContributor
+ assertNotSuggested('g');
assertNotSuggested('G');
//assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
assertSuggestImportedClass('Object');
@@ -1677,7 +1634,8 @@
assertSuggestImportedClass('EE');
// hidden element suggested as low relevance
//assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
- assertSuggestLibraryPrefix('g');
+ // Suggested by LibraryPrefixContributor
+ assertNotSuggested('g');
assertNotSuggested('G');
//assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
assertSuggestImportedClass('Object');
@@ -2124,7 +2082,8 @@
expect(suggestionO.element.isPrivate, isFalse);
}
assertNotSuggested('T');
- assertSuggestLibraryPrefix('x');
+ // Suggested by LibraryPrefixContributor
+ assertNotSuggested('x');
});
}
@@ -2147,7 +2106,8 @@
assertSuggestLocalClass('_B');
assertSuggestImportedClass('Object');
assertNotSuggested('T');
- assertSuggestLibraryPrefix('x');
+ // Suggested by LibraryPrefixContributor
+ assertNotSuggested('x');
});
}
@@ -2170,7 +2130,8 @@
assertSuggestLocalClass('_B');
assertSuggestImportedClass('String');
assertNotSuggested('T');
- assertSuggestLibraryPrefix('x');
+ // Suggested by LibraryPrefixContributor
+ assertNotSuggested('x');
});
}
@@ -2193,7 +2154,8 @@
assertSuggestLocalClass('_B');
assertSuggestImportedClass('String');
assertNotSuggested('Sew');
- assertSuggestLibraryPrefix('Soo');
+ // Suggested by LibraryPrefixContributor
+ assertNotSuggested('Soo');
});
}
@@ -2216,7 +2178,8 @@
assertSuggestLocalClass('_B');
assertSuggestImportedClass('Object');
assertNotSuggested('T');
- assertSuggestLibraryPrefix('x');
+ // Suggested by LibraryPrefixContributor
+ assertNotSuggested('x');
});
}
@@ -2239,7 +2202,8 @@
assertSuggestLocalClass('_B');
assertSuggestImportedClass('Object');
assertNotSuggested('T');
- assertSuggestLibraryPrefix('x');
+ // Suggested by LibraryPrefixContributor
+ assertNotSuggested('x');
});
}
@@ -2452,7 +2416,8 @@
return computeFull((bool result) {
expect(request.replacementOffset, completionOffset);
expect(request.replacementLength, 0);
- assertSuggestNamedConstructor('c', 'X');
+ // Suggested by NamedConstructorContributor
+ assertNotSuggested('c');
assertNotSuggested('F1');
assertNotSuggested('T1');
assertNotSuggested('_d');
@@ -2479,7 +2444,8 @@
return computeFull((bool result) {
expect(request.replacementOffset, completionOffset);
expect(request.replacementLength, 0);
- assertSuggestNamedConstructor('c', 'X');
+ // Suggested by NamedConstructorContributor
+ assertNotSuggested('c');
assertNotSuggested('F1');
assertNotSuggested('T1');
assertNotSuggested('_d');
@@ -2497,7 +2463,8 @@
return computeFull((bool result) {
expect(request.replacementOffset, completionOffset - 2);
expect(request.replacementLength, 13);
- assertSuggestNamedConstructor('fromCharCodes', 'String');
+ // Suggested by NamedConstructorContributor
+ assertNotSuggested('fromCharCodes');
assertNotSuggested('isEmpty');
assertNotSuggested('isNotEmpty');
assertNotSuggested('length');
@@ -2518,8 +2485,9 @@
return computeFull((bool result) {
expect(request.replacementOffset, completionOffset);
expect(request.replacementLength, 0);
- assertSuggestNamedConstructor('c', 'X');
- assertSuggestNamedConstructor('_d', 'X');
+ // Suggested by NamedConstructorContributor
+ assertNotSuggested('c');
+ assertNotSuggested('_d');
assertNotSuggested('F1');
assertNotSuggested('T1');
assertNotSuggested('z');
@@ -2539,8 +2507,9 @@
return computeFull((bool result) {
expect(request.replacementOffset, completionOffset);
expect(request.replacementLength, 0);
- assertSuggestNamedConstructor('c', 'X');
- assertSuggestNamedConstructor('_d', 'X');
+ // Suggested by NamedConstructorContributor
+ assertNotSuggested('c');
+ assertNotSuggested('_d');
assertNotSuggested('F1');
assertNotSuggested('T1');
assertNotSuggested('z');
@@ -3878,9 +3847,10 @@
return computeFull((bool result) {
expect(request.replacementOffset, completionOffset);
expect(request.replacementLength, 0);
- assertSuggestInvocationField('scA', 'String');
- assertSuggestInvocationField('scB', 'int');
- assertSuggestInvocationField('scI', null);
+ // Suggested by StaticMemberContributor
+ assertNotSuggested('scA');
+ assertNotSuggested('scB');
+ assertNotSuggested('scI');
assertNotSuggested('b');
assertNotSuggested('_c');
assertNotSuggested('d');
@@ -4002,9 +3972,10 @@
return computeFull((bool result) {
expect(request.replacementOffset, completionOffset);
expect(request.replacementLength, 0);
- assertSuggestInvocationClass('X');
- assertSuggestInvocationClass('Y');
- assertSuggestInvocationTopLevelVar('T1', null);
+ // Suggested by LibraryMemberContributor
+ assertNotSuggested('X');
+ assertNotSuggested('Y');
+ assertNotSuggested('T1');
assertNotSuggested('T2');
assertNotSuggested('Object');
assertNotSuggested('b');
@@ -4031,8 +4002,9 @@
return computeFull((bool result) {
expect(request.replacementOffset, completionOffset);
expect(request.replacementLength, 0);
- assertSuggestInvocationClass('X');
- assertSuggestInvocationClass('Y');
+ // Suggested by LibraryMemberContributor
+ assertNotSuggested('X');
+ assertNotSuggested('Y');
assertNotSuggested('T1');
assertNotSuggested('T2');
assertNotSuggested('Object');
@@ -4060,8 +4032,9 @@
return computeFull((bool result) {
expect(request.replacementOffset, completionOffset);
expect(request.replacementLength, 0);
- assertSuggestInvocationClass('X');
- assertSuggestInvocationClass('Y');
+ // Suggested by LibraryMemberContributor
+ assertNotSuggested('X');
+ assertNotSuggested('Y');
assertNotSuggested('T1');
assertNotSuggested('T2');
assertNotSuggested('Object');
diff --git a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
index 273509c..0a14ef1 100644
--- a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
@@ -31,15 +31,19 @@
void assertSuggestArgumentList(
List<String> paramNames, List<String> paramTypes) {
- CompletionSuggestionKind csKind = CompletionSuggestionKind.ARGUMENT_LIST;
- CompletionSuggestion cs = getSuggest(csKind: csKind);
- if (cs == null) {
- failedCompletion('expected completion $csKind', suggestions);
- }
- assertSuggestArgumentList_params(
- paramNames, paramTypes, cs.parameterNames, cs.parameterTypes);
- expect(cs.relevance, DART_RELEVANCE_HIGH);
- assertNoOtherSuggestions([cs]);
+ // DEPRECATED... argument lists are no longer suggested.
+ // See https://github.com/dart-lang/sdk/issues/25197
+ assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+
+ // CompletionSuggestionKind csKind = CompletionSuggestionKind.ARGUMENT_LIST;
+ // CompletionSuggestion cs = getSuggest(csKind: csKind);
+ // if (cs == null) {
+ // failedCompletion('expected completion $csKind', suggestions);
+ // }
+ // assertSuggestArgumentList_params(
+ // paramNames, paramTypes, cs.parameterNames, cs.parameterTypes);
+ // expect(cs.relevance, DART_RELEVANCE_HIGH);
+ // assertNoOtherSuggestions([cs]);
}
void assertSuggestArgumentList_params(
@@ -302,6 +306,27 @@
assertNoSuggestions();
}
+ test_ArgumentList_imported_function_named_param_label1() async {
+ //
+ addTestSource('main() { int.parse("16", r^: 16);}');
+ await computeSuggestions();
+ assertSuggestArguments(namedArguments: ['radix', 'onError']);
+ }
+
+ test_ArgumentList_imported_function_named_param_label2() async {
+ //
+ addTestSource('main() { int.parse("16", ^r: 16);}');
+ await computeSuggestions();
+ assertSuggestArguments(namedArguments: ['radix', 'onError']);
+ }
+
+ test_ArgumentList_imported_function_named_param_label3() async {
+ //
+ addTestSource('main() { int.parse("16", ^: 16);}');
+ await computeSuggestions();
+ assertSuggestArguments(namedArguments: ['radix', 'onError']);
+ }
+
test_ArgumentList_local_constructor_named_param() async {
//
addTestSource('''
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index d75024b..59e5e69 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -368,6 +368,9 @@
if (libraries.isNotEmpty) {
return new Future.value(libraries);
}
+ if (times == 0) {
+ fail('failed to determine libraries containing $testSource');
+ }
context.performAnalysisTask();
// We use a delayed future to allow microtask events to finish. The
// Future.value or Future() constructors use scheduleMicrotask themselves and
@@ -380,23 +383,33 @@
Future computeSuggestions([int times = 200]) async {
CompletionRequestImpl baseRequest = new CompletionRequestImpl(
context, provider, searchEngine, testSource, completionOffset);
- request = new DartCompletionRequestImpl.forRequest(baseRequest);
+
+ // Build the request
+ Completer<DartCompletionRequest> requestCompleter =
+ new Completer<DartCompletionRequest>();
+ DartCompletionRequestImpl
+ .from(baseRequest)
+ .then((DartCompletionRequest request) {
+ requestCompleter.complete(request);
+ });
+ request = await performAnalysis(times, requestCompleter);
+
var range = new ReplacementRange.compute(request.offset, request.target);
replacementOffset = range.offset;
replacementLength = range.length;
- Completer<List<CompletionSuggestion>> completer =
+ Completer<List<CompletionSuggestion>> suggestionCompleter =
new Completer<List<CompletionSuggestion>>();
// Request completions
contributor
.computeSuggestions(request)
.then((List<CompletionSuggestion> computedSuggestions) {
- completer.complete(computedSuggestions);
+ suggestionCompleter.complete(computedSuggestions);
});
// Perform analysis until the suggestions have been computed
// or the max analysis cycles ([times]) has been reached
- suggestions = await performAnalysis(times, completer);
+ suggestions = await performAnalysis(times, suggestionCompleter);
expect(suggestions, isNotNull, reason: 'expected suggestions');
}
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index 8933b0a..1d3549d 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -333,13 +333,15 @@
addTestSource('main() {foo(() ^ {}}}');
await computeSuggestions();
assertSuggestKeywords([],
- pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+ pseudoKeywords: ['async', 'async*', 'sync*'],
+ relevance: DART_RELEVANCE_HIGH);
}
test_anonymous_function_async2() async {
addTestSource('main() {foo(() a^ {}}}');
await computeSuggestions();
- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, pseudoKeywords: ['async']);
+ assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+ pseudoKeywords: ['async', 'async*', 'sync*']);
}
test_anonymous_function_async3() async {
@@ -348,6 +350,20 @@
assertSuggestKeywords([]);
}
+ test_anonymous_function_async4() async {
+ addTestSource('main() {foo(() ^ => 2}}');
+ await computeSuggestions();
+ assertSuggestKeywords([],
+ pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+ }
+
+ test_anonymous_function_async5() async {
+ addTestSource('main() {foo(() ^}}');
+ await computeSuggestions();
+ assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE,
+ pseudoKeywords: ['async', 'async*', 'sync*']);
+ }
+
test_argument() async {
addTestSource('main() {foo(^);}');
await computeSuggestions();
@@ -651,35 +667,40 @@
addTestSource('main()^');
await computeSuggestions();
assertSuggestKeywords(DECLARATION_KEYWORDS,
- pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+ pseudoKeywords: ['async', 'async*', 'sync*'],
+ relevance: DART_RELEVANCE_HIGH);
}
test_function_async2() async {
addTestSource('main()^{}');
await computeSuggestions();
assertSuggestKeywords([],
- pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+ pseudoKeywords: ['async', 'async*', 'sync*'],
+ relevance: DART_RELEVANCE_HIGH);
}
test_function_async3() async {
addTestSource('main()a^');
await computeSuggestions();
assertSuggestKeywords(DECLARATION_KEYWORDS,
- pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+ pseudoKeywords: ['async', 'async*', 'sync*'],
+ relevance: DART_RELEVANCE_HIGH);
}
test_function_async4() async {
addTestSource('main()a^{}');
await computeSuggestions();
assertSuggestKeywords(DECLARATION_KEYWORDS,
- pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+ pseudoKeywords: ['async', 'async*', 'sync*'],
+ relevance: DART_RELEVANCE_HIGH);
}
test_function_async5() async {
addTestSource('main()a^ Foo foo;');
await computeSuggestions();
assertSuggestKeywords(DECLARATION_KEYWORDS,
- pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+ pseudoKeywords: ['async', 'async*', 'sync*'],
+ relevance: DART_RELEVANCE_HIGH);
}
test_function_body_inClass_constructorInitializer() async {
@@ -706,6 +727,19 @@
assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, pseudoKeywords: ['await']);
}
+ test_function_body_inClass_constructorInitializer_async_star() async {
+ addTestSource(r'''
+ foo(p) {}
+ class A {
+ final f;
+ A() : f = foo(() async* {^});
+ }
+ ''');
+ await computeSuggestions();
+ assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+ pseudoKeywords: ['await', 'yield', 'yield*']);
+ }
+
test_function_body_inClass_field() async {
addTestSource(r'''
class A {
@@ -756,6 +790,21 @@
assertSuggestKeywords(STMT_START_IN_CLASS, pseudoKeywords: ['await']);
}
+ test_function_body_inClass_methodBody_inFunction_async_star() async {
+ addTestSource(r'''
+ class A {
+ m() {
+ f() {
+ f2() async* {^};
+ };
+ }
+ }
+ ''');
+ await computeSuggestions();
+ assertSuggestKeywords(STMT_START_IN_CLASS,
+ pseudoKeywords: ['await', 'yield', 'yield*']);
+ }
+
test_function_body_inUnit() async {
addTestSource('main() {^}');
await computeSuggestions();
@@ -774,6 +823,34 @@
assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, pseudoKeywords: ['await']);
}
+ test_function_body_inUnit_async_star() async {
+ addTestSource('main() async* {n^}');
+ await computeSuggestions();
+ assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+ pseudoKeywords: ['await', 'yield', 'yield*']);
+ }
+
+ test_function_body_inUnit_async_star2() async {
+ addTestSource('main() async* {n^ foo}');
+ await computeSuggestions();
+ assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+ pseudoKeywords: ['await', 'yield', 'yield*']);
+ }
+
+ test_function_body_inUnit_sync_star() async {
+ addTestSource('main() sync* {n^}');
+ await computeSuggestions();
+ assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+ pseudoKeywords: ['await', 'yield', 'yield*']);
+ }
+
+ test_function_body_inUnit_sync_star2() async {
+ addTestSource('main() sync* {n^ foo}');
+ await computeSuggestions();
+ assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+ pseudoKeywords: ['await', 'yield', 'yield*']);
+ }
+
test_if_expression_in_class() async {
addTestSource('class A {foo() {if (^) }}');
await computeSuggestions();
@@ -1098,38 +1175,44 @@
test_method_async() async {
addTestSource('class A { foo() ^}');
await computeSuggestions();
- assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
+ assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+ pseudoKeywords: ['async', 'async*', 'sync*']);
}
test_method_async2() async {
addTestSource('class A { foo() ^{}}');
await computeSuggestions();
assertSuggestKeywords([],
- pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+ pseudoKeywords: ['async', 'async*', 'sync*'],
+ relevance: DART_RELEVANCE_HIGH);
}
test_method_async3() async {
addTestSource('class A { foo() a^}');
await computeSuggestions();
- assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
+ assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+ pseudoKeywords: ['async', 'async*', 'sync*']);
}
test_method_async4() async {
addTestSource('class A { foo() a^{}}');
await computeSuggestions();
- assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
+ assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+ pseudoKeywords: ['async', 'async*', 'sync*']);
}
test_method_async5() async {
addTestSource('class A { foo() ^ Foo foo;}');
await computeSuggestions();
- assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
+ assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+ pseudoKeywords: ['async', 'async*', 'sync*']);
}
test_method_async6() async {
addTestSource('class A { foo() a^ Foo foo;}');
await computeSuggestions();
- assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
+ assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+ pseudoKeywords: ['async', 'async*', 'sync*']);
}
test_method_async7() async {
@@ -1142,7 +1225,8 @@
test_method_async8() async {
addTestSource('class A { foo() a^ Foo foo;}');
await computeSuggestions();
- assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
+ assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+ pseudoKeywords: ['async', 'async*', 'sync*']);
}
test_method_body() async {
@@ -1175,6 +1259,13 @@
assertSuggestKeywords(STMT_START_IN_CLASS, pseudoKeywords: ['await']);
}
+ test_method_body_async_star() async {
+ addTestSource('class A { foo() async* {^}}');
+ await computeSuggestions();
+ assertSuggestKeywords(STMT_START_IN_CLASS,
+ pseudoKeywords: ['await', 'yield', 'yield*']);
+ }
+
test_method_body_async2() async {
addTestSource('class A { foo() async => ^}');
await computeSuggestions();
diff --git a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
new file mode 100644
index 0000000..ac38fa6
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
@@ -0,0 +1,262 @@
+// 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 test.services.completion.contributor.dart.library_member;
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/library_member_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+ initializeTestEnvironment();
+ defineReflectiveTests(LibraryMemberContributorTest);
+}
+
+@reflectiveTest
+class LibraryMemberContributorTest extends DartCompletionContributorTest {
+ @override
+ DartCompletionContributor createContributor() {
+ return new LibraryMemberContributor();
+ }
+
+ test_libraryPrefix() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('import "dart:async" as bar; foo() {bar.^}');
+ await computeSuggestions();
+ assertSuggestClass('Future');
+ assertNotSuggested('loadLibrary');
+ }
+
+ test_libraryPrefix_cascade() async {
+ addTestSource('''
+ import "dart:math" as math;
+ main() {math..^}''');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_libraryPrefix_cascade2() async {
+ addTestSource('''
+ import "dart:math" as math;
+ main() {math.^.}''');
+ await computeSuggestions();
+ assertSuggestFunction('min', 'num');
+ }
+
+ test_libraryPrefix_cascade3() async {
+ addTestSource('''
+ import "dart:math" as math;
+ main() {math..^a}''');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_libraryPrefix_cascade4() async {
+ addTestSource('''
+ import "dart:math" as math;
+ main() {math.^.a}''');
+ await computeSuggestions();
+ assertSuggestFunction('min', 'num');
+ }
+
+ test_libraryPrefix2() async {
+ // SimpleIdentifier MethodInvocation ExpressionStatement
+ addTestSource('import "dart:async" as bar; foo() {bar.^ print("f")}');
+ await computeSuggestions();
+ assertSuggestClass('Future');
+ }
+
+ test_libraryPrefix3() async {
+ // SimpleIdentifier MethodInvocation ExpressionStatement
+ addTestSource('import "dart:async" as bar; foo() {new bar.F^ print("f")}');
+ await computeSuggestions();
+ assertSuggestConstructor('Future');
+ assertSuggestConstructor('Future.delayed');
+ }
+
+ test_libraryPrefix_deferred() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('import "dart:async" deferred as bar; foo() {bar.^}');
+ await computeSuggestions();
+ assertSuggestClass('Future');
+ assertSuggestFunction('loadLibrary', 'Future<dynamic>');
+ }
+
+ test_libraryPrefix_deferred_inPart() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ var libFile = '${testFile.substring(0, testFile.length - 5)}A.dart';
+ addSource(
+ libFile,
+ '''
+ library testA;
+ import "dart:async" deferred as bar;
+ part "$testFile";''');
+ addTestSource('part of testA; foo() {bar.^}');
+ // Assume that libraries containing has been computed for part files
+ await computeLibrariesContaining();
+ await computeSuggestions();
+ assertSuggestClass('Future');
+ assertSuggestFunction('loadLibrary', 'Future<dynamic>');
+ }
+
+ test_libraryPrefix_with_exports() async {
+ addSource('/libA.dart', 'library libA; class A { }');
+ addSource('/libB.dart', 'library libB; export "/libA.dart"; class B { }');
+ addTestSource('import "/libB.dart" as foo; main() {foo.^} class C { }');
+ await computeSuggestions();
+ assertSuggestClass('B');
+ assertSuggestClass('A');
+ }
+
+ test_PrefixedIdentifier_library() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ var T1;
+ class X { }
+ class Y { }''');
+ addTestSource('''
+ import "/testB.dart" as b;
+ var T2;
+ class A { }
+ main() {b.^}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestClass('X');
+ assertSuggestClass('Y');
+ assertSuggestTopLevelVar('T1', null);
+ assertNotSuggested('T2');
+ assertNotSuggested('Object');
+ assertNotSuggested('b');
+ assertNotSuggested('A');
+ assertNotSuggested('==');
+ }
+
+ test_PrefixedIdentifier_library_inPart() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ var libFile = '${testFile.substring(0, testFile.length - 5)}A.dart';
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ var T1;
+ class X { }
+ class Y { }''');
+ addSource(
+ libFile,
+ '''
+ library testA;
+ import "/testB.dart" as b;
+ part "$testFile";
+ var T2;
+ class A { }''');
+ addTestSource('''
+ part of testA;
+ main() {b.^}''');
+ // Assume that libraries containing has been computed for part files
+ await computeLibrariesContaining();
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestClass('X');
+ assertSuggestClass('Y');
+ assertSuggestTopLevelVar('T1', null);
+ assertNotSuggested('T2');
+ assertNotSuggested('Object');
+ assertNotSuggested('b');
+ assertNotSuggested('A');
+ assertNotSuggested('==');
+ }
+
+ test_PrefixedIdentifier_library_typesOnly() async {
+ // SimpleIdentifier PrefixedIdentifier TypeName
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ var T1;
+ class X { }
+ class Y { }''');
+ addTestSource('''
+ import "/testB.dart" as b;
+ var T2;
+ class A { }
+ foo(b.^ f) {}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestClass('X');
+ assertSuggestClass('Y');
+ assertNotSuggested('T1');
+ assertNotSuggested('T2');
+ assertNotSuggested('Object');
+ assertNotSuggested('b');
+ assertNotSuggested('A');
+ assertNotSuggested('==');
+ }
+
+ test_PrefixedIdentifier_library_typesOnly2() async {
+ // SimpleIdentifier PrefixedIdentifier TypeName
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ var T1;
+ class X { }
+ class Y { }''');
+ addTestSource('''
+ import "/testB.dart" as b;
+ var T2;
+ class A { }
+ foo(b.^) {}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestClass('X');
+ assertSuggestClass('Y');
+ assertNotSuggested('T1');
+ assertNotSuggested('T2');
+ assertNotSuggested('Object');
+ assertNotSuggested('b');
+ assertNotSuggested('A');
+ assertNotSuggested('==');
+ }
+
+ test_PrefixedIdentifier_parameter() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ class _W {M y; var _z;}
+ class X extends _W {}
+ class M{}''');
+ addTestSource('''
+ import "/testB.dart";
+ foo(X x) {x.^}''');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_PrefixedIdentifier_prefix() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addSource(
+ '/testA.dart',
+ '''
+ class A {static int bar = 10;}
+ _B() {}''');
+ addTestSource('''
+ import "/testA.dart";
+ class X {foo(){A^.bar}}''');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
new file mode 100644
index 0000000..2de1f23
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
@@ -0,0 +1,377 @@
+// 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 test.services.completion.contributor.dart.library_prefix;
+
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/library_prefix_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+ initializeTestEnvironment();
+ defineReflectiveTests(LibraryPrefixContributorTest);
+}
+
+@reflectiveTest
+class LibraryPrefixContributorTest extends DartCompletionContributorTest {
+ void assertSuggestLibraryPrefixes(List<String> expectedPrefixes) {
+ for (String prefix in expectedPrefixes) {
+ CompletionSuggestion cs = assertSuggest(prefix,
+ csKind: CompletionSuggestionKind.IDENTIFIER,
+ relevance: DART_RELEVANCE_DEFAULT);
+ Element element = cs.element;
+ expect(element, isNotNull);
+ expect(element.kind, equals(ElementKind.LIBRARY));
+ expect(element.parameters, isNull);
+ expect(element.returnType, isNull);
+ assertHasNoParameterInfo(cs);
+ }
+ if (suggestions.length != expectedPrefixes.length) {
+ failedCompletion('expected only ${expectedPrefixes.length} suggestions');
+ }
+ }
+
+ @override
+ DartCompletionContributor createContributor() {
+ return new LibraryPrefixContributor();
+ }
+
+ test_Block() async {
+ // Block BlockFunctionBody MethodDeclaration
+ addSource(
+ '/testAB.dart',
+ '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+ addSource(
+ '/testCD.dart',
+ '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+ addSource(
+ '/testEEF.dart',
+ '''
+class EE { }
+class F { }''');
+ addSource('/testG.dart', 'class G { }');
+ addSource(
+ '/testH.dart',
+ '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+ addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+ int get clog => 8;
+ set blog(value) { }
+ a() {
+ var f;
+ localF(int arg1) { }
+ {var x;}
+ ^ var r;
+ }
+ void b() { }}
+class Z { }''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestLibraryPrefixes(['g']);
+ }
+
+ test_Block_final_final() async {
+ // Block BlockFunctionBody MethodDeclaration
+ addSource(
+ '/testAB.dart',
+ '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+ addSource(
+ '/testCD.dart',
+ '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+ addSource(
+ '/testEEF.dart',
+ '''
+class EE { }
+class F { }''');
+ addSource('/testG.dart', 'class G { }');
+ addSource(
+ '/testH.dart',
+ '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+ addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+ int get clog => 8;
+ set blog(value) { }
+ a() {
+ final ^
+ final var f;
+ localF(int arg1) { }
+ {var x;}
+ }
+ void b() { }}
+class Z { }''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestLibraryPrefixes(['g']);
+ }
+
+ test_Block_final_var() async {
+ // Block BlockFunctionBody MethodDeclaration
+ addSource(
+ '/testAB.dart',
+ '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+ addSource(
+ '/testCD.dart',
+ '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+ addSource(
+ '/testEEF.dart',
+ '''
+class EE { }
+class F { }''');
+ addSource('/testG.dart', 'class G { }');
+ addSource(
+ '/testH.dart',
+ '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+ addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+ int get clog => 8;
+ set blog(value) { }
+ a() {
+ final ^
+ var f;
+ localF(int arg1) { }
+ {var x;}
+ }
+ void b() { }}
+class Z { }''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestLibraryPrefixes(['g']);
+ }
+
+ test_ClassDeclaration_body() async {
+ // ClassDeclaration CompilationUnit
+ addSource(
+ '/testB.dart',
+ '''
+class B { }''');
+ addTestSource('''
+import "testB.dart" as x;
+@deprecated class A {^}
+class _B {}
+A T;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestLibraryPrefixes(['x']);
+ }
+
+ test_ClassDeclaration_body_final() async {
+ // ClassDeclaration CompilationUnit
+ addSource(
+ '/testB.dart',
+ '''
+class B { }''');
+ addTestSource('''
+import "testB.dart" as x;
+class A {final ^}
+class _B {}
+A T;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestLibraryPrefixes(['x']);
+ }
+
+ test_ClassDeclaration_body_final_field() async {
+ // ClassDeclaration CompilationUnit
+ addSource(
+ '/testB.dart',
+ '''
+class B { }''');
+ addTestSource('''
+import "testB.dart" as x;
+class A {final ^ A(){}}
+class _B {}
+A T;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestLibraryPrefixes(['x']);
+ }
+
+ test_ClassDeclaration_body_final_field2() async {
+ // ClassDeclaration CompilationUnit
+ addSource(
+ '/testB.dart',
+ '''
+class B { }''');
+ addTestSource('''
+import "testB.dart" as Soo;
+class A {final S^ A();}
+class _B {}
+A Sew;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+ assertSuggestLibraryPrefixes(['Soo']);
+ }
+
+ test_ClassDeclaration_body_final_final() async {
+ // ClassDeclaration CompilationUnit
+ addSource(
+ '/testB.dart',
+ '''
+class B { }''');
+ addTestSource('''
+import "testB.dart" as x;
+class A {final ^ final foo;}
+class _B {}
+A T;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestLibraryPrefixes(['x']);
+ }
+
+ test_ClassDeclaration_body_final_var() async {
+ // ClassDeclaration CompilationUnit
+ addSource(
+ '/testB.dart',
+ '''
+class B { }''');
+ addTestSource('''
+import "testB.dart" as x;
+class A {final ^ var foo;}
+class _B {}
+A T;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestLibraryPrefixes(['x']);
+ }
+
+ test_InstanceCreationExpression() async {
+ addSource(
+ '/testA.dart',
+ '''
+class A {foo(){var f; {var x;}}}
+class B {B(this.x, [String boo]) { } int x;}
+class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
+ addTestSource('''
+import "/testA.dart" as t;
+import "dart:math" as math;
+main() {new ^ String x = "hello";}''');
+ await computeSuggestions();
+ assertSuggestLibraryPrefixes(['math', 't']);
+ }
+
+ test_InstanceCreationExpression2() async {
+ addTestSource('import "dart:convert" as json;f() {var x=new js^}');
+ await computeSuggestions();
+ assertSuggestLibraryPrefixes(['json']);
+ }
+
+ test_InstanceCreationExpression_inPart() async {
+ addSource(
+ '/testA.dart',
+ '''
+class A {foo(){var f; {var x;}}}
+class B {B(this.x, [String boo]) { } int x;}
+class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
+ addSource(
+ '/testB.dart',
+ '''
+library testB;
+import "/testA.dart" as t;
+import "dart:math" as math;
+part "$testFile"
+main() {new ^ String x = "hello";}''');
+ addTestSource('''
+part of testB;
+main() {new ^ String x = "hello";}''');
+ await computeLibrariesContaining();
+ await computeSuggestions();
+ assertSuggestLibraryPrefixes(['math', 't']);
+ }
+
+ test_InstanceCreationExpression_inPart_detached() async {
+ addSource(
+ '/testA.dart',
+ '''
+class A {foo(){var f; {var x;}}}
+class B {B(this.x, [String boo]) { } int x;}
+class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
+ addSource(
+ '/testB.dart',
+ '''
+library testB;
+import "/testA.dart" as t;
+import "dart:math" as math;
+//part "$testFile"
+main() {new ^ String x = "hello";}''');
+ addTestSource('''
+//part of testB;
+main() {new ^ String x = "hello";}''');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
new file mode 100644
index 0000000..0ac517b
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
@@ -0,0 +1,182 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.services.completion.contributor.dart.named_constructor;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/named_constructor_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+main() {
+ initializeTestEnvironment();
+ defineReflectiveTests(NamedConstructorContributorTest);
+}
+
+@reflectiveTest
+class NamedConstructorContributorTest extends DartCompletionContributorTest {
+ CompletionSuggestion assertSuggestNamedConstructor(
+ String name, String returnType,
+ [int relevance = DART_RELEVANCE_DEFAULT,
+ CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
+ CompletionSuggestion cs =
+ assertSuggest(name, csKind: kind, relevance: relevance);
+ Element element = cs.element;
+ expect(element, isNotNull);
+ expect(element.kind, equals(ElementKind.CONSTRUCTOR));
+ expect(element.name, equals(name));
+ String param = element.parameters;
+ expect(param, isNotNull);
+ expect(param[0], equals('('));
+ expect(param[param.length - 1], equals(')'));
+ expect(element.returnType, equals(returnType));
+ assertHasParameterInfo(cs);
+ return cs;
+ }
+
+ @override
+ DartCompletionContributor createContributor() {
+ return new NamedConstructorContributor();
+ }
+
+ test_ConstructorName_importedClass() async {
+ // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName
+ // InstanceCreationExpression
+ Source libSource = addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ int T1;
+ F1() { }
+ class X {X.c(); X._d(); z() {}}''');
+ addTestSource('''
+ import "/testB.dart";
+ var m;
+ main() {new X.^}''');
+ // Assume that imported libraries are resolved
+ await resolveLibraryUnit(libSource);
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestNamedConstructor('c', 'X');
+ assertNotSuggested('F1');
+ assertNotSuggested('T1');
+ assertNotSuggested('_d');
+ assertNotSuggested('z');
+ assertNotSuggested('m');
+ }
+
+ test_ConstructorName_importedClass_unresolved() async {
+ // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName
+ // InstanceCreationExpression
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ int T1;
+ F1() { }
+ class X {X.c(); X._d(); z() {}}''');
+ addTestSource('''
+ import "/testB.dart";
+ var m;
+ main() {new X.^}''');
+ // Assume that imported libraries are NOT resolved
+ //await resolveLibraryUnit(libSource);
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestNamedConstructor('c', 'X');
+ assertNotSuggested('F1');
+ assertNotSuggested('T1');
+ assertNotSuggested('_d');
+ assertNotSuggested('z');
+ assertNotSuggested('m');
+ }
+
+ test_ConstructorName_importedFactory() async {
+ // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName
+ // InstanceCreationExpression
+ Source libSource = addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ int T1;
+ F1() { }
+ class X {factory X.c(); factory X._d(); z() {}}''');
+ addTestSource('''
+ import "/testB.dart";
+ var m;
+ main() {new X.^}''');
+ // Assume that imported libraries are resolved
+ await resolveLibraryUnit(libSource);
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestNamedConstructor('c', 'X');
+ assertNotSuggested('F1');
+ assertNotSuggested('T1');
+ assertNotSuggested('_d');
+ assertNotSuggested('z');
+ assertNotSuggested('m');
+ }
+
+ test_ConstructorName_importedFactory2() async {
+ // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName
+ // InstanceCreationExpression
+ addTestSource('''
+ main() {new String.fr^omCharCodes([]);}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 2);
+ expect(replacementLength, 13);
+ assertSuggestNamedConstructor('fromCharCodes', 'String');
+ assertNotSuggested('isEmpty');
+ assertNotSuggested('isNotEmpty');
+ assertNotSuggested('length');
+ assertNotSuggested('Object');
+ assertNotSuggested('String');
+ }
+
+ test_ConstructorName_localClass() async {
+ // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName
+ // InstanceCreationExpression
+ addTestSource('''
+ int T1;
+ F1() { }
+ class X {X.c(); X._d(); z() {}}
+ main() {new X.^}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestNamedConstructor('c', 'X');
+ assertSuggestNamedConstructor('_d', 'X');
+ assertNotSuggested('F1');
+ assertNotSuggested('T1');
+ assertNotSuggested('z');
+ assertNotSuggested('m');
+ }
+
+ test_ConstructorName_localFactory() async {
+ // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName
+ // InstanceCreationExpression
+ addTestSource('''
+ int T1;
+ F1() { }
+ class X {factory X.c(); factory X._d(); z() {}}
+ main() {new X.^}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestNamedConstructor('c', 'X');
+ assertSuggestNamedConstructor('_d', 'X');
+ assertNotSuggested('F1');
+ assertNotSuggested('T1');
+ assertNotSuggested('z');
+ assertNotSuggested('m');
+ }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
new file mode 100644
index 0000000..6efd8ab
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
@@ -0,0 +1,289 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.services.completion.dart.static_member;
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/static_member_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+ initializeTestEnvironment();
+ defineReflectiveTests(StaticMemberContributorTest);
+}
+
+@reflectiveTest
+class StaticMemberContributorTest extends DartCompletionContributorTest {
+ @override
+ DartCompletionContributor createContributor() {
+ return new StaticMemberContributor();
+ }
+
+ fail_enumConst_deprecated() async {
+ addTestSource('@deprecated enum E { one, two } main() {E.^}');
+ await computeSuggestions();
+ assertNotSuggested('E');
+ // TODO(danrubel) Investigate why enum suggestion is not marked
+ // as deprecated if enum ast element is deprecated
+ assertSuggestEnumConst('one', isDeprecated: true);
+ assertSuggestEnumConst('two', isDeprecated: true);
+ assertNotSuggested('index');
+ assertSuggestField('values', 'List<E>', isDeprecated: true);
+ }
+
+ test_PrefixedIdentifier_class_const() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ class I {
+ static const scI = 'boo';
+ X get f => new A();
+ get _g => new A();}
+ class B implements I {
+ static const int scB = 12;
+ var b; X _c;
+ X get d => new A();get _e => new A();
+ set s1(I x) {} set _s2(I x) {}
+ m(X x) {} I _n(X x) {}}
+ class X{}''');
+ addTestSource('''
+ import "/testB.dart";
+ class A extends B {
+ static const String scA = 'foo';
+ w() { }}
+ main() {A.^}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestField('scA', 'String');
+ assertNotSuggested('scB');
+ assertNotSuggested('scI');
+ assertNotSuggested('b');
+ assertNotSuggested('_c');
+ assertNotSuggested('d');
+ assertNotSuggested('_e');
+ assertNotSuggested('f');
+ assertNotSuggested('_g');
+ assertNotSuggested('s1');
+ assertNotSuggested('_s2');
+ assertNotSuggested('m');
+ assertNotSuggested('_n');
+ assertNotSuggested('a');
+ assertNotSuggested('A');
+ assertNotSuggested('X');
+ assertNotSuggested('w');
+ assertNotSuggested('Object');
+ assertNotSuggested('==');
+ }
+
+ test_enumConst() async {
+ addTestSource('enum E { one, two } main() {E.^}');
+ await computeSuggestions();
+ assertNotSuggested('E');
+ assertSuggestEnumConst('one');
+ assertSuggestEnumConst('two');
+ assertNotSuggested('index');
+ assertSuggestField('values', 'List<E>');
+ }
+
+ test_enumConst2() async {
+ addTestSource('enum E { one, two } main() {E.o^}');
+ await computeSuggestions();
+ assertNotSuggested('E');
+ assertSuggestEnumConst('one');
+ assertSuggestEnumConst('two');
+ assertNotSuggested('index');
+ assertSuggestField('values', 'List<E>');
+ }
+
+ test_enumConst3() async {
+ addTestSource('enum E { one, two } main() {E.^ int g;}');
+ await computeSuggestions();
+ assertNotSuggested('E');
+ assertSuggestEnumConst('one');
+ assertSuggestEnumConst('two');
+ assertNotSuggested('index');
+ assertSuggestField('values', 'List<E>');
+ }
+
+ test_enumConst_cascade1() async {
+ addTestSource('enum E { one, two } main() {E..^}');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_enumConst_cascade2() async {
+ addTestSource('enum E { one, two } main() {E.^.}');
+ await computeSuggestions();
+ assertNotSuggested('E');
+ assertSuggestEnumConst('one');
+ assertSuggestEnumConst('two');
+ assertNotSuggested('index');
+ assertSuggestField('values', 'List<E>');
+ }
+
+ test_enumConst_cascade3() async {
+ addTestSource('enum E { one, two } main() {E..o^}');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_enumConst_cascade4() async {
+ addTestSource('enum E { one, two } main() {E.^.o}');
+ await computeSuggestions();
+ assertNotSuggested('E');
+ assertSuggestEnumConst('one');
+ assertSuggestEnumConst('two');
+ assertNotSuggested('index');
+ assertSuggestField('values', 'List<E>');
+ }
+
+ test_keyword() async {
+ addTestSource('class C { static C get instance => null; } main() {C.in^}');
+ await computeSuggestions();
+ assertSuggestGetter('instance', 'C');
+ }
+
+ test_only_static() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('''
+class B {
+ static int b1;
+}
+class C extends B {
+ int f1;
+ static int f2;
+ m1() {}
+ static m2() {}
+}
+void main() {C.^}''');
+ await computeSuggestions();
+ assertNotSuggested('b1');
+ assertNotSuggested('f1');
+ assertSuggestField('f2', 'int');
+ assertNotSuggested('m1');
+ assertSuggestMethod('m2', 'C', null);
+ }
+
+ test_only_static2() async {
+ // SimpleIdentifier MethodInvocation ExpressionStatement
+ addTestSource('''
+class B {
+ static int b1;
+}
+class C extends B {
+ int f1;
+ static int f2;
+ m1() {}
+ static m2() {}
+}
+void main() {C.^ print("something");}''');
+ await computeSuggestions();
+ assertNotSuggested('b1');
+ assertNotSuggested('f1');
+ assertSuggestField('f2', 'int');
+ assertNotSuggested('m1');
+ assertSuggestMethod('m2', 'C', null);
+ }
+
+ test_only_static_cascade1() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('''
+class B {
+ static int b1;
+}
+class C extends B {
+ int f1;
+ static int f2;
+ m1() {}
+ static m2() {}
+}
+void main() {C..^}''');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_only_static_cascade2() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('''
+class B {
+ static int b1;
+}
+class C extends B {
+ int f1;
+ static int f2;
+ m1() {}
+ static m2() {}
+}
+void main() {C.^.}''');
+ await computeSuggestions();
+ assertNotSuggested('b1');
+ assertNotSuggested('f1');
+ assertSuggestField('f2', 'int');
+ assertNotSuggested('m1');
+ assertSuggestMethod('m2', 'C', null);
+ }
+
+ test_only_static_cascade3() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('''
+class B {
+ static int b1;
+}
+class C extends B {
+ int f1;
+ static int f2;
+ m1() {}
+ static m2() {}
+}
+void main() {C..m^()}''');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_only_static_cascade4() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('''
+class B {
+ static int b1;
+}
+class C extends B {
+ int f1;
+ static int f2;
+ m1() {}
+ static m2() {}
+}
+void main() {C.^.m()}''');
+ await computeSuggestions();
+ assertNotSuggested('b1');
+ assertNotSuggested('f1');
+ assertSuggestField('f2', 'int');
+ assertNotSuggested('m1');
+ assertSuggestMethod('m2', 'C', null);
+ }
+
+ test_only_static_cascade_prefixed1() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('''
+import "dart:async" as async;
+void main() {async.Future..w^()}''');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_only_static_cascade_prefixed2() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('''
+import "dart:async" as async;
+void main() {async.Future.^.w()}''');
+ await computeSuggestions();
+ assertSuggestMethod('wait', 'Future', 'Future<dynamic>');
+ }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/test_all.dart b/pkg/analysis_server/test/services/completion/dart/test_all.dart
index 6d5c836..a9dc275 100644
--- a/pkg/analysis_server/test/services/completion/dart/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/test_all.dart
@@ -7,12 +7,17 @@
import 'package:unittest/unittest.dart';
import '../../../utils.dart';
-import 'combinator_contributor_test.dart' as combinator_test;
import 'arglist_contributor_test.dart' as arglist_test;
+import 'combinator_contributor_test.dart' as combinator_test;
import 'common_usage_sorter_test.dart' as common_usage_test;
import 'field_formal_contributor_test.dart' as field_formal_contributor_test;
import 'inherited_contributor_test.dart' as inherited_contributor_test;
import 'keyword_contributor_test.dart' as keyword_test;
+import 'library_member_contributor_test.dart' as library_member_test;
+import 'library_prefix_contributor_test.dart' as library_prefix_test;
+import 'named_constructor_contributor_test.dart' as named_contributor_test;
+import 'static_member_contributor_test.dart' as static_contributor_test;
+import 'type_member_contributor_test.dart' as type_member_contributor_test;
import 'uri_contributor_test.dart' as uri_contributor_test;
/// Utility for manually running all tests.
@@ -25,6 +30,11 @@
field_formal_contributor_test.main();
inherited_contributor_test.main();
keyword_test.main();
+ library_member_test.main();
+ library_prefix_test.main();
+ named_contributor_test.main();
+ static_contributor_test.main();
+ type_member_contributor_test.main();
uri_contributor_test.main();
});
}
diff --git a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
new file mode 100644
index 0000000..8d176b8
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
@@ -0,0 +1,4157 @@
+// 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 test.services.completion.contributor.dart.type_member;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/type_member_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+ initializeTestEnvironment();
+ defineReflectiveTests(TypeMemberContributorTest);
+}
+
+@reflectiveTest
+class TypeMemberContributorTest extends DartCompletionContributorTest {
+ /**
+ * Check whether a declaration of the form [shadower] in a derived class
+ * shadows a declaration of the form [shadowee] in a base class, for the
+ * purposes of what is shown during completion. [shouldBeShadowed] indicates
+ * whether shadowing is expected.
+ */
+ Future check_shadowing(
+ String shadower, String shadowee, bool shouldBeShadowed) async {
+ addTestSource('''
+class Base {
+ $shadowee
+}
+class Derived extends Base {
+ $shadower
+}
+void f(Derived d) {
+ d.^
+}
+''');
+ await computeSuggestions();
+ List<CompletionSuggestion> suggestionsForX = suggestions
+ .where((CompletionSuggestion s) => s.completion == 'x')
+ .toList();
+ expect(suggestionsForX, hasLength(1));
+ if (shouldBeShadowed) {
+ expect(suggestionsForX[0].declaringType, 'Derived');
+ } else {
+ expect(suggestionsForX[0].declaringType, 'Base');
+ }
+ }
+
+ fail_test_PrefixedIdentifier_trailingStmt_const_untyped() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('const g = "hello"; f() {g.^ int y = 0;}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ @override
+ DartCompletionContributor createContributor() {
+ return new TypeMemberContributor();
+ }
+
+ test_enumConst() async {
+ addTestSource('enum E { one, two } main() {E.^}');
+ await computeSuggestions();
+ assertNotSuggested('E');
+ // Suggested by StaticMemberContributor
+ assertNotSuggested('one');
+ assertNotSuggested('two');
+ assertNotSuggested('index');
+ assertNotSuggested('values');
+ }
+
+ test_enumConst2() async {
+ addTestSource('enum E { one, two } main() {E.o^}');
+ await computeSuggestions();
+ assertNotSuggested('E');
+ // Suggested by StaticMemberContributor
+ assertNotSuggested('one');
+ assertNotSuggested('two');
+ assertNotSuggested('index');
+ assertNotSuggested('values');
+ }
+
+ test_enumConst3() async {
+ addTestSource('enum E { one, two } main() {E.^ int g;}');
+ await computeSuggestions();
+ assertNotSuggested('E');
+ // Suggested by StaticMemberContributor
+ assertNotSuggested('one');
+ assertNotSuggested('two');
+ assertNotSuggested('index');
+ assertNotSuggested('values');
+ }
+
+ test_enumConst_index() async {
+ addTestSource('enum E { one, two } main() {E.one.^}');
+ await computeSuggestions();
+ assertNotSuggested('E');
+ assertNotSuggested('one');
+ assertNotSuggested('two');
+ assertSuggestField('index', 'int');
+ assertNotSuggested('values');
+ }
+
+ test_enumConst_index2() async {
+ addTestSource('enum E { one, two } main() {E.one.i^}');
+ await computeSuggestions();
+ assertNotSuggested('E');
+ assertNotSuggested('one');
+ assertNotSuggested('two');
+ assertSuggestField('index', 'int');
+ assertNotSuggested('values');
+ }
+
+ test_enumConst_index3() async {
+ addTestSource('enum E { one, two } main() {E.one.^ int g;}');
+ await computeSuggestions();
+ assertNotSuggested('E');
+ assertNotSuggested('one');
+ assertNotSuggested('two');
+ assertSuggestField('index', 'int');
+ assertNotSuggested('values');
+ }
+
+ test_generic_field() async {
+ addTestSource('''
+class C<T> {
+ T t;
+}
+void f(C<int> c) {
+ c.^
+}
+''');
+ await computeSuggestions();
+ assertSuggestField('t', 'int');
+ }
+
+ test_generic_getter() async {
+ addTestSource('''
+class C<T> {
+ T get t => null;
+}
+void f(C<int> c) {
+ c.^
+}
+''');
+ await computeSuggestions();
+ assertSuggestGetter('t', 'int');
+ }
+
+ test_generic_method() async {
+ addTestSource('''
+class C<T> {
+ T m(T t) {}
+}
+void f(C<int> c) {
+ c.^
+}
+''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'int');
+ expect(suggestion.parameterTypes[0], 'int');
+ expect(suggestion.element.returnType, 'int');
+ expect(suggestion.element.parameters, '(int t)');
+ }
+
+ test_generic_setter() async {
+ addTestSource('''
+class C<T> {
+ set t(T value) {}
+}
+void f(C<int> c) {
+ c.^
+}
+''');
+ await computeSuggestions();
+ // TODO(paulberry): modify assertSuggestSetter so that we can pass 'int'
+ // as a parmeter to it, and it will check the appropriate field in
+ // the suggestion object.
+ CompletionSuggestion suggestion = assertSuggestSetter('t');
+ expect(suggestion.element.parameters, '(int value)');
+ }
+
+ test_keyword() async {
+ addTestSource('class C { static C get instance => null; } main() {C.in^}');
+ await computeSuggestions();
+ // Suggested by StaticMemberContributor
+ assertNotSuggested('instance');
+ }
+
+ test_libraryPrefix() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('import "dart:async" as bar; foo() {bar.^}');
+ await computeSuggestions();
+ // Suggested by LibraryMemberContributor
+ assertNotSuggested('Future');
+ assertNotSuggested('loadLibrary');
+ }
+
+ test_libraryPrefix2() async {
+ // SimpleIdentifier MethodInvocation ExpressionStatement
+ addTestSource('import "dart:async" as bar; foo() {bar.^ print("f")}');
+ await computeSuggestions();
+ // Suggested by LibraryMemberContributor
+ assertNotSuggested('Future');
+ }
+
+ test_libraryPrefix3() async {
+ // SimpleIdentifier MethodInvocation ExpressionStatement
+ addTestSource('import "dart:async" as bar; foo() {new bar.F^ print("f")}');
+ await computeSuggestions();
+ // Suggested by LibraryMemberContributor
+ assertNotSuggested('Future');
+ assertNotSuggested('Future.delayed');
+ }
+
+ test_libraryPrefix_deferred() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('import "dart:async" deferred as bar; foo() {bar.^}');
+ await computeSuggestions();
+ // Suggested by LibraryMemberContributor
+ assertNotSuggested('Future');
+ assertNotSuggested('loadLibrary');
+ }
+
+ test_libraryPrefix_with_exports() async {
+ addSource('/libA.dart', 'library libA; class A { }');
+ addSource('/libB.dart', 'library libB; export "/libA.dart"; class B { }');
+ addTestSource('import "/libB.dart" as foo; main() {foo.^} class C { }');
+ await computeSuggestions();
+ // Suggested by LibraryMemberContributor
+ assertNotSuggested('B');
+ assertNotSuggested('A');
+ }
+
+ test_local() async {
+ addTestSource('foo() {String x = "bar"; x.^}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_local_is() async {
+ addTestSource('foo() {var x; if (x is String) x.^}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_local_propogatedType() async {
+ addTestSource('foo() {var x = "bar"; x.^}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_method_parameters_mixed_required_and_named() async {
+ addTestSource('''
+class C {
+ void m(x, {int y}) {}
+}
+void main() {new C().^}''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'x');
+ expect(suggestion.parameterTypes[0], 'dynamic');
+ expect(suggestion.parameterNames[1], 'y');
+ expect(suggestion.parameterTypes[1], 'int');
+ expect(suggestion.requiredParameterCount, 1);
+ expect(suggestion.hasNamedParameters, true);
+ }
+
+ test_method_parameters_mixed_required_and_positional() async {
+ addTestSource('''
+class C {
+ void m(x, [int y]) {}
+}
+void main() {new C().^}''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'x');
+ expect(suggestion.parameterTypes[0], 'dynamic');
+ expect(suggestion.parameterNames[1], 'y');
+ expect(suggestion.parameterTypes[1], 'int');
+ expect(suggestion.requiredParameterCount, 1);
+ expect(suggestion.hasNamedParameters, false);
+ }
+
+ test_method_parameters_named() async {
+ addTestSource('''
+class C {
+ void m({x, int y}) {}
+}
+void main() {new C().^}''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'x');
+ expect(suggestion.parameterTypes[0], 'dynamic');
+ expect(suggestion.parameterNames[1], 'y');
+ expect(suggestion.parameterTypes[1], 'int');
+ expect(suggestion.requiredParameterCount, 0);
+ expect(suggestion.hasNamedParameters, true);
+ }
+
+ test_method_parameters_none() async {
+ addTestSource('''
+class C {
+ void m() {}
+}
+void main() {new C().^}''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+ expect(suggestion.parameterNames, isEmpty);
+ expect(suggestion.parameterTypes, isEmpty);
+ expect(suggestion.requiredParameterCount, 0);
+ expect(suggestion.hasNamedParameters, false);
+ }
+
+ test_method_parameters_positional() async {
+ addTestSource('''
+class C {
+ void m([x, int y]) {}
+}
+void main() {new C().^}''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'x');
+ expect(suggestion.parameterTypes[0], 'dynamic');
+ expect(suggestion.parameterNames[1], 'y');
+ expect(suggestion.parameterTypes[1], 'int');
+ expect(suggestion.requiredParameterCount, 0);
+ expect(suggestion.hasNamedParameters, false);
+ }
+
+ test_method_parameters_required() async {
+ addTestSource('''
+class C {
+ void m(x, int y) {}
+}
+void main() {new C().^}''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'x');
+ expect(suggestion.parameterTypes[0], 'dynamic');
+ expect(suggestion.parameterNames[1], 'y');
+ expect(suggestion.parameterTypes[1], 'int');
+ expect(suggestion.requiredParameterCount, 2);
+ expect(suggestion.hasNamedParameters, false);
+ }
+
+ test_no_parameters_field() async {
+ addTestSource('''
+class C {
+ int x;
+}
+void main() {new C().^}''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestField('x', 'int');
+ assertHasNoParameterInfo(suggestion);
+ }
+
+ test_no_parameters_getter() async {
+ addTestSource('''
+class C {
+ int get x => null;
+}
+void main() {int y = new C().^}''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestGetter('x', 'int');
+ assertHasNoParameterInfo(suggestion);
+ }
+
+ test_no_parameters_setter() async {
+ addTestSource('''
+class C {
+ set x(int value) {};
+}
+void main() {int y = new C().^}''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestSetter('x');
+ assertHasNoParameterInfo(suggestion);
+ }
+
+ test_only_instance() async {
+ // SimpleIdentifier PropertyAccess ExpressionStatement
+ addTestSource('''
+class C {
+ int f1;
+ static int f2;
+ m1() {}
+ static m2() {}
+}
+void main() {new C().^}''');
+ await computeSuggestions();
+ assertSuggestField('f1', 'int');
+ assertNotSuggested('f2');
+ assertSuggestMethod('m1', 'C', null);
+ assertNotSuggested('m2');
+ }
+
+ test_only_instance2() async {
+ // SimpleIdentifier MethodInvocation ExpressionStatement
+ addTestSource('''
+class C {
+ int f1;
+ static int f2;
+ m1() {}
+ static m2() {}
+}
+void main() {new C().^ print("something");}''');
+ await computeSuggestions();
+ assertSuggestField('f1', 'int');
+ assertNotSuggested('f2');
+ assertSuggestMethod('m1', 'C', null);
+ assertNotSuggested('m2');
+ }
+
+ test_only_static() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('''
+class C {
+ int f1;
+ static int f2;
+ m1() {}
+ static m2() {}
+}
+void main() {C.^}''');
+ await computeSuggestions();
+ assertNotSuggested('f1');
+ // Suggested by StaticMemberContributor
+ assertNotSuggested('f2');
+ assertNotSuggested('m1');
+ assertNotSuggested('m2');
+ }
+
+ test_only_static2() async {
+ // SimpleIdentifier MethodInvocation ExpressionStatement
+ addTestSource('''
+class C {
+ int f1;
+ static int f2;
+ m1() {}
+ static m2() {}
+}
+void main() {C.^ print("something");}''');
+ await computeSuggestions();
+ assertNotSuggested('f1');
+ // Suggested by StaticMemberContributor
+ assertNotSuggested('f2');
+ assertNotSuggested('m1');
+ assertNotSuggested('m2');
+ }
+
+ test_param() async {
+ addTestSource('foo(String x) {x.^}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_param_is() async {
+ addTestSource('foo(x) {if (x is String) x.^}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_shadowing_field_over_field() =>
+ check_shadowing('int x;', 'int x;', true);
+
+ test_shadowing_field_over_getter() =>
+ check_shadowing('int x;', 'int get x => null;', true);
+
+ test_shadowing_field_over_method() =>
+ check_shadowing('int x;', 'void x() {}', true);
+
+ test_shadowing_field_over_setter() =>
+ check_shadowing('int x;', 'set x(int value) {}', true);
+
+ test_shadowing_getter_over_field() =>
+ check_shadowing('int get x => null;', 'int x;', false);
+
+ test_shadowing_getter_over_getter() =>
+ check_shadowing('int get x => null;', 'int get x => null;', true);
+
+ test_shadowing_getter_over_method() =>
+ check_shadowing('int get x => null;', 'void x() {}', true);
+
+ test_shadowing_getter_over_setter() =>
+ check_shadowing('int get x => null;', 'set x(int value) {}', false);
+
+ test_shadowing_method_over_field() =>
+ check_shadowing('void x() {}', 'int x;', true);
+
+ test_shadowing_method_over_getter() =>
+ check_shadowing('void x() {}', 'int get x => null;', true);
+
+ test_shadowing_method_over_method() =>
+ check_shadowing('void x() {}', 'void x() {}', true);
+
+ test_shadowing_method_over_setter() =>
+ check_shadowing('void x() {}', 'set x(int value) {}', true);
+
+ test_shadowing_mixin_order() async {
+ addTestSource('''
+class Base {
+}
+class Mixin1 {
+ void f() {}
+}
+class Mixin2 {
+ void f() {}
+}
+class Derived extends Base with Mixin1, Mixin2 {
+}
+void test(Derived d) {
+ d.^
+}
+''');
+ await computeSuggestions();
+ // Note: due to dartbug.com/22069, analyzer currently analyzes mixins in
+ // reverse order. The correct order is that Derived inherits from
+ // "Base with Mixin1, Mixin2", which inherits from "Base with Mixin1",
+ // which inherits from "Base". So the definition of f in Mixin2 should
+ // shadow the definition in Mixin1.
+ assertSuggestMethod('f', 'Mixin2', 'void');
+ }
+
+ test_shadowing_mixin_over_superclass() async {
+ addTestSource('''
+class Base {
+ void f() {}
+}
+class Mixin {
+ void f() {}
+}
+class Derived extends Base with Mixin {
+}
+void test(Derived d) {
+ d.^
+}
+''');
+ await computeSuggestions();
+ assertSuggestMethod('f', 'Mixin', 'void');
+ }
+
+ test_shadowing_setter_over_field() =>
+ check_shadowing('set x(int value) {}', 'int x;', false);
+
+ test_shadowing_setter_over_getter() =>
+ check_shadowing('set x(int value) {}', 'int get x => null;', false);
+
+ test_shadowing_setter_over_method() =>
+ check_shadowing('set x(int value) {}', 'void x() {}', true);
+
+ test_shadowing_setter_over_setter() =>
+ check_shadowing('set x(int value) {}', 'set x(int value) {}', true);
+
+ test_shadowing_superclass_over_interface() async {
+ addTestSource('''
+class Base {
+ void f() {}
+}
+class Interface {
+ void f() {}
+}
+class Derived extends Base implements Interface {
+}
+void test(Derived d) {
+ d.^
+}
+''');
+ await computeSuggestions();
+ assertSuggestMethod('f', 'Base', 'void');
+ }
+
+ test_super() async {
+ // SimpleIdentifier MethodInvocation ExpressionStatement
+ addTestSource('''
+class C3 {
+ int fi3;
+ static int fs3;
+ m() {}
+ mi3() {}
+ static ms3() {}
+}
+class C2 {
+ int fi2;
+ static int fs2;
+ m() {}
+ mi2() {}
+ static ms2() {}
+}
+class C1 extends C2 implements C3 {
+ int fi1;
+ static int fs1;
+ m() {super.^}
+ mi1() {}
+ static ms1() {}
+}''');
+ await computeSuggestions();
+ assertNotSuggested('fi1');
+ assertNotSuggested('fs1');
+ assertNotSuggested('mi1');
+ assertNotSuggested('ms1');
+ assertSuggestField('fi2', 'int');
+ assertNotSuggested('fs2');
+ assertSuggestMethod('mi2', 'C2', null);
+ assertNotSuggested('ms2');
+ assertSuggestMethod('m', 'C2', null, relevance: DART_RELEVANCE_HIGH);
+ assertNotSuggested('fi3');
+ assertNotSuggested('fs3');
+ assertNotSuggested('mi3');
+ assertNotSuggested('ms3');
+ }
+
+ test_ArgumentList() async {
+ // ArgumentList MethodInvocation ExpressionStatement Block
+ addSource(
+ '/libA.dart',
+ '''
+ library A;
+ bool hasLength(int expected) { }
+ void baz() { }''');
+ addTestSource('''
+ import '/libA.dart';
+ class B { }
+ String bar() => true;
+ void main() {expect(^)}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+ assertNotSuggested('bar');
+ assertNotSuggested('hasLength');
+ assertNotSuggested('identical');
+ assertNotSuggested('B');
+ assertNotSuggested('Object');
+ assertNotSuggested('main');
+ assertNotSuggested('baz');
+ assertNotSuggested('print');
+ }
+
+ test_ArgumentList_imported_function() async {
+ // ArgumentList MethodInvocation ExpressionStatement Block
+ addSource(
+ '/libA.dart',
+ '''
+ library A;
+ bool hasLength(int expected) { }
+ expect(arg) { }
+ void baz() { }''');
+ addTestSource('''
+ import '/libA.dart'
+ class B { }
+ String bar() => true;
+ void main() {expect(^)}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+ assertNotSuggested('bar');
+ assertNotSuggested('hasLength');
+ assertNotSuggested('identical');
+ assertNotSuggested('B');
+ assertNotSuggested('Object');
+ assertNotSuggested('main');
+ assertNotSuggested('baz');
+ assertNotSuggested('print');
+ }
+
+ test_ArgumentList_InstanceCreationExpression_functionalArg() async {
+ // ArgumentList InstanceCreationExpression ExpressionStatement Block
+ addSource(
+ '/libA.dart',
+ '''
+ library A;
+ class A { A(f()) { } }
+ bool hasLength(int expected) { }
+ void baz() { }''');
+ addTestSource('''
+ import 'dart:async';
+ import '/libA.dart';
+ class B { }
+ String bar() => true;
+ void main() {new A(^)}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+ assertNotSuggested('bar');
+ assertNotSuggested('hasLength');
+ assertNotSuggested('identical');
+ assertNotSuggested('B');
+ assertNotSuggested('A');
+ assertNotSuggested('Object');
+ assertNotSuggested('main');
+ assertNotSuggested('baz');
+ assertNotSuggested('print');
+ }
+
+ test_ArgumentList_InstanceCreationExpression_typedefArg() async {
+ // ArgumentList InstanceCreationExpression ExpressionStatement Block
+ addSource(
+ '/libA.dart',
+ '''
+ library A;
+ typedef Funct();
+ class A { A(Funct f) { } }
+ bool hasLength(int expected) { }
+ void baz() { }''');
+ addTestSource('''
+ import 'dart:async';
+ import '/libA.dart';
+ class B { }
+ String bar() => true;
+ void main() {new A(^)}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+ assertNotSuggested('bar');
+ assertNotSuggested('hasLength');
+ assertNotSuggested('identical');
+ assertNotSuggested('B');
+ assertNotSuggested('A');
+ assertNotSuggested('Object');
+ assertNotSuggested('main');
+ assertNotSuggested('baz');
+ assertNotSuggested('print');
+ }
+
+ test_ArgumentList_local_function() async {
+ // ArgumentList MethodInvocation ExpressionStatement Block
+ addSource(
+ '/libA.dart',
+ '''
+ library A;
+ bool hasLength(int expected) { }
+ void baz() { }''');
+ addTestSource('''
+ import '/libA.dart'
+ expect(arg) { }
+ class B { }
+ String bar() => true;
+ void main() {expect(^)}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+ assertNotSuggested('bar');
+ assertNotSuggested('hasLength');
+ assertNotSuggested('identical');
+ assertNotSuggested('B');
+ assertNotSuggested('Object');
+ assertNotSuggested('main');
+ assertNotSuggested('baz');
+ assertNotSuggested('print');
+ }
+
+ test_ArgumentList_local_method() async {
+ // ArgumentList MethodInvocation ExpressionStatement Block
+ addSource(
+ '/libA.dart',
+ '''
+ library A;
+ bool hasLength(int expected) { }
+ void baz() { }''');
+ addTestSource('''
+ import '/libA.dart'
+ class B {
+ expect(arg) { }
+ void foo() {expect(^)}}
+ String bar() => true;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+ assertNotSuggested('bar');
+ assertNotSuggested('hasLength');
+ assertNotSuggested('identical');
+ assertNotSuggested('B');
+ assertNotSuggested('Object');
+ assertNotSuggested('main');
+ assertNotSuggested('baz');
+ assertNotSuggested('print');
+ }
+
+ test_ArgumentList_MethodInvocation_functionalArg() async {
+ // ArgumentList MethodInvocation ExpressionStatement Block
+ addSource(
+ '/libA.dart',
+ '''
+ library A;
+ class A { A(f()) { } }
+ bool hasLength(int expected) { }
+ void baz() { }''');
+ addTestSource('''
+ import 'dart:async';
+ import '/libA.dart';
+ class B { }
+ String bar(f()) => true;
+ void main() {bar(^);}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+ assertNotSuggested('bar');
+ assertNotSuggested('hasLength');
+ assertNotSuggested('identical');
+ assertNotSuggested('B');
+ assertNotSuggested('A');
+ assertNotSuggested('Object');
+ assertNotSuggested('main');
+ assertNotSuggested('baz');
+ assertNotSuggested('print');
+ }
+
+ test_ArgumentList_MethodInvocation_methodArg() async {
+ // ArgumentList MethodInvocation ExpressionStatement Block
+ addSource(
+ '/libA.dart',
+ '''
+ library A;
+ class A { A(f()) { } }
+ bool hasLength(int expected) { }
+ void baz() { }''');
+ addTestSource('''
+ import 'dart:async';
+ import '/libA.dart';
+ class B { String bar(f()) => true; }
+ void main() {new B().bar(^);}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+ assertNotSuggested('hasLength');
+ assertNotSuggested('identical');
+ assertNotSuggested('B');
+ assertNotSuggested('A');
+ assertNotSuggested('Object');
+ assertNotSuggested('main');
+ assertNotSuggested('baz');
+ assertNotSuggested('print');
+ }
+
+ test_ArgumentList_namedParam() async {
+ // SimpleIdentifier NamedExpression ArgumentList MethodInvocation
+ // ExpressionStatement
+ addSource(
+ '/libA.dart',
+ '''
+ library A;
+ bool hasLength(int expected) { }''');
+ addTestSource('''
+ import '/libA.dart'
+ String bar() => true;
+ void main() {expect(foo: ^)}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('bar');
+ assertNotSuggested('hasLength');
+ assertNotSuggested('main');
+ }
+
+ test_AsExpression() async {
+ // SimpleIdentifier TypeName AsExpression
+ addTestSource('''
+ class A {var b; X _c; foo() {var a; (a as ^).foo();}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('b');
+ assertNotSuggested('_c');
+ assertNotSuggested('Object');
+ assertNotSuggested('A');
+ assertNotSuggested('==');
+ }
+
+ test_AssignmentExpression_name() async {
+ // SimpleIdentifier VariableDeclaration VariableDeclarationList
+ // VariableDeclarationStatement Block
+ addTestSource('class A {} main() {int a; int ^b = 1;}');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_AssignmentExpression_RHS() async {
+ // SimpleIdentifier VariableDeclaration VariableDeclarationList
+ // VariableDeclarationStatement Block
+ addTestSource('class A {} main() {int a; int b = ^}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('a');
+ assertNotSuggested('main');
+ assertNotSuggested('A');
+ assertNotSuggested('Object');
+ }
+
+ test_AssignmentExpression_type() async {
+ // SimpleIdentifier TypeName VariableDeclarationList
+ // VariableDeclarationStatement Block
+ addTestSource('''
+ class A {} main() {
+ int a;
+ ^ b = 1;}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('A');
+ assertNotSuggested('int');
+ // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+ // the user may be either (1) entering a type for the assignment
+ // or (2) starting a new statement.
+ // Consider suggesting only types
+ // if only spaces separates the 1st and 2nd identifiers.
+ //assertNotSuggested('a');
+ //assertNotSuggested('main');
+ //assertNotSuggested('identical');
+ }
+
+ test_AssignmentExpression_type_newline() async {
+ // SimpleIdentifier TypeName VariableDeclarationList
+ // VariableDeclarationStatement Block
+ addTestSource('''
+ class A {} main() {
+ int a;
+ ^
+ b = 1;}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('A');
+ assertNotSuggested('int');
+ // Allow non-types preceding an identifier on LHS of assignment
+ // if newline follows first identifier
+ // because user is probably starting a new statement
+ assertNotSuggested('a');
+ assertNotSuggested('main');
+ assertNotSuggested('identical');
+ }
+
+ test_AssignmentExpression_type_partial() async {
+ // SimpleIdentifier TypeName VariableDeclarationList
+ // VariableDeclarationStatement Block
+ addTestSource('''
+ class A {} main() {
+ int a;
+ int^ b = 1;}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 3);
+ expect(replacementLength, 3);
+ assertNotSuggested('A');
+ assertNotSuggested('int');
+ // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+ // the user may be either (1) entering a type for the assignment
+ // or (2) starting a new statement.
+ // Consider suggesting only types
+ // if only spaces separates the 1st and 2nd identifiers.
+ //assertNotSuggested('a');
+ //assertNotSuggested('main');
+ //assertNotSuggested('identical');
+ }
+
+ test_AssignmentExpression_type_partial_newline() async {
+ // SimpleIdentifier TypeName VariableDeclarationList
+ // VariableDeclarationStatement Block
+ addTestSource('''
+ class A {} main() {
+ int a;
+ i^
+ b = 1;}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+ assertNotSuggested('A');
+ assertNotSuggested('int');
+ // Allow non-types preceding an identifier on LHS of assignment
+ // if newline follows first identifier
+ // because user is probably starting a new statement
+ assertNotSuggested('a');
+ assertNotSuggested('main');
+ assertNotSuggested('identical');
+ }
+
+ test_AwaitExpression() async {
+ // SimpleIdentifier AwaitExpression ExpressionStatement
+ addTestSource('''
+ class A {int x; int y() => 0;}
+ main() async {A a; await ^}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('a');
+ assertNotSuggested('main');
+ assertNotSuggested('A');
+ assertNotSuggested('Object');
+ }
+
+ test_BinaryExpression_LHS() async {
+ // SimpleIdentifier BinaryExpression VariableDeclaration
+ // VariableDeclarationList VariableDeclarationStatement
+ addTestSource('main() {int a = 1, b = ^ + 2;}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('a');
+ assertNotSuggested('Object');
+ assertNotSuggested('b');
+ }
+
+ test_BinaryExpression_RHS() async {
+ // SimpleIdentifier BinaryExpression VariableDeclaration
+ // VariableDeclarationList VariableDeclarationStatement
+ addTestSource('main() {int a = 1, b = 2 + ^;}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('a');
+ assertNotSuggested('Object');
+ assertNotSuggested('b');
+ assertNotSuggested('==');
+ }
+
+ test_Block() async {
+ // Block BlockFunctionBody MethodDeclaration
+ addSource(
+ '/testAB.dart',
+ '''
+ export "dart:math" hide max;
+ class A {int x;}
+ @deprecated D1() {int x;}
+ class _B {boo() { partBoo() {}} }''');
+ addSource(
+ '/testCD.dart',
+ '''
+ String T1;
+ var _T2;
+ class C { }
+ class D { }''');
+ addSource(
+ '/testEEF.dart',
+ '''
+ class EE { }
+ class F { }''');
+ addSource('/testG.dart', 'class G { }');
+ addSource(
+ '/testH.dart',
+ '''
+ class H { }
+ int T3;
+ var _T4;'''); // not imported
+ addTestSource('''
+ import "/testAB.dart";
+ import "/testCD.dart" hide D;
+ import "/testEEF.dart" show EE;
+ import "/testG.dart" as g;
+ int T5;
+ var _T6;
+ String get T7 => 'hello';
+ set T8(int value) { partT8() {} }
+ Z D2() {int x;}
+ class X {
+ int get clog => 8;
+ set blog(value) { }
+ a() {
+ var f;
+ localF(int arg1) { }
+ {var x;}
+ ^ var r;
+ }
+ void b() { }}
+ class Z { }''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+
+ assertNotSuggested('X');
+ assertNotSuggested('Z');
+ assertNotSuggested('a');
+ assertNotSuggested('b');
+ assertNotSuggested('localF');
+ assertNotSuggested('f');
+ // Don't suggest locals out of scope
+ assertNotSuggested('r');
+ assertNotSuggested('x');
+ assertNotSuggested('partT8');
+
+ assertNotSuggested('A');
+ assertNotSuggested('_B');
+ assertNotSuggested('C');
+ assertNotSuggested('partBoo');
+ // hidden element suggested as low relevance
+ // but imported results are partially filtered
+ //assertNotSuggested('D');
+ //assertNotSuggested(
+ // 'D1', null, true, COMPLETION_RELEVANCE_LOW);
+ assertNotSuggested('D2');
+ assertNotSuggested('EE');
+ // hidden element suggested as low relevance
+ //assertNotSuggested('F');
+ assertNotSuggested('g');
+ assertNotSuggested('G');
+ //assertNotSuggested('H');
+ assertNotSuggested('Object');
+ assertNotSuggested('min');
+ assertNotSuggested('_T2');
+ //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+ assertNotSuggested('_T4');
+ assertNotSuggested('T5');
+ assertNotSuggested('_T6');
+ assertNotSuggested('==');
+ assertNotSuggested('T7');
+ assertNotSuggested('T8');
+ assertNotSuggested('clog');
+ assertNotSuggested('blog');
+ // TODO (danrubel) suggest HtmlElement as low relevance
+ assertNotSuggested('HtmlElement');
+ assertNotSuggested('Uri');
+ assertNotSuggested('parseIPv6Address');
+ assertNotSuggested('parseHex');
+ }
+
+ test_Block_final() async {
+ // Block BlockFunctionBody MethodDeclaration
+ addSource(
+ '/testAB.dart',
+ '''
+ export "dart:math" hide max;
+ class A {int x;}
+ @deprecated D1() {int x;}
+ class _B {boo() { partBoo() {}} }''');
+ addSource(
+ '/testCD.dart',
+ '''
+ String T1;
+ var _T2;
+ class C { }
+ class D { }''');
+ addSource(
+ '/testEEF.dart',
+ '''
+ class EE { }
+ class F { }''');
+ addSource('/testG.dart', 'class G { }');
+ addSource(
+ '/testH.dart',
+ '''
+ class H { }
+ int T3;
+ var _T4;'''); // not imported
+ addTestSource('''
+ import "/testAB.dart";
+ import "/testCD.dart" hide D;
+ import "/testEEF.dart" show EE;
+ import "/testG.dart" as g;
+ int T5;
+ var _T6;
+ String get T7 => 'hello';
+ set T8(int value) { partT8() {} }
+ Z D2() {int x;}
+ class X {
+ int get clog => 8;
+ set blog(value) { }
+ a() {
+ var f;
+ localF(int arg1) { }
+ {var x;}
+ final ^
+ }
+ void b() { }}
+ class Z { }''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+
+ assertNotSuggested('X');
+ assertNotSuggested('Z');
+ assertNotSuggested('a');
+ assertNotSuggested('b');
+ assertNotSuggested('localF');
+ assertNotSuggested('f');
+ // Don't suggest locals out of scope
+ assertNotSuggested('r');
+ assertNotSuggested('x');
+ assertNotSuggested('partT8');
+
+ assertNotSuggested('A');
+ assertNotSuggested('_B');
+ assertNotSuggested('C');
+ assertNotSuggested('partBoo');
+ // hidden element suggested as low relevance
+ // but imported results are partially filtered
+ //assertNotSuggested('D');
+ //assertNotSuggested(
+ // 'D1', null, true, COMPLETION_RELEVANCE_LOW);
+ assertNotSuggested('D2');
+ assertNotSuggested('EE');
+ // hidden element suggested as low relevance
+ //assertNotSuggested('F');
+ assertNotSuggested('g');
+ assertNotSuggested('G');
+ //assertNotSuggested('H');
+ assertNotSuggested('Object');
+ assertNotSuggested('min');
+ //assertNotSuggested(
+ // 'max',
+ // 'num',
+ // false,
+ // COMPLETION_RELEVANCE_LOW);
+ assertNotSuggested('T1');
+ assertNotSuggested('_T2');
+ //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+ assertNotSuggested('_T4');
+ assertNotSuggested('T5');
+ assertNotSuggested('_T6');
+ assertNotSuggested('==');
+ assertNotSuggested('T7');
+ assertNotSuggested('T8');
+ assertNotSuggested('clog');
+ assertNotSuggested('blog');
+ // TODO (danrubel) suggest HtmlElement as low relevance
+ assertNotSuggested('HtmlElement');
+ assertNotSuggested('Uri');
+ assertNotSuggested('parseIPv6Address');
+ assertNotSuggested('parseHex');
+ }
+
+ test_Block_final2() async {
+ addTestSource('main() {final S^ v;}');
+ await computeSuggestions();
+
+ assertNotSuggested('String');
+ }
+
+ test_Block_final3() async {
+ addTestSource('main() {final ^ v;}');
+ await computeSuggestions();
+
+ assertNotSuggested('String');
+ }
+
+ test_Block_final_final() async {
+ // Block BlockFunctionBody MethodDeclaration
+ addSource(
+ '/testAB.dart',
+ '''
+ export "dart:math" hide max;
+ class A {int x;}
+ @deprecated D1() {int x;}
+ class _B {boo() { partBoo() {}} }''');
+ addSource(
+ '/testCD.dart',
+ '''
+ String T1;
+ var _T2;
+ class C { }
+ class D { }''');
+ addSource(
+ '/testEEF.dart',
+ '''
+ class EE { }
+ class F { }''');
+ addSource('/testG.dart', 'class G { }');
+ addSource(
+ '/testH.dart',
+ '''
+ class H { }
+ int T3;
+ var _T4;'''); // not imported
+ addTestSource('''
+ import "/testAB.dart";
+ import "/testCD.dart" hide D;
+ import "/testEEF.dart" show EE;
+ import "/testG.dart" as g;
+ int T5;
+ var _T6;
+ String get T7 => 'hello';
+ set T8(int value) { partT8() {} }
+ Z D2() {int x;}
+ class X {
+ int get clog => 8;
+ set blog(value) { }
+ a() {
+ final ^
+ final var f;
+ localF(int arg1) { }
+ {var x;}
+ }
+ void b() { }}
+ class Z { }''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+
+ assertNotSuggested('X');
+ assertNotSuggested('Z');
+ assertNotSuggested('a');
+ assertNotSuggested('b');
+ assertNotSuggested('localF');
+ assertNotSuggested('f');
+ // Don't suggest locals out of scope
+ assertNotSuggested('r');
+ assertNotSuggested('x');
+ assertNotSuggested('partT8');
+
+ assertNotSuggested('A');
+ assertNotSuggested('_B');
+ assertNotSuggested('C');
+ assertNotSuggested('partBoo');
+ // hidden element suggested as low relevance
+ // but imported results are partially filtered
+ //assertNotSuggested('D');
+ //assertNotSuggested(
+ // 'D1', null, true, COMPLETION_RELEVANCE_LOW);
+ assertNotSuggested('D2');
+ assertNotSuggested('EE');
+ // hidden element suggested as low relevance
+ //assertNotSuggested('F');
+ assertNotSuggested('g');
+ assertNotSuggested('G');
+ //assertNotSuggested('H');
+ assertNotSuggested('Object');
+ assertNotSuggested('min');
+ //assertNotSuggested(
+ // 'max',
+ // 'num',
+ // false,
+ // COMPLETION_RELEVANCE_LOW);
+ assertNotSuggested('T1');
+ assertNotSuggested('_T2');
+ //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+ assertNotSuggested('_T4');
+ assertNotSuggested('T5');
+ assertNotSuggested('_T6');
+ assertNotSuggested('==');
+ assertNotSuggested('T7');
+ assertNotSuggested('T8');
+ assertNotSuggested('clog');
+ assertNotSuggested('blog');
+ // TODO (danrubel) suggest HtmlElement as low relevance
+ assertNotSuggested('HtmlElement');
+ assertNotSuggested('Uri');
+ assertNotSuggested('parseIPv6Address');
+ assertNotSuggested('parseHex');
+ }
+
+ test_Block_final_var() async {
+ // Block BlockFunctionBody MethodDeclaration
+ addSource(
+ '/testAB.dart',
+ '''
+ export "dart:math" hide max;
+ class A {int x;}
+ @deprecated D1() {int x;}
+ class _B {boo() { partBoo() {}} }''');
+ addSource(
+ '/testCD.dart',
+ '''
+ String T1;
+ var _T2;
+ class C { }
+ class D { }''');
+ addSource(
+ '/testEEF.dart',
+ '''
+ class EE { }
+ class F { }''');
+ addSource('/testG.dart', 'class G { }');
+ addSource(
+ '/testH.dart',
+ '''
+ class H { }
+ int T3;
+ var _T4;'''); // not imported
+ addTestSource('''
+ import "/testAB.dart";
+ import "/testCD.dart" hide D;
+ import "/testEEF.dart" show EE;
+ import "/testG.dart" as g;
+ int T5;
+ var _T6;
+ String get T7 => 'hello';
+ set T8(int value) { partT8() {} }
+ Z D2() {int x;}
+ class X {
+ int get clog => 8;
+ set blog(value) { }
+ a() {
+ final ^
+ var f;
+ localF(int arg1) { }
+ {var x;}
+ }
+ void b() { }}
+ class Z { }''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+
+ assertNotSuggested('X');
+ assertNotSuggested('Z');
+ assertNotSuggested('a');
+ assertNotSuggested('b');
+ assertNotSuggested('localF');
+ assertNotSuggested('f');
+ // Don't suggest locals out of scope
+ assertNotSuggested('r');
+ assertNotSuggested('x');
+ assertNotSuggested('partT8');
+
+ assertNotSuggested('A');
+ assertNotSuggested('_B');
+ assertNotSuggested('C');
+ assertNotSuggested('partBoo');
+ // hidden element suggested as low relevance
+ // but imported results are partially filtered
+ //assertNotSuggested('D');
+ //assertNotSuggested(
+ // 'D1', null, true, COMPLETION_RELEVANCE_LOW);
+ assertNotSuggested('D2');
+ assertNotSuggested('EE');
+ // hidden element suggested as low relevance
+ //assertNotSuggested('F');
+ assertNotSuggested('g');
+ assertNotSuggested('G');
+ //assertNotSuggested('H');
+ assertNotSuggested('Object');
+ assertNotSuggested('min');
+ //assertNotSuggested(
+ // 'max',
+ // 'num',
+ // false,
+ // COMPLETION_RELEVANCE_LOW);
+ assertNotSuggested('T1');
+ assertNotSuggested('_T2');
+ //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+ assertNotSuggested('_T4');
+ assertNotSuggested('T5');
+ assertNotSuggested('_T6');
+ assertNotSuggested('==');
+ assertNotSuggested('T7');
+ assertNotSuggested('T8');
+ assertNotSuggested('clog');
+ assertNotSuggested('blog');
+ // TODO (danrubel) suggest HtmlElement as low relevance
+ assertNotSuggested('HtmlElement');
+ assertNotSuggested('Uri');
+ assertNotSuggested('parseIPv6Address');
+ assertNotSuggested('parseHex');
+ }
+
+ test_Block_identifier_partial() async {
+ addSource(
+ '/testAB.dart',
+ '''
+ export "dart:math" hide max;
+ class A {int x;}
+ @deprecated D1() {int x;}
+ class _B { }''');
+ addSource(
+ '/testCD.dart',
+ '''
+ String T1;
+ var _T2;
+ class C { }
+ class D { }''');
+ addSource(
+ '/testEEF.dart',
+ '''
+ class EE { }
+ class F { }''');
+ addSource('/testG.dart', 'class G { }');
+ addSource(
+ '/testH.dart',
+ '''
+ class H { }
+ class D3 { }
+ int T3;
+ var _T4;'''); // not imported
+ addTestSource('''
+ import "/testAB.dart";
+ import "/testCD.dart" hide D;
+ import "/testEEF.dart" show EE;
+ import "/testG.dart" as g;
+ int T5;
+ var _T6;
+ Z D2() {int x;}
+ class X {a() {var f; {var x;} D^ var r;} void b() { }}
+ class Z { }''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+
+ assertNotSuggested('X');
+ assertNotSuggested('Z');
+ assertNotSuggested('a');
+ assertNotSuggested('b');
+ assertNotSuggested('f');
+ // Don't suggest locals out of scope
+ assertNotSuggested('r');
+ assertNotSuggested('x');
+
+ // imported elements are portially filtered
+ //assertNotSuggested('A');
+ assertNotSuggested('_B');
+ //assertNotSuggested('C');
+ // hidden element suggested as low relevance
+ assertNotSuggested('D');
+ assertNotSuggested('D1');
+ assertNotSuggested('D2');
+ // unimported elements suggested with low relevance
+ assertNotSuggested('D3');
+ //assertNotSuggested('EE');
+ // hidden element suggested as low relevance
+ //assertNotSuggested('F');
+ //assertNotSuggested('g');
+ assertNotSuggested('G');
+ //assertNotSuggested('H');
+ //assertNotSuggested('Object');
+ //assertNotSuggested('min');
+ //assertNotSuggested(
+ // 'max',
+ // 'num',
+ // false,
+ // COMPLETION_RELEVANCE_LOW);
+ //assertSuggestTopLevelVarGetterSetter('T1', 'String');
+ assertNotSuggested('_T2');
+ //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+ assertNotSuggested('_T4');
+ //assertNotSuggested('T5');
+ //assertNotSuggested('_T6');
+ assertNotSuggested('==');
+ // TODO (danrubel) suggest HtmlElement as low relevance
+ assertNotSuggested('HtmlElement');
+ }
+
+ test_Block_inherited_imported() async {
+ // Block BlockFunctionBody MethodDeclaration ClassDeclaration
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
+ class E extends F { var e1; e2() { } }
+ class I { int i1; i2() { } }
+ class M { var m1; int m2() { } }''');
+ addTestSource('''
+ import "/testB.dart";
+ class A extends E implements I with M {a() {^}}''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ // TODO (danrubel) prefer fields over getters
+ // If add `get e1;` to interface I
+ // then suggestions include getter e1 rather than field e1
+ assertNotSuggested('e1');
+ assertNotSuggested('f1');
+ assertNotSuggested('i1');
+ assertNotSuggested('m1');
+ assertNotSuggested('f3');
+ assertNotSuggested('f4');
+ assertNotSuggested('e2');
+ assertNotSuggested('f2');
+ assertNotSuggested('i2');
+ //assertNotSuggested('m2');
+ assertNotSuggested('==');
+ }
+
+ test_Block_inherited_local() async {
+ // Block BlockFunctionBody MethodDeclaration ClassDeclaration
+ addTestSource('''
+ class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
+ class E extends F { var e1; e2() { } }
+ class I { int i1; i2() { } }
+ class M { var m1; int m2() { } }
+ class A extends E implements I with M {a() {^}}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('e1');
+ assertNotSuggested('f1');
+ assertNotSuggested('i1');
+ assertNotSuggested('m1');
+ assertNotSuggested('f3');
+ assertNotSuggested('f4');
+ assertNotSuggested('e2');
+ assertNotSuggested('f2');
+ assertNotSuggested('i2');
+ assertNotSuggested('m2');
+ }
+
+ test_Block_local_function() async {
+ addSource(
+ '/testAB.dart',
+ '''
+ export "dart:math" hide max;
+ class A {int x;}
+ @deprecated D1() {int x;}
+ class _B {boo() { partBoo() {}} }''');
+ addSource(
+ '/testCD.dart',
+ '''
+ String T1;
+ var _T2;
+ class C { }
+ class D { }''');
+ addSource(
+ '/testEEF.dart',
+ '''
+ class EE { }
+ class F { }''');
+ addSource('/testG.dart', 'class G { }');
+ addSource(
+ '/testH.dart',
+ '''
+ class H { }
+ int T3;
+ var _T4;'''); // not imported
+ addTestSource('''
+ import "/testAB.dart";
+ import "/testCD.dart" hide D;
+ import "/testEEF.dart" show EE;
+ import "/testG.dart" as g;
+ int T5;
+ var _T6;
+ String get T7 => 'hello';
+ set T8(int value) { partT8() {} }
+ Z D2() {int x;}
+ class X {
+ int get clog => 8;
+ set blog(value) { }
+ a() {
+ var f;
+ localF(int arg1) { }
+ {var x;}
+ p^ var r;
+ }
+ void b() { }}
+ class Z { }''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+ assertNotSuggested('partT8');
+ assertNotSuggested('partBoo');
+ assertNotSuggested('parseIPv6Address');
+ assertNotSuggested('parseHex');
+ }
+
+ test_Block_unimported() async {
+ addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
+ addSource(
+ '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
+ testFile = '/proj/completionTest.dart';
+ addTestSource('class C {foo(){F^}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+ assertNotSuggested('Foo');
+ // TODO(danrubel) implement
+ assertNotSuggested('Foo2');
+ assertNotSuggested('Future');
+ }
+
+ test_CascadeExpression_method1() async {
+ // PropertyAccess CascadeExpression ExpressionStatement Block
+ addSource(
+ '/testB.dart',
+ '''
+ class B { }''');
+ addTestSource('''
+ import "/testB.dart";
+ class A {var b; X _c;}
+ class X{}
+ // looks like a cascade to the parser
+ // but the user is trying to get completions for a non-cascade
+ main() {A a; a.^.z()}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestField('b', null);
+ assertSuggestField('_c', 'X');
+ assertNotSuggested('Object');
+ assertNotSuggested('A');
+ assertNotSuggested('B');
+ assertNotSuggested('X');
+ assertNotSuggested('z');
+ assertNotSuggested('==');
+ }
+
+ test_CascadeExpression_selector1() async {
+ // PropertyAccess CascadeExpression ExpressionStatement Block
+ addSource(
+ '/testB.dart',
+ '''
+ class B { }''');
+ addTestSource('''
+ import "/testB.dart";
+ class A {var b; X _c;}
+ class X{}
+ // looks like a cascade to the parser
+ // but the user is trying to get completions for a non-cascade
+ main() {A a; a.^.z}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestField('b', null);
+ assertSuggestField('_c', 'X');
+ assertNotSuggested('Object');
+ assertNotSuggested('A');
+ assertNotSuggested('B');
+ assertNotSuggested('X');
+ assertNotSuggested('z');
+ assertNotSuggested('==');
+ }
+
+ test_CascadeExpression_selector2() async {
+ // SimpleIdentifier PropertyAccess CascadeExpression ExpressionStatement
+ addSource(
+ '/testB.dart',
+ '''
+ class B { }''');
+ addTestSource('''
+ import "/testB.dart";
+ class A {var b; X _c;}
+ class X{}
+ main() {A a; a..^z}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 1);
+ assertSuggestField('b', null);
+ assertSuggestField('_c', 'X');
+ assertNotSuggested('Object');
+ assertNotSuggested('A');
+ assertNotSuggested('B');
+ assertNotSuggested('X');
+ assertNotSuggested('z');
+ assertNotSuggested('==');
+ }
+
+ test_CascadeExpression_selector2_withTrailingReturn() async {
+ // PropertyAccess CascadeExpression ExpressionStatement Block
+ addSource(
+ '/testB.dart',
+ '''
+ class B { }''');
+ addTestSource('''
+ import "/testB.dart";
+ class A {var b; X _c;}
+ class X{}
+ main() {A a; a..^ return}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestField('b', null);
+ assertSuggestField('_c', 'X');
+ assertNotSuggested('Object');
+ assertNotSuggested('A');
+ assertNotSuggested('B');
+ assertNotSuggested('X');
+ assertNotSuggested('z');
+ assertNotSuggested('==');
+ }
+
+ test_CascadeExpression_target() async {
+ // SimpleIdentifier CascadeExpression ExpressionStatement
+ addTestSource('''
+ class A {var b; X _c;}
+ class X{}
+ main() {A a; a^..b}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+ assertNotSuggested('b');
+ assertNotSuggested('_c');
+ assertNotSuggested('a');
+ assertNotSuggested('A');
+ assertNotSuggested('X');
+ // top level results are partially filtered
+ //assertNotSuggested('Object');
+ assertNotSuggested('==');
+ }
+
+ test_CatchClause_onType() async {
+ // TypeName CatchClause TryStatement
+ addTestSource('class A {a() {try{var x;} on ^ {}}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('A');
+ assertNotSuggested('Object');
+ assertNotSuggested('a');
+ assertNotSuggested('x');
+ }
+
+ test_CatchClause_onType_noBrackets() async {
+ // TypeName CatchClause TryStatement
+ addTestSource('class A {a() {try{var x;} on ^}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('A');
+ assertNotSuggested('Object');
+ assertNotSuggested('x');
+ }
+
+ test_CatchClause_typed() async {
+ // Block CatchClause TryStatement
+ addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('e');
+ assertNotSuggested('a');
+ assertNotSuggested('Object');
+ assertNotSuggested('x');
+ }
+
+ test_CatchClause_untyped() async {
+ // Block CatchClause TryStatement
+ addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('e');
+ assertNotSuggested('s');
+ assertNotSuggested('a');
+ assertNotSuggested('Object');
+ assertNotSuggested('x');
+ }
+
+ test_ClassDeclaration_body() async {
+ // ClassDeclaration CompilationUnit
+ addSource(
+ '/testB.dart',
+ '''
+ class B { }''');
+ addTestSource('''
+ import "testB.dart" as x;
+ @deprecated class A {^}
+ class _B {}
+ A T;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('A');
+ assertNotSuggested('_B');
+ assertNotSuggested('Object');
+ assertNotSuggested('T');
+ assertNotSuggested('x');
+ }
+
+ test_ClassDeclaration_body_final() async {
+ // ClassDeclaration CompilationUnit
+ addSource(
+ '/testB.dart',
+ '''
+ class B { }''');
+ addTestSource('''
+ import "testB.dart" as x;
+ class A {final ^}
+ class _B {}
+ A T;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('A');
+ assertNotSuggested('_B');
+ assertNotSuggested('Object');
+ assertNotSuggested('T');
+ assertNotSuggested('x');
+ }
+
+ test_ClassDeclaration_body_final_field() async {
+ // ClassDeclaration CompilationUnit
+ addSource(
+ '/testB.dart',
+ '''
+ class B { }''');
+ addTestSource('''
+ import "testB.dart" as x;
+ class A {final ^ A(){}}
+ class _B {}
+ A T;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('A');
+ assertNotSuggested('_B');
+ assertNotSuggested('String');
+ assertNotSuggested('T');
+ assertNotSuggested('x');
+ }
+
+ test_ClassDeclaration_body_final_field2() async {
+ // ClassDeclaration CompilationUnit
+ addSource(
+ '/testB.dart',
+ '''
+ class B { }''');
+ addTestSource('''
+ import "testB.dart" as Soo;
+ class A {final S^ A();}
+ class _B {}
+ A Sew;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+ assertNotSuggested('A');
+ assertNotSuggested('_B');
+ assertNotSuggested('String');
+ assertNotSuggested('Sew');
+ assertNotSuggested('Soo');
+ }
+
+ test_ClassDeclaration_body_final_final() async {
+ // ClassDeclaration CompilationUnit
+ addSource(
+ '/testB.dart',
+ '''
+ class B { }''');
+ addTestSource('''
+ import "testB.dart" as x;
+ class A {final ^ final foo;}
+ class _B {}
+ A T;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('A');
+ assertNotSuggested('_B');
+ assertNotSuggested('Object');
+ assertNotSuggested('T');
+ assertNotSuggested('x');
+ }
+
+ test_ClassDeclaration_body_final_var() async {
+ // ClassDeclaration CompilationUnit
+ addSource(
+ '/testB.dart',
+ '''
+ class B { }''');
+ addTestSource('''
+ import "testB.dart" as x;
+ class A {final ^ var foo;}
+ class _B {}
+ A T;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('A');
+ assertNotSuggested('_B');
+ assertNotSuggested('Object');
+ assertNotSuggested('T');
+ assertNotSuggested('x');
+ }
+
+ test_Combinator_hide() async {
+ // SimpleIdentifier HideCombinator ImportDirective
+ addSource(
+ '/testAB.dart',
+ '''
+ library libAB;
+ part '/partAB.dart';
+ class A { }
+ class B { }''');
+ addSource(
+ '/partAB.dart',
+ '''
+ part of libAB;
+ var T1;
+ PB F1() => new PB();
+ class PB { }''');
+ addSource(
+ '/testCD.dart',
+ '''
+ class C { }
+ class D { }''');
+ addTestSource('''
+ import "/testAB.dart" hide ^;
+ import "/testCD.dart";
+ class X {}''');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_Combinator_show() async {
+ // SimpleIdentifier HideCombinator ImportDirective
+ addSource(
+ '/testAB.dart',
+ '''
+ library libAB;
+ part '/partAB.dart';
+ class A { }
+ class B { }''');
+ addSource(
+ '/partAB.dart',
+ '''
+ part of libAB;
+ var T1;
+ PB F1() => new PB();
+ typedef PB2 F2(int blat);
+ class Clz = Object with Object;
+ class PB { }''');
+ addSource(
+ '/testCD.dart',
+ '''
+ class C { }
+ class D { }''');
+ addTestSource('''
+ import "/testAB.dart" show ^;
+ import "/testCD.dart";
+ class X {}''');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_ConditionalExpression_elseExpression() async {
+ // SimpleIdentifier ConditionalExpression ReturnStatement
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ class A {int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ class B {int x;}
+ class C {foo(){var f; {var x;} return a ? T1 : T^}}''');
+ await computeSuggestions();
+ // top level results are partially filtered based on first char
+ assertNotSuggested('T2');
+ // TODO (danrubel) getter is being suggested instead of top level var
+ //assertSuggestImportedTopLevelVar('T1', 'int');
+ }
+
+ test_ConditionalExpression_elseExpression_empty() async {
+ // SimpleIdentifier ConditionalExpression ReturnStatement
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ class A {int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ class B {int x;}
+ class C {foo(){var f; {var x;} return a ? T1 : ^}}''');
+ await computeSuggestions();
+ assertNotSuggested('x');
+ assertNotSuggested('f');
+ assertNotSuggested('foo');
+ assertNotSuggested('C');
+ assertNotSuggested('F2');
+ assertNotSuggested('T2');
+ assertNotSuggested('A');
+ assertNotSuggested('F1');
+ // TODO (danrubel) getter is being suggested instead of top level var
+ //assertSuggestImportedTopLevelVar('T1', 'int');
+ }
+
+ test_ConditionalExpression_partial_thenExpression() async {
+ // SimpleIdentifier ConditionalExpression ReturnStatement
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ class A {int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ class B {int x;}
+ class C {foo(){var f; {var x;} return a ? T^}}''');
+ await computeSuggestions();
+ // top level results are partially filtered based on first char
+ assertNotSuggested('T2');
+ // TODO (danrubel) getter is being suggested instead of top level var
+ //assertSuggestImportedTopLevelVar('T1', 'int');
+ }
+
+ test_ConditionalExpression_partial_thenExpression_empty() async {
+ // SimpleIdentifier ConditionalExpression ReturnStatement
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ class A {int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ class B {int x;}
+ class C {foo(){var f; {var x;} return a ? ^}}''');
+ await computeSuggestions();
+ assertNotSuggested('x');
+ assertNotSuggested('f');
+ assertNotSuggested('foo');
+ assertNotSuggested('C');
+ assertNotSuggested('F2');
+ assertNotSuggested('T2');
+ assertNotSuggested('A');
+ assertNotSuggested('F1');
+ // TODO (danrubel) getter is being suggested instead of top level var
+ //assertSuggestImportedTopLevelVar('T1', 'int');
+ }
+
+ test_ConditionalExpression_thenExpression() async {
+ // SimpleIdentifier ConditionalExpression ReturnStatement
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ class A {int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ class B {int x;}
+ class C {foo(){var f; {var x;} return a ? T^ : c}}''');
+ await computeSuggestions();
+ // top level results are partially filtered based on first char
+ assertNotSuggested('T2');
+ // TODO (danrubel) getter is being suggested instead of top level var
+ //assertSuggestImportedTopLevelVar('T1', 'int');
+ }
+
+ test_ConstructorName_importedClass() async {
+ // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName
+ // InstanceCreationExpression
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ int T1;
+ F1() { }
+ class X {X.c(); X._d(); z() {}}''');
+ addTestSource('''
+ import "/testB.dart";
+ var m;
+ main() {new X.^}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ // Suggested by NamedConstructorContributor
+ assertNotSuggested('c');
+ assertNotSuggested('F1');
+ assertNotSuggested('T1');
+ assertNotSuggested('_d');
+ assertNotSuggested('z');
+ assertNotSuggested('m');
+ }
+
+ test_ConstructorName_importedFactory() async {
+ // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName
+ // InstanceCreationExpression
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ int T1;
+ F1() { }
+ class X {factory X.c(); factory X._d(); z() {}}''');
+ addTestSource('''
+ import "/testB.dart";
+ var m;
+ main() {new X.^}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ // Suggested by NamedConstructorContributor
+ assertNotSuggested('c');
+ assertNotSuggested('F1');
+ assertNotSuggested('T1');
+ assertNotSuggested('_d');
+ assertNotSuggested('z');
+ assertNotSuggested('m');
+ }
+
+ test_ConstructorName_importedFactory2() async {
+ // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName
+ // InstanceCreationExpression
+ addTestSource('''
+ main() {new String.fr^omCharCodes([]);}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 2);
+ expect(replacementLength, 13);
+ // Suggested by NamedConstructorContributor
+ assertNotSuggested('fromCharCodes');
+ assertNotSuggested('isEmpty');
+ assertNotSuggested('isNotEmpty');
+ assertNotSuggested('length');
+ assertNotSuggested('Object');
+ assertNotSuggested('String');
+ }
+
+ test_ConstructorName_localClass() async {
+ // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName
+ // InstanceCreationExpression
+ addTestSource('''
+ int T1;
+ F1() { }
+ class X {X.c(); X._d(); z() {}}
+ main() {new X.^}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ // Suggested by NamedConstructorContributor
+ assertNotSuggested('c');
+ assertNotSuggested('_d');
+ assertNotSuggested('F1');
+ assertNotSuggested('T1');
+ assertNotSuggested('z');
+ assertNotSuggested('m');
+ }
+
+ test_ConstructorName_localFactory() async {
+ // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName
+ // InstanceCreationExpression
+ addTestSource('''
+ int T1;
+ F1() { }
+ class X {factory X.c(); factory X._d(); z() {}}
+ main() {new X.^}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ // Suggested by NamedConstructorContributor
+ assertNotSuggested('c');
+ assertNotSuggested('_d');
+ assertNotSuggested('F1');
+ assertNotSuggested('T1');
+ assertNotSuggested('z');
+ assertNotSuggested('m');
+ }
+
+ test_DefaultFormalParameter_named_expression() async {
+ // DefaultFormalParameter FormalParameterList MethodDeclaration
+ addTestSource('''
+ foo() { }
+ void bar() { }
+ class A {a(blat: ^) { }}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('foo');
+ assertNotSuggested('a');
+ assertNotSuggested('A');
+ assertNotSuggested('String');
+ assertNotSuggested('identical');
+ assertNotSuggested('bar');
+ }
+
+ test_ExpressionStatement_identifier() async {
+ // SimpleIdentifier ExpressionStatement Block
+ addSource(
+ '/testA.dart',
+ '''
+ _B F1() { }
+ class A {int x;}
+ class _B { }''');
+ addTestSource('''
+ import "/testA.dart";
+ typedef int F2(int blat);
+ class Clz = Object with Object;
+ class C {foo(){^} void bar() {}}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('A');
+ assertNotSuggested('F1');
+ assertNotSuggested('C');
+ assertNotSuggested('foo');
+ assertNotSuggested('bar');
+ assertNotSuggested('F2');
+ assertNotSuggested('Clz');
+ assertNotSuggested('C');
+ assertNotSuggested('x');
+ assertNotSuggested('_B');
+ }
+
+ test_ExpressionStatement_name() async {
+ // ExpressionStatement Block BlockFunctionBody MethodDeclaration
+ addSource(
+ '/testA.dart',
+ '''
+ B T1;
+ class B{}''');
+ addTestSource('''
+ import "/testA.dart";
+ class C {a() {C ^}}''');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_FieldDeclaration_name_typed() async {
+ // SimpleIdentifier VariableDeclaration VariableDeclarationList
+ // FieldDeclaration
+ addSource('/testA.dart', 'class A { }');
+ addTestSource('''
+ import "/testA.dart";
+ class C {A ^}''');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_FieldDeclaration_name_var() async {
+ // SimpleIdentifier VariableDeclaration VariableDeclarationList
+ // FieldDeclaration
+ addSource('/testA.dart', 'class A { }');
+ addTestSource('''
+ import "/testA.dart";
+ class C {var ^}''');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_FieldFormalParameter_in_non_constructor() async {
+ // SimpleIdentifer FieldFormalParameter FormalParameterList
+ addTestSource('class A {B(this.^foo) {}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 3);
+ assertNoSuggestions();
+ }
+
+ test_ForEachStatement_body_typed() async {
+ // Block ForEachStatement
+ addTestSource('main(args) {for (int foo in bar) {^}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('args');
+ assertNotSuggested('foo');
+ assertNotSuggested('Object');
+ }
+
+ test_ForEachStatement_body_untyped() async {
+ // Block ForEachStatement
+ addTestSource('main(args) {for (foo in bar) {^}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('args');
+ assertNotSuggested('foo');
+ assertNotSuggested('Object');
+ }
+
+ test_ForEachStatement_iterable() async {
+ // SimpleIdentifier ForEachStatement Block
+ addTestSource('main(args) {for (int foo in ^) {}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('args');
+ assertNotSuggested('Object');
+ }
+
+ test_ForEachStatement_loopVariable() async {
+ // SimpleIdentifier ForEachStatement Block
+ addTestSource('main(args) {for (^ in args) {}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('args');
+ assertNotSuggested('String');
+ }
+
+ test_ForEachStatement_loopVariable_type() async {
+ // SimpleIdentifier ForEachStatement Block
+ addTestSource('main(args) {for (^ foo in args) {}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('args');
+ assertNotSuggested('foo');
+ assertNotSuggested('String');
+ }
+
+ test_ForEachStatement_loopVariable_type2() async {
+ // DeclaredIdentifier ForEachStatement Block
+ addTestSource('main(args) {for (S^ foo in args) {}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+ assertNotSuggested('args');
+ assertNotSuggested('foo');
+ assertNotSuggested('String');
+ }
+
+ test_FormalParameterList() async {
+ // FormalParameterList MethodDeclaration
+ addTestSource('''
+ foo() { }
+ void bar() { }
+ class A {a(^) { }}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('foo');
+ assertNotSuggested('a');
+ assertNotSuggested('A');
+ assertNotSuggested('String');
+ assertNotSuggested('identical');
+ assertNotSuggested('bar');
+ }
+
+ test_ForStatement_body() async {
+ // Block ForStatement
+ addTestSource('main(args) {for (int i; i < 10; ++i) {^}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('i');
+ assertNotSuggested('Object');
+ }
+
+ test_ForStatement_condition() async {
+ // SimpleIdentifier ForStatement
+ addTestSource('main() {for (int index = 0; i^)}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+ assertNotSuggested('index');
+ }
+
+ test_ForStatement_initializer() async {
+ // SimpleIdentifier ForStatement
+ addTestSource('main() {List a; for (^)}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('a');
+ assertNotSuggested('Object');
+ assertNotSuggested('int');
+ }
+
+ test_ForStatement_updaters() async {
+ // SimpleIdentifier ForStatement
+ addTestSource('main() {for (int index = 0; index < 10; i^)}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+ assertNotSuggested('index');
+ }
+
+ test_ForStatement_updaters_prefix_expression() async {
+ // SimpleIdentifier PrefixExpression ForStatement
+ addTestSource('''
+ void bar() { }
+ main() {for (int index = 0; index < 10; ++i^)}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+ assertNotSuggested('index');
+ assertNotSuggested('main');
+ assertNotSuggested('bar');
+ }
+
+ test_FunctionDeclaration_returnType_afterComment() async {
+ // ClassDeclaration CompilationUnit
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ typedef D1();
+ class C1 {C1(this.x) { } int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ typedef D2();
+ class C2 { }
+ /* */ ^ zoo(z) { } String name;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('Object');
+ assertNotSuggested('T1');
+ assertNotSuggested('F1');
+ assertNotSuggested('D1');
+ assertNotSuggested('C1');
+ assertNotSuggested('T2');
+ assertNotSuggested('F2');
+ assertNotSuggested('D2');
+ assertNotSuggested('C2');
+ assertNotSuggested('name');
+ }
+
+ test_FunctionDeclaration_returnType_afterComment2() async {
+ // FunctionDeclaration ClassDeclaration CompilationUnit
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ typedef D1();
+ class C1 {C1(this.x) { } int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ typedef D2();
+ class C2 { }
+ /** */ ^ zoo(z) { } String name;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('Object');
+ assertNotSuggested('T1');
+ assertNotSuggested('F1');
+ assertNotSuggested('D1');
+ assertNotSuggested('C1');
+ assertNotSuggested('T2');
+ assertNotSuggested('F2');
+ assertNotSuggested('D2');
+ assertNotSuggested('C2');
+ assertNotSuggested('name');
+ }
+
+ test_FunctionDeclaration_returnType_afterComment3() async {
+ // FunctionDeclaration ClassDeclaration CompilationUnit
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ typedef D1();
+ class C1 {C1(this.x) { } int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ typedef D2();
+ /// some dartdoc
+ class C2 { }
+ ^ zoo(z) { } String name;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('Object');
+ assertNotSuggested('T1');
+ assertNotSuggested('F1');
+ assertNotSuggested('D1');
+ assertNotSuggested('C1');
+ assertNotSuggested('T2');
+ assertNotSuggested('F2');
+ assertNotSuggested('D2');
+ assertNotSuggested('C2');
+ assertNotSuggested('name');
+ }
+
+ test_FunctionExpression_body_function() async {
+ // Block BlockFunctionBody FunctionExpression
+ addTestSource('''
+ void bar() { }
+ String foo(List args) {x.then((R b) {^}''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('foo');
+ assertNotSuggested('bar');
+ assertNotSuggested('args');
+ assertNotSuggested('b');
+ assertNotSuggested('Object');
+ }
+
+ test_IfStatement() async {
+ // SimpleIdentifier IfStatement
+ addTestSource('''
+ class A {var b; X _c; foo() {A a; if (true) ^}}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('b');
+ assertNotSuggested('_c');
+ assertNotSuggested('Object');
+ assertNotSuggested('A');
+ assertNotSuggested('==');
+ }
+
+ test_IfStatement_condition() async {
+ // SimpleIdentifier IfStatement Block BlockFunctionBody
+ addTestSource('''
+ class A {int x; int y() => 0;}
+ main(){var a; if (^)}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('a');
+ assertNotSuggested('main');
+ assertNotSuggested('A');
+ assertNotSuggested('Object');
+ }
+
+ test_IfStatement_empty() async {
+ // SimpleIdentifier IfStatement
+ addTestSource('''
+ class A {var b; X _c; foo() {A a; if (^) something}}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('b');
+ assertNotSuggested('_c');
+ assertNotSuggested('Object');
+ assertNotSuggested('A');
+ assertNotSuggested('==');
+ }
+
+ test_IfStatement_invocation() async {
+ // SimpleIdentifier PrefixIdentifier IfStatement
+ addTestSource('''
+ main() {var a; if (a.^) something}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestMethod('toString', 'Object', 'String');
+ assertNotSuggested('Object');
+ assertNotSuggested('A');
+ assertNotSuggested('==');
+ }
+
+ test_ImportDirective_dart() async {
+ // SimpleStringLiteral ImportDirective
+ addTestSource('''
+ import "dart^";
+ main() {}''');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_IndexExpression() async {
+ // ExpressionStatement Block
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ class A {int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ class B {int x;}
+ class C {foo(){var f; {var x;} f[^]}}''');
+ await computeSuggestions();
+ assertNotSuggested('x');
+ assertNotSuggested('f');
+ assertNotSuggested('foo');
+ assertNotSuggested('C');
+ assertNotSuggested('F2');
+ assertNotSuggested('T2');
+ assertNotSuggested('A');
+ assertNotSuggested('F1');
+ // TODO (danrubel) getter is being suggested instead of top level var
+ //assertSuggestImportedTopLevelVar('T1', 'int');
+ }
+
+ test_IndexExpression2() async {
+ // SimpleIdentifier IndexExpression ExpressionStatement Block
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ class A {int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ class B {int x;}
+ class C {foo(){var f; {var x;} f[T^]}}''');
+ await computeSuggestions();
+ // top level results are partially filtered based on first char
+ assertNotSuggested('T2');
+ // TODO (danrubel) getter is being suggested instead of top level var
+ //assertSuggestImportedTopLevelVar('T1', 'int');
+ }
+
+ test_InstanceCreationExpression_imported() async {
+ // SimpleIdentifier TypeName ConstructorName InstanceCreationExpression
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ class A {A(this.x) { } int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ import "dart:async";
+ int T2;
+ F2() { }
+ class B {B(this.x, [String boo]) { } int x;}
+ class C {foo(){var f; {var x;} new ^}}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('Object');
+ assertNotSuggested('Future');
+ assertNotSuggested('A');
+ assertNotSuggested('B');
+ assertNotSuggested('C');
+ assertNotSuggested('f');
+ assertNotSuggested('x');
+ assertNotSuggested('foo');
+ assertNotSuggested('F1');
+ assertNotSuggested('F2');
+ assertNotSuggested('T1');
+ assertNotSuggested('T2');
+ }
+
+ test_InstanceCreationExpression_unimported() async {
+ // SimpleIdentifier TypeName ConstructorName InstanceCreationExpression
+ addSource('/testAB.dart', 'class Foo { }');
+ addTestSource('class C {foo(){new F^}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+ assertNotSuggested('Future');
+ assertNotSuggested('Foo');
+ }
+
+ test_InterpolationExpression() async {
+ // SimpleIdentifier InterpolationExpression StringInterpolation
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ typedef D1();
+ class C1 {C1(this.x) { } int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ typedef D2();
+ class C2 { }
+ main() {String name; print("hello \$^");}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('Object');
+ // TODO(danrubel) should return top level var rather than getter
+ assertNotSuggested('F1');
+ assertNotSuggested('D1');
+ assertNotSuggested('C1');
+ assertNotSuggested('T2');
+ assertNotSuggested('F2');
+ assertNotSuggested('D2');
+ assertNotSuggested('C2');
+ assertNotSuggested('name');
+ }
+
+ test_InterpolationExpression_block() async {
+ // SimpleIdentifier InterpolationExpression StringInterpolation
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ typedef D1();
+ class C1 {C1(this.x) { } int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ typedef D2();
+ class C2 { }
+ main() {String name; print("hello \${^}");}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('Object');
+ assertNotSuggested('F1');
+ assertNotSuggested('D1');
+ assertNotSuggested('C1');
+ assertNotSuggested('T2');
+ assertNotSuggested('F2');
+ assertNotSuggested('D2');
+ assertNotSuggested('C2');
+ assertNotSuggested('name');
+ }
+
+ test_InterpolationExpression_block2() async {
+ // SimpleIdentifier InterpolationExpression StringInterpolation
+ addTestSource('main() {String name; print("hello \${n^}");}');
+ await computeSuggestions();
+ assertNotSuggested('name');
+ // top level results are partially filtered
+ //assertNotSuggested('Object');
+ }
+
+ test_InterpolationExpression_prefix_selector() async {
+ // SimpleIdentifier PrefixedIdentifier InterpolationExpression
+ addTestSource('main() {String name; print("hello \${name.^}");}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestGetter('length', 'int');
+ assertNotSuggested('name');
+ assertNotSuggested('Object');
+ assertNotSuggested('==');
+ }
+
+ test_InterpolationExpression_prefix_selector2() async {
+ // SimpleIdentifier PrefixedIdentifier InterpolationExpression
+ addTestSource('main() {String name; print("hello \$name.^");}');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_InterpolationExpression_prefix_target() async {
+ // SimpleIdentifier PrefixedIdentifier InterpolationExpression
+ addTestSource('main() {String name; print("hello \${nam^e.length}");}');
+ await computeSuggestions();
+ assertNotSuggested('name');
+ // top level results are partially filtered
+ //assertNotSuggested('Object');
+ assertNotSuggested('length');
+ }
+
+ test_IsExpression() async {
+ // SimpleIdentifier TypeName IsExpression IfStatement
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ foo() { }
+ class X {X.c(); X._d(); z() {}}''');
+ addTestSource('''
+ import "/testB.dart";
+ class Y {Y.c(); Y._d(); z() {}}
+ main() {var x; if (x is ^) { }}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('X');
+ assertNotSuggested('Y');
+ assertNotSuggested('x');
+ assertNotSuggested('main');
+ assertNotSuggested('foo');
+ }
+
+ test_IsExpression_target() async {
+ // IfStatement Block BlockFunctionBody
+ addTestSource('''
+ foo() { }
+ void bar() { }
+ class A {int x; int y() => 0;}
+ main(){var a; if (^ is A)}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('a');
+ assertNotSuggested('main');
+ assertNotSuggested('foo');
+ assertNotSuggested('bar');
+ assertNotSuggested('A');
+ assertNotSuggested('Object');
+ }
+
+ test_IsExpression_type() async {
+ // SimpleIdentifier TypeName IsExpression IfStatement
+ addTestSource('''
+ class A {int x; int y() => 0;}
+ main(){var a; if (a is ^)}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('a');
+ assertNotSuggested('main');
+ assertNotSuggested('A');
+ assertNotSuggested('Object');
+ }
+
+ test_IsExpression_type_partial() async {
+ // SimpleIdentifier TypeName IsExpression IfStatement
+ addTestSource('''
+ class A {int x; int y() => 0;}
+ main(){var a; if (a is Obj^)}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 3);
+ expect(replacementLength, 3);
+ assertNotSuggested('a');
+ assertNotSuggested('main');
+ assertNotSuggested('A');
+ assertNotSuggested('Object');
+ }
+
+ test_keyword2() async {
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ int newT1;
+ int T1;
+ nowIsIt() { }
+ class X {factory X.c(); factory X._d(); z() {}}''');
+ addTestSource('''
+ import "/testB.dart";
+ String newer() {}
+ var m;
+ main() {new^ X.c();}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 3);
+ expect(replacementLength, 3);
+ assertNotSuggested('c');
+ assertNotSuggested('_d');
+ // Imported suggestion are filtered by 1st character
+ assertNotSuggested('nowIsIt');
+ assertNotSuggested('T1');
+ assertNotSuggested('z');
+ assertNotSuggested('m');
+ assertNotSuggested('newer');
+ }
+
+ test_Literal_list() async {
+ // ']' ListLiteral ArgumentList MethodInvocation
+ addTestSource('main() {var Some; print([^]);}');
+ await computeSuggestions();
+ assertNotSuggested('Some');
+ assertNotSuggested('String');
+ }
+
+ test_Literal_list2() async {
+ // SimpleIdentifier ListLiteral ArgumentList MethodInvocation
+ addTestSource('main() {var Some; print([S^]);}');
+ await computeSuggestions();
+ assertNotSuggested('Some');
+ assertNotSuggested('String');
+ }
+
+ test_Literal_string() async {
+ // SimpleStringLiteral ExpressionStatement Block
+ addTestSource('class A {a() {"hel^lo"}}');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_MapLiteralEntry() async {
+ // MapLiteralEntry MapLiteral VariableDeclaration
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ typedef D1();
+ class C1 {C1(this.x) { } int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ typedef D2();
+ class C2 { }
+ foo = {^''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('Object');
+ assertNotSuggested('F1');
+ assertNotSuggested('D1');
+ assertNotSuggested('C1');
+ assertNotSuggested('T2');
+ assertNotSuggested('F2');
+ assertNotSuggested('D2');
+ assertNotSuggested('C2');
+ }
+
+ test_MapLiteralEntry1() async {
+ // MapLiteralEntry MapLiteral VariableDeclaration
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ typedef D1();
+ class C1 {C1(this.x) { } int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ typedef D2();
+ class C2 { }
+ foo = {T^''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+ assertNotSuggested('T2');
+ }
+
+ test_MapLiteralEntry2() async {
+ // SimpleIdentifier MapLiteralEntry MapLiteral VariableDeclaration
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ typedef D1();
+ class C1 {C1(this.x) { } int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ typedef D2();
+ class C2 { }
+ foo = {7:T^};''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+ assertNotSuggested('T2');
+ }
+
+ test_MethodDeclaration_body_getters() async {
+ // Block BlockFunctionBody MethodDeclaration
+ addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('a');
+ assertNotSuggested('f');
+ assertNotSuggested('_g');
+ }
+
+ test_MethodDeclaration_body_static() async {
+ // Block BlockFunctionBody MethodDeclaration
+ addSource(
+ '/testC.dart',
+ '''
+ class C {
+ c1() {}
+ var c2;
+ static c3() {}
+ static var c4;}''');
+ addTestSource('''
+ import "/testC.dart";
+ class B extends C {
+ b1() {}
+ var b2;
+ static b3() {}
+ static var b4;}
+ class A extends B {
+ a1() {}
+ var a2;
+ static a3() {}
+ static var a4;
+ static a() {^}}''');
+ await computeSuggestions();
+ assertNotSuggested('a1');
+ assertNotSuggested('a2');
+ assertNotSuggested('a3');
+ assertNotSuggested('a4');
+ assertNotSuggested('b1');
+ assertNotSuggested('b2');
+ assertNotSuggested('b3');
+ assertNotSuggested('b4');
+ assertNotSuggested('c1');
+ assertNotSuggested('c2');
+ assertNotSuggested('c3');
+ assertNotSuggested('c4');
+ }
+
+ test_MethodDeclaration_members() async {
+ // Block BlockFunctionBody MethodDeclaration
+ addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('_a');
+ assertNotSuggested('f');
+ assertNotSuggested('_g');
+ assertNotSuggested('bool');
+ }
+
+ test_MethodDeclaration_parameters_named() async {
+ // Block BlockFunctionBody MethodDeclaration
+ addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('a');
+ assertNotSuggested('x');
+ assertNotSuggested('y');
+ assertNotSuggested('b');
+ assertNotSuggested('int');
+ assertNotSuggested('_');
+ }
+
+ test_MethodDeclaration_parameters_positional() async {
+ // Block BlockFunctionBody MethodDeclaration
+ addTestSource('''
+ foo() { }
+ void bar() { }
+ class A {Z a(X x, [int y=1]) {^}}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('foo');
+ assertNotSuggested('bar');
+ assertNotSuggested('a');
+ assertNotSuggested('x');
+ assertNotSuggested('y');
+ assertNotSuggested('String');
+ }
+
+ test_MethodDeclaration_returnType() async {
+ // ClassDeclaration CompilationUnit
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ typedef D1();
+ class C1 {C1(this.x) { } int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ typedef D2();
+ class C2 {^ zoo(z) { } String name; }''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('Object');
+ assertNotSuggested('T1');
+ assertNotSuggested('F1');
+ assertNotSuggested('D1');
+ assertNotSuggested('C1');
+ assertNotSuggested('T2');
+ assertNotSuggested('F2');
+ assertNotSuggested('D2');
+ assertNotSuggested('C2');
+ assertNotSuggested('name');
+ }
+
+ test_MethodDeclaration_returnType_afterComment() async {
+ // ClassDeclaration CompilationUnit
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ typedef D1();
+ class C1 {C1(this.x) { } int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ typedef D2();
+ class C2 {/* */ ^ zoo(z) { } String name; }''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('Object');
+ assertNotSuggested('T1');
+ assertNotSuggested('F1');
+ assertNotSuggested('D1');
+ assertNotSuggested('C1');
+ assertNotSuggested('T2');
+ assertNotSuggested('F2');
+ assertNotSuggested('D2');
+ assertNotSuggested('C2');
+ assertNotSuggested('name');
+ }
+
+ test_MethodDeclaration_returnType_afterComment2() async {
+ // MethodDeclaration ClassDeclaration CompilationUnit
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ typedef D1();
+ class C1 {C1(this.x) { } int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ typedef D2();
+ class C2 {/** */ ^ zoo(z) { } String name; }''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('Object');
+ assertNotSuggested('T1');
+ assertNotSuggested('F1');
+ assertNotSuggested('D1');
+ assertNotSuggested('C1');
+ assertNotSuggested('T2');
+ assertNotSuggested('F2');
+ assertNotSuggested('D2');
+ assertNotSuggested('C2');
+ assertNotSuggested('name');
+ }
+
+ test_MethodDeclaration_returnType_afterComment3() async {
+ // MethodDeclaration ClassDeclaration CompilationUnit
+ addSource(
+ '/testA.dart',
+ '''
+ int T1;
+ F1() { }
+ typedef D1();
+ class C1 {C1(this.x) { } int x;}''');
+ addTestSource('''
+ import "/testA.dart";
+ int T2;
+ F2() { }
+ typedef D2();
+ class C2 {
+ /// some dartdoc
+ ^ zoo(z) { } String name; }''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('Object');
+ assertNotSuggested('T1');
+ assertNotSuggested('F1');
+ assertNotSuggested('D1');
+ assertNotSuggested('C1');
+ assertNotSuggested('T2');
+ assertNotSuggested('F2');
+ assertNotSuggested('D2');
+ assertNotSuggested('C2');
+ assertNotSuggested('name');
+ }
+
+ test_MethodInvocation_no_semicolon() async {
+ // MethodInvocation ExpressionStatement Block
+ addTestSource('''
+ main() { }
+ class I {X get f => new A();get _g => new A();}
+ class A implements I {
+ var b; X _c;
+ X get d => new A();get _e => new A();
+ // no semicolon between completion point and next statement
+ set s1(I x) {} set _s2(I x) {x.^ m(null);}
+ m(X x) {} I _n(X x) {}}
+ class X{}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestGetter('f', 'X');
+ assertSuggestGetter('_g', null);
+ assertNotSuggested('b');
+ assertNotSuggested('_c');
+ assertNotSuggested('d');
+ assertNotSuggested('_e');
+ assertNotSuggested('s1');
+ assertNotSuggested('_s2');
+ assertNotSuggested('m');
+ assertNotSuggested('_n');
+ assertNotSuggested('a');
+ assertNotSuggested('A');
+ assertNotSuggested('X');
+ assertNotSuggested('Object');
+ assertNotSuggested('==');
+ }
+
+ test_new_instance() async {
+ addTestSource('import "dart:math"; class A {x() {new Random().^}}');
+ await computeSuggestions();
+ assertSuggestMethod('nextBool', 'Random', 'bool');
+ assertSuggestMethod('nextDouble', 'Random', 'double');
+ assertSuggestMethod('nextInt', 'Random', 'int');
+ assertNotSuggested('Random');
+ assertNotSuggested('Object');
+ assertNotSuggested('A');
+ }
+
+ test_parameterName_excludeTypes() async {
+ addTestSource('m(int ^) {}');
+ await computeSuggestions();
+ assertNotSuggested('int');
+ assertNotSuggested('bool');
+ }
+
+ test_partFile_TypeName() async {
+ // SimpleIdentifier TypeName ConstructorName
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ int T1;
+ F1() { }
+ class X {X.c(); X._d(); z() {}}''');
+ addSource(
+ '/testA.dart',
+ '''
+ library libA;
+ import "/testB.dart";
+ part "$testFile";
+ class A { }
+ var m;''');
+ addTestSource('''
+ part of libA;
+ class B { factory B.bar(int x) => null; }
+ main() {new ^}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('B.bar');
+ assertNotSuggested('Object');
+ assertNotSuggested('X.c');
+ assertNotSuggested('X._d');
+ assertNotSuggested('A');
+ assertNotSuggested('F1');
+ assertNotSuggested('T1');
+ assertNotSuggested('_d');
+ assertNotSuggested('z');
+ assertNotSuggested('m');
+ }
+
+ test_partFile_TypeName2() async {
+ // SimpleIdentifier TypeName ConstructorName
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ int T1;
+ F1() { }
+ class X {X.c(); X._d(); z() {}}''');
+ addSource(
+ '/testA.dart',
+ '''
+ part of libA;
+ class B { }''');
+ addTestSource('''
+ library libA;
+ import "/testB.dart";
+ part "/testA.dart";
+ class A { A({String boo: 'hoo'}) { } }
+ main() {new ^}
+ var m;''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('A');
+ assertNotSuggested('Object');
+ assertNotSuggested('X.c');
+ assertNotSuggested('X._d');
+ assertNotSuggested('B');
+ assertNotSuggested('F1');
+ assertNotSuggested('T1');
+ assertNotSuggested('_d');
+ assertNotSuggested('z');
+ assertNotSuggested('m');
+ }
+
+ test_PrefixedIdentifier_class_const() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ class I {
+ static const scI = 'boo';
+ X get f => new A();
+ get _g => new A();}
+ class B implements I {
+ static const int scB = 12;
+ var b; X _c;
+ X get d => new A();get _e => new A();
+ set s1(I x) {} set _s2(I x) {}
+ m(X x) {} I _n(X x) {}}
+ class X{}''');
+ addTestSource('''
+ import "/testB.dart";
+ class A extends B {
+ static const String scA = 'foo';
+ w() { }}
+ main() {A.^}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ // Suggested by StaticMemberContributor
+ assertNotSuggested('scA');
+ assertNotSuggested('scB');
+ assertNotSuggested('scI');
+ assertNotSuggested('b');
+ assertNotSuggested('_c');
+ assertNotSuggested('d');
+ assertNotSuggested('_e');
+ assertNotSuggested('f');
+ assertNotSuggested('_g');
+ assertNotSuggested('s1');
+ assertNotSuggested('_s2');
+ assertNotSuggested('m');
+ assertNotSuggested('_n');
+ assertNotSuggested('a');
+ assertNotSuggested('A');
+ assertNotSuggested('X');
+ assertNotSuggested('w');
+ assertNotSuggested('Object');
+ assertNotSuggested('==');
+ }
+
+ test_PrefixedIdentifier_class_imported() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ class I {X get f => new A();get _g => new A();}
+ class A implements I {
+ static const int sc = 12;
+ @deprecated var b; X _c;
+ X get d => new A();get _e => new A();
+ set s1(I x) {} set _s2(I x) {}
+ m(X x) {} I _n(X x) {}}
+ class X{}''');
+ addTestSource('''
+ import "/testB.dart";
+ main() {A a; a.^}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('sc');
+ assertSuggestField('b', null, isDeprecated: true);
+ assertNotSuggested('_c');
+ assertSuggestGetter('d', 'X');
+ assertNotSuggested('_e');
+ assertSuggestGetter('f', 'X');
+ assertNotSuggested('_g');
+ assertSuggestSetter('s1');
+ assertNotSuggested('_s2');
+ assertSuggestMethod('m', 'A', null);
+ assertNotSuggested('_n');
+ assertNotSuggested('a');
+ assertNotSuggested('A');
+ assertNotSuggested('X');
+ assertNotSuggested('Object');
+ assertNotSuggested('==');
+ }
+
+ test_PrefixedIdentifier_class_local() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('''
+ main() {A a; a.^}
+ class I {X get f => new A();get _g => new A();}
+ class A implements I {
+ static const int sc = 12;
+ var b; X _c;
+ X get d => new A();get _e => new A();
+ set s1(I x) {} set _s2(I x) {}
+ m(X x) {} I _n(X x) {}}
+ class X{}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('sc');
+ assertSuggestField('b', null);
+ assertSuggestField('_c', 'X');
+ assertSuggestGetter('d', 'X');
+ assertSuggestGetter('_e', null);
+ assertSuggestGetter('f', 'X');
+ assertSuggestGetter('_g', null);
+ assertSuggestSetter('s1');
+ assertSuggestSetter('_s2');
+ assertSuggestMethod('m', 'A', null);
+ assertSuggestMethod('_n', 'A', 'I');
+ assertNotSuggested('a');
+ assertNotSuggested('A');
+ assertNotSuggested('X');
+ assertNotSuggested('Object');
+ assertNotSuggested('==');
+ }
+
+ test_PrefixedIdentifier_getter() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('String get g => "one"; f() {g.^}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_PrefixedIdentifier_library() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ var T1;
+ class X { }
+ class Y { }''');
+ addTestSource('''
+ import "/testB.dart" as b;
+ var T2;
+ class A { }
+ main() {b.^}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ // Suggested by LibraryMemberContributor
+ assertNotSuggested('X');
+ assertNotSuggested('Y');
+ assertNotSuggested('T1');
+ assertNotSuggested('T2');
+ assertNotSuggested('Object');
+ assertNotSuggested('b');
+ assertNotSuggested('A');
+ assertNotSuggested('==');
+ }
+
+ test_PrefixedIdentifier_library_typesOnly() async {
+ // SimpleIdentifier PrefixedIdentifier TypeName
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ var T1;
+ class X { }
+ class Y { }''');
+ addTestSource('''
+ import "/testB.dart" as b;
+ var T2;
+ class A { }
+ foo(b.^ f) {}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ // Suggested by LibraryMemberContributor
+ assertNotSuggested('X');
+ assertNotSuggested('Y');
+ assertNotSuggested('T1');
+ assertNotSuggested('T2');
+ assertNotSuggested('Object');
+ assertNotSuggested('b');
+ assertNotSuggested('A');
+ assertNotSuggested('==');
+ }
+
+ test_PrefixedIdentifier_library_typesOnly2() async {
+ // SimpleIdentifier PrefixedIdentifier TypeName
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ var T1;
+ class X { }
+ class Y { }''');
+ addTestSource('''
+ import "/testB.dart" as b;
+ var T2;
+ class A { }
+ foo(b.^) {}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ // Suggested by LibraryMemberContributor
+ assertNotSuggested('X');
+ assertNotSuggested('Y');
+ assertNotSuggested('T1');
+ assertNotSuggested('T2');
+ assertNotSuggested('Object');
+ assertNotSuggested('b');
+ assertNotSuggested('A');
+ assertNotSuggested('==');
+ }
+
+ test_PrefixedIdentifier_parameter() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ class _W {M y; var _z;}
+ class X extends _W {}
+ class M{}''');
+ addTestSource('''
+ import "/testB.dart";
+ foo(X x) {x.^}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestField('y', 'M');
+ assertNotSuggested('_z');
+ assertNotSuggested('==');
+ }
+
+ test_PrefixedIdentifier_prefix() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addSource(
+ '/testA.dart',
+ '''
+ class A {static int bar = 10;}
+ _B() {}''');
+ addTestSource('''
+ import "/testA.dart";
+ class X {foo(){A^.bar}}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+ assertNotSuggested('A');
+ assertNotSuggested('X');
+ assertNotSuggested('foo');
+ assertNotSuggested('bar');
+ assertNotSuggested('_B');
+ }
+
+ test_PrefixedIdentifier_propertyAccess() async {
+ // PrefixedIdentifier ExpressionStatement Block BlockFunctionBody
+ addTestSource('class A {String x; int get foo {x.^}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestGetter('isEmpty', 'bool');
+ assertSuggestMethod('compareTo', 'Comparable', 'int');
+ }
+
+ test_PrefixedIdentifier_propertyAccess_newStmt() async {
+ // PrefixedIdentifier ExpressionStatement Block BlockFunctionBody
+ addTestSource('class A {String x; int get foo {x.^ int y = 0;}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestGetter('isEmpty', 'bool');
+ assertSuggestMethod('compareTo', 'Comparable', 'int');
+ }
+
+ test_PrefixedIdentifier_trailingStmt_const() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('const String g = "hello"; f() {g.^ int y = 0;}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_PrefixedIdentifier_trailingStmt_field() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('class A {String g; f() {g.^ int y = 0;}}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_PrefixedIdentifier_trailingStmt_function() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('String g() => "one"; f() {g.^ int y = 0;}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_PrefixedIdentifier_trailingStmt_functionTypeAlias() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('typedef String g(); f() {g.^ int y = 0;}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_PrefixedIdentifier_trailingStmt_getter() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('String get g => "one"; f() {g.^ int y = 0;}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_PrefixedIdentifier_trailingStmt_local_typed() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('f() {String g; g.^ int y = 0;}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_PrefixedIdentifier_trailingStmt_local_untyped() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('f() {var g = "hello"; g.^ int y = 0;}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_PrefixedIdentifier_trailingStmt_method() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('class A {String g() {}; f() {g.^ int y = 0;}}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_PrefixedIdentifier_trailingStmt_param() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('class A {f(String g) {g.^ int y = 0;}}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_localVariableDeclarationName() async {
+ addTestSource('main() {String m^}');
+ await computeSuggestions();
+ assertNotSuggested('main');
+ assertNotSuggested('min');
+ }
+
+ test_PrefixedIdentifier_trailingStmt_param2() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('f(String g) {g.^ int y = 0;}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_PrefixedIdentifier_trailingStmt_topLevelVar() async {
+ // SimpleIdentifier PrefixedIdentifier ExpressionStatement
+ addTestSource('String g; f() {g.^ int y = 0;}');
+ await computeSuggestions();
+ assertSuggestGetter('length', 'int');
+ }
+
+ test_PropertyAccess_expression() async {
+ // SimpleIdentifier MethodInvocation PropertyAccess ExpressionStatement
+ addTestSource('class A {a() {"hello".to^String().length}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 2);
+ expect(replacementLength, 8);
+ assertSuggestGetter('length', 'int');
+ assertNotSuggested('A');
+ assertNotSuggested('a');
+ assertNotSuggested('Object');
+ assertNotSuggested('==');
+ }
+
+ test_PropertyAccess_noTarget() async {
+ // SimpleIdentifier PropertyAccess ExpressionStatement
+ addSource('/testAB.dart', 'class Foo { }');
+ addTestSource('class C {foo(){.^}}');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_PropertyAccess_noTarget2() async {
+ // SimpleIdentifier PropertyAccess ExpressionStatement
+ addSource('/testAB.dart', 'class Foo { }');
+ addTestSource('main() {.^}');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_PropertyAccess_selector() async {
+ // SimpleIdentifier PropertyAccess ExpressionStatement Block
+ addTestSource('class A {a() {"hello".length.^}}');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestGetter('isEven', 'bool');
+ assertNotSuggested('A');
+ assertNotSuggested('a');
+ assertNotSuggested('Object');
+ assertNotSuggested('==');
+ }
+
+ test_SwitchStatement_c() async {
+ // SwitchStatement Block BlockFunctionBody MethodDeclaration
+ addTestSource('class A {String g(int x) {switch(x) {c^}}}');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_SwitchStatement_case() async {
+ // SwitchStatement Block BlockFunctionBody MethodDeclaration
+ addTestSource('class A {String g(int x) {var t; switch(x) {case 0: ^}}}');
+ await computeSuggestions();
+ assertNotSuggested('A');
+ assertNotSuggested('g');
+ assertNotSuggested('t');
+ assertNotSuggested('String');
+ }
+
+ test_SwitchStatement_empty() async {
+ // SwitchStatement Block BlockFunctionBody MethodDeclaration
+ addTestSource('class A {String g(int x) {switch(x) {^}}}');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_ThisExpression_block() async {
+ // MethodInvocation ExpressionStatement Block
+ addTestSource('''
+ main() { }
+ class I {X get f => new A();get _g => new A();}
+ class A implements I {
+ A() {}
+ A.z() {}
+ var b; X _c;
+ X get d => new A();get _e => new A();
+ // no semicolon between completion point and next statement
+ set s1(I x) {} set _s2(I x) {this.^ m(null);}
+ m(X x) {} I _n(X x) {}}
+ class X{}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestField('b', null);
+ assertSuggestField('_c', 'X');
+ assertSuggestGetter('d', 'X');
+ assertSuggestGetter('_e', null);
+ assertSuggestGetter('f', 'X');
+ assertSuggestGetter('_g', null);
+ assertSuggestMethod('m', 'A', null);
+ assertSuggestMethod('_n', 'A', 'I');
+ assertSuggestSetter('s1');
+ assertSuggestSetter('_s2');
+ assertNotSuggested('z');
+ assertNotSuggested('I');
+ assertNotSuggested('A');
+ assertNotSuggested('X');
+ assertNotSuggested('Object');
+ assertNotSuggested('==');
+ }
+
+ test_ThisExpression_constructor() async {
+ // MethodInvocation ExpressionStatement Block
+ addTestSource('''
+ main() { }
+ class I {X get f => new A();get _g => new A();}
+ class A implements I {
+ A() {this.^}
+ A.z() {}
+ var b; X _c;
+ X get d => new A();get _e => new A();
+ // no semicolon between completion point and next statement
+ set s1(I x) {} set _s2(I x) {m(null);}
+ m(X x) {} I _n(X x) {}}
+ class X{}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestField('b', null);
+ assertSuggestField('_c', 'X');
+ assertSuggestGetter('d', 'X');
+ assertSuggestGetter('_e', null);
+ assertSuggestGetter('f', 'X');
+ assertSuggestGetter('_g', null);
+ assertSuggestMethod('m', 'A', null);
+ assertSuggestMethod('_n', 'A', 'I');
+ assertSuggestSetter('s1');
+ assertSuggestSetter('_s2');
+ assertNotSuggested('z');
+ assertNotSuggested('I');
+ assertNotSuggested('A');
+ assertNotSuggested('X');
+ assertNotSuggested('Object');
+ assertNotSuggested('==');
+ }
+
+ test_ThisExpression_constructor_param() async {
+ // SimpleIdentifier FieldFormalParameter FormalParameterList
+ addTestSource('''
+ main() { }
+ class I {X get f => new A();get _g => new A();}
+ class A implements I {
+ A(this.^) {}
+ A.z() {}
+ var b; X _c; static sb;
+ X get d => new A();get _e => new A();
+ // no semicolon between completion point and next statement
+ set s1(I x) {} set _s2(I x) {m(null);}
+ m(X x) {} I _n(X x) {}}
+ class X{}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ // Contributed by FieldFormalConstructorContributor
+ assertNotSuggested('b');
+ assertNotSuggested('_c');
+ assertNotSuggested('sb');
+ assertNotSuggested('d');
+ assertNotSuggested('_e');
+ assertNotSuggested('f');
+ assertNotSuggested('_g');
+ assertNotSuggested('m');
+ assertNotSuggested('_n');
+ assertNotSuggested('s1');
+ assertNotSuggested('_s2');
+ assertNotSuggested('z');
+ assertNotSuggested('I');
+ assertNotSuggested('A');
+ assertNotSuggested('X');
+ assertNotSuggested('Object');
+ assertNotSuggested('==');
+ }
+
+ test_ThisExpression_constructor_param2() async {
+ // SimpleIdentifier FieldFormalParameter FormalParameterList
+ addTestSource('''
+ main() { }
+ class I {X get f => new A();get _g => new A();}
+ class A implements I {
+ A(this.b^) {}
+ A.z() {}
+ var b; X _c;
+ X get d => new A();get _e => new A();
+ // no semicolon between completion point and next statement
+ set s1(I x) {} set _s2(I x) {m(null);}
+ m(X x) {} I _n(X x) {}}
+ class X{}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+ // Contributed by FieldFormalConstructorContributor
+ assertNotSuggested('b');
+ assertNotSuggested('_c');
+ assertNotSuggested('d');
+ assertNotSuggested('_e');
+ assertNotSuggested('f');
+ assertNotSuggested('_g');
+ assertNotSuggested('m');
+ assertNotSuggested('_n');
+ assertNotSuggested('s1');
+ assertNotSuggested('_s2');
+ assertNotSuggested('z');
+ assertNotSuggested('I');
+ assertNotSuggested('A');
+ assertNotSuggested('X');
+ assertNotSuggested('Object');
+ assertNotSuggested('==');
+ }
+
+ test_ThisExpression_constructor_param3() async {
+ // SimpleIdentifier FieldFormalParameter FormalParameterList
+ addTestSource('''
+ main() { }
+ class I {X get f => new A();get _g => new A();}
+ class A implements I {
+ A(this.^b) {}
+ A.z() {}
+ var b; X _c;
+ X get d => new A();get _e => new A();
+ // no semicolon between completion point and next statement
+ set s1(I x) {} set _s2(I x) {m(null);}
+ m(X x) {} I _n(X x) {}}
+ class X{}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 1);
+ // Contributed by FieldFormalConstructorContributor
+ assertNotSuggested('b');
+ assertNotSuggested('_c');
+ assertNotSuggested('d');
+ assertNotSuggested('_e');
+ assertNotSuggested('f');
+ assertNotSuggested('_g');
+ assertNotSuggested('m');
+ assertNotSuggested('_n');
+ assertNotSuggested('s1');
+ assertNotSuggested('_s2');
+ assertNotSuggested('z');
+ assertNotSuggested('I');
+ assertNotSuggested('A');
+ assertNotSuggested('X');
+ assertNotSuggested('Object');
+ assertNotSuggested('==');
+ }
+
+ test_ThisExpression_constructor_param4() async {
+ // SimpleIdentifier FieldFormalParameter FormalParameterList
+ addTestSource('''
+ main() { }
+ class I {X get f => new A();get _g => new A();}
+ class A implements I {
+ A(this.b, this.^) {}
+ A.z() {}
+ var b; X _c;
+ X get d => new A();get _e => new A();
+ // no semicolon between completion point and next statement
+ set s1(I x) {} set _s2(I x) {m(null);}
+ m(X x) {} I _n(X x) {}}
+ class X{}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('b');
+ // Contributed by FieldFormalConstructorContributor
+ assertNotSuggested('_c');
+ assertNotSuggested('d');
+ assertNotSuggested('_e');
+ assertNotSuggested('f');
+ assertNotSuggested('_g');
+ assertNotSuggested('m');
+ assertNotSuggested('_n');
+ assertNotSuggested('s1');
+ assertNotSuggested('_s2');
+ assertNotSuggested('z');
+ assertNotSuggested('I');
+ assertNotSuggested('A');
+ assertNotSuggested('X');
+ assertNotSuggested('Object');
+ assertNotSuggested('==');
+ }
+
+ test_TopLevelVariableDeclaration_typed_name() async {
+ // SimpleIdentifier VariableDeclaration VariableDeclarationList
+ // TopLevelVariableDeclaration
+ addTestSource('class A {} B ^');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_TopLevelVariableDeclaration_untyped_name() async {
+ // SimpleIdentifier VariableDeclaration VariableDeclarationList
+ // TopLevelVariableDeclaration
+ addTestSource('class A {} var ^');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_TypeArgumentList() async {
+ // SimpleIdentifier BinaryExpression ExpressionStatement
+ addSource(
+ '/testA.dart',
+ '''
+ class C1 {int x;}
+ F1() => 0;
+ typedef String T1(int blat);''');
+ addTestSource('''
+ import "/testA.dart";'
+ class C2 {int x;}
+ F2() => 0;
+ typedef int T2(int blat);
+ class C<E> {}
+ main() { C<^> c; }''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('Object');
+ assertNotSuggested('C1');
+ assertNotSuggested('T1');
+ assertNotSuggested('C2');
+ assertNotSuggested('T2');
+ assertNotSuggested('F1');
+ assertNotSuggested('F2');
+ }
+
+ test_TypeArgumentList2() async {
+ // TypeName TypeArgumentList TypeName
+ addSource(
+ '/testA.dart',
+ '''
+ class C1 {int x;}
+ F1() => 0;
+ typedef String T1(int blat);''');
+ addTestSource('''
+ import "/testA.dart";'
+ class C2 {int x;}
+ F2() => 0;
+ typedef int T2(int blat);
+ class C<E> {}
+ main() { C<C^> c; }''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 1);
+ expect(replacementLength, 1);
+ assertNotSuggested('C1');
+ assertNotSuggested('C2');
+ }
+
+ test_VariableDeclaration_name() async {
+ // SimpleIdentifier VariableDeclaration VariableDeclarationList
+ // VariableDeclarationStatement Block
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ foo() { }
+ class _B { }
+ class X {X.c(); X._d(); z() {}}''');
+ addTestSource('''
+ import "/testB.dart";
+ class Y {Y.c(); Y._d(); z() {}}
+ main() {var ^}''');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_VariableDeclarationList_final() async {
+ // VariableDeclarationList VariableDeclarationStatement Block
+ addTestSource('main() {final ^} class C { }');
+ await computeSuggestions();
+ assertNotSuggested('Object');
+ assertNotSuggested('C');
+ assertNotSuggested('==');
+ }
+
+ test_VariableDeclarationStatement_RHS() async {
+ // SimpleIdentifier VariableDeclaration VariableDeclarationList
+ // VariableDeclarationStatement
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ foo() { }
+ class _B { }
+ class X {X.c(); X._d(); z() {}}''');
+ addTestSource('''
+ import "/testB.dart";
+ class Y {Y.c(); Y._d(); z() {}}
+ class C {bar(){var f; {var x;} var e = ^}}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('X');
+ assertNotSuggested('_B');
+ assertNotSuggested('Y');
+ assertNotSuggested('C');
+ assertNotSuggested('f');
+ assertNotSuggested('x');
+ assertNotSuggested('e');
+ }
+
+ test_VariableDeclarationStatement_RHS_missing_semicolon() async {
+ // VariableDeclaration VariableDeclarationList
+ // VariableDeclarationStatement
+ addSource(
+ '/testB.dart',
+ '''
+ lib B;
+ foo1() { }
+ void bar1() { }
+ class _B { }
+ class X {X.c(); X._d(); z() {}}''');
+ addTestSource('''
+ import "/testB.dart";
+ foo2() { }
+ void bar2() { }
+ class Y {Y.c(); Y._d(); z() {}}
+ class C {bar(){var f; {var x;} var e = ^ var g}}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('X');
+ assertNotSuggested('foo1');
+ assertNotSuggested('bar1');
+ assertNotSuggested('foo2');
+ assertNotSuggested('bar2');
+ assertNotSuggested('_B');
+ assertNotSuggested('Y');
+ assertNotSuggested('C');
+ assertNotSuggested('f');
+ assertNotSuggested('x');
+ assertNotSuggested('e');
+ }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
index e6c2384..f120744 100644
--- a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
@@ -173,11 +173,32 @@
assertNotSuggested('../blat.dart');
}
+ test_import_file_outside_lib() async {
+ testFile = '/proj/lib/completion.dart';
+ addSource('/proj/lib/other.dart', 'library other;');
+ addSource('/proj/lib/foo/bar.dart', 'library bar;');
+ addSource('/proj/blat.dart', 'library blat;');
+ addSource('/proj/bin/boo.dart', 'library boo;');
+ addTestSource('import "../^" import');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 3);
+ expect(replacementLength, 3);
+ assertNotSuggested('completion.dart');
+ assertNotSuggested('other.dart');
+ assertNotSuggested('foo');
+ assertNotSuggested('foo/');
+ assertNotSuggested('foo/bar.dart');
+ assertNotSuggested('../bin');
+ assertNotSuggested('../bin/');
+ assertNotSuggested('../blat.dart');
+ }
+
test_import_file_parent() async {
testFile = '/proj/completion.dart';
addSource('/proj/other.dart', 'library other;');
addSource('/proj/foo/bar.dart', 'library bar;');
addSource('/blat.dart', 'library blat;');
+ addSource('/proj2/boo.dart', 'library boo;');
addTestSource('import "../^" import');
await computeSuggestions();
expect(replacementOffset, completionOffset - 3);
@@ -188,6 +209,7 @@
assertNotSuggested('foo/');
assertNotSuggested('foo/bar.dart');
assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT);
+ assertSuggest('../proj2/', csKind: CompletionSuggestionKind.IMPORT);
}
test_import_file_parent2() async {
diff --git a/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart
index 54ad5e1..fb91d76 100644
--- a/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart
@@ -4,8 +4,6 @@
library test.services.completion.toplevel;
-import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
- show Element, ElementKind;
import 'package:analysis_server/plugin/protocol/protocol.dart'
hide Element, ElementKind;
import 'package:analysis_server/src/services/completion/dart_completion_cache.dart';
@@ -33,7 +31,6 @@
DartCompletionCache cache = request.cache;
if (!isCached(cache.importedTypeSuggestions, completion) &&
!isCached(cache.importedVoidReturnSuggestions, completion) &&
- !isCached(cache.libraryPrefixSuggestions, completion) &&
!isCached(cache.otherImportedSuggestions, completion)) {
fail('expected $completion to be cached');
}
@@ -116,7 +113,6 @@
DartCompletionCache cache = request.cache;
if (isCached(cache.importedTypeSuggestions, completion) ||
isCached(cache.importedVoidReturnSuggestions, completion) ||
- isCached(cache.libraryPrefixSuggestions, completion) ||
isCached(cache.otherImportedSuggestions, completion)) {
fail('expected $completion NOT to be cached');
}
@@ -203,21 +199,6 @@
name, returnType, relevance, kind, importUri);
}
- @override
- CompletionSuggestion assertSuggestLibraryPrefix(String prefix,
- [int relevance = DART_RELEVANCE_DEFAULT,
- CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
- CompletionSuggestion cs =
- assertSuggest(prefix, csKind: kind, relevance: relevance);
- protocol.Element element = cs.element;
- expect(element, isNotNull);
- expect(element.kind, equals(protocol.ElementKind.LIBRARY));
- expect(element.parameters, isNull);
- expect(element.returnType, isNull);
- assertHasNoParameterInfo(cs);
- return cs;
- }
-
fail_enum_deprecated() {
addSource('/libA.dart', 'library A; @deprecated enum E { one, two }');
addTestSource('import "/libA.dart"; main() {^}');
@@ -257,6 +238,13 @@
});
}
+ test_Assert() {
+ addTestSource('main() {assert(^)}');
+ return computeFull((bool result) {
+ assertSuggestClass('String');
+ });
+ }
+
@override
test_AssignmentExpression_RHS() {
return super.test_AssignmentExpression_RHS().then((_) {
@@ -545,7 +533,8 @@
expect(suggestion.requiredParameterCount, 0);
expect(suggestion.hasNamedParameters, true);
- assertSuggestLibraryPrefix('math');
+ // Suggested by LibraryPrefixContributor
+ assertNotSuggested('math');
});
}
diff --git a/pkg/analysis_server/test/services/completion/optype_test.dart b/pkg/analysis_server/test/services/completion/optype_test.dart
index 94b5daf..179b09b 100644
--- a/pkg/analysis_server/test/services/completion/optype_test.dart
+++ b/pkg/analysis_server/test/services/completion/optype_test.dart
@@ -9,6 +9,7 @@
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:plugin/manager.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
@@ -67,6 +68,15 @@
expect(visitor.isPrefixed, prefixed, reason: 'prefixed');
}
+ void processRequiredPlugins() {
+ ExtensionManager manager = new ExtensionManager();
+ manager.processPlugins(AnalysisEngine.instance.requiredPlugins);
+ }
+
+ void setUp() {
+ processRequiredPlugins();
+ }
+
test_Annotation() {
// SimpleIdentifier Annotation MethodDeclaration ClassDeclaration
addTestSource('class C { @A^ }');
@@ -98,6 +108,11 @@
assertOpType(typeNames: true);
}
+ test_Assert() {
+ addTestSource('main() {assert(^)}');
+ assertOpType(returnValue: true, typeNames: true);
+ }
+
test_AssignmentExpression_name() {
// SimpleIdentifier VariableDeclaration VariableDeclarationList
// VariableDeclarationStatement Block
diff --git a/pkg/analysis_server/test/services/completion/prefixed_element_contributor_test.dart b/pkg/analysis_server/test/services/completion/prefixed_element_contributor_test.dart
deleted file mode 100644
index 6e15a0c..0000000
--- a/pkg/analysis_server/test/services/completion/prefixed_element_contributor_test.dart
+++ /dev/null
@@ -1,675 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.services.completion.invocation;
-
-import 'dart:async';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/prefixed_element_contributor.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
-import 'completion_test_util.dart';
-
-main() {
- initializeTestEnvironment();
- defineReflectiveTests(PrefixedElementContributorTest);
-}
-
-@reflectiveTest
-class PrefixedElementContributorTest extends AbstractSelectorSuggestionTest {
- @override
- CompletionSuggestion assertSuggestInvocationField(String name, String type,
- {int relevance: DART_RELEVANCE_DEFAULT, bool isDeprecated: false}) {
- return assertSuggestField(name, type,
- relevance: relevance, isDeprecated: isDeprecated);
- }
-
- /**
- * Check whether a declaration of the form [shadower] in a derived class
- * shadows a declaration of the form [shadowee] in a base class, for the
- * purposes of what is shown during completion. [shouldBeShadowed] indicates
- * whether shadowing is expected.
- */
- Future check_shadowing(
- String shadower, String shadowee, bool shouldBeShadowed) {
- addTestSource('''
-class Base {
- $shadowee
-}
-class Derived extends Base {
- $shadower
-}
-void f(Derived d) {
- d.^
-}
-''');
- return computeFull((bool result) {
- List<CompletionSuggestion> suggestionsForX = request.suggestions
- .where((CompletionSuggestion s) => s.completion == 'x')
- .toList();
- if (shouldBeShadowed) {
- expect(suggestionsForX, hasLength(1));
- expect(suggestionsForX[0].declaringType, 'Derived');
- } else {
- expect(suggestionsForX, hasLength(2));
- }
- });
- }
-
- fail_enumConst_deprecated() {
- addTestSource('@deprecated enum E { one, two } main() {E.^}');
- return computeFull((bool result) {
- assertNotSuggested('E');
- // TODO(danrubel) Investigate why enum suggestion is not marked
- // as deprecated if enum ast element is deprecated
- assertSuggestEnumConst('one', isDeprecated: true);
- assertSuggestEnumConst('two', isDeprecated: true);
- assertNotSuggested('index');
- assertSuggestField('values', 'List<E>', isDeprecated: true);
- });
- }
-
- fail_test_PrefixedIdentifier_trailingStmt_const_untyped() {
- // SimpleIdentifier PrefixedIdentifier ExpressionStatement
- addTestSource('const g = "hello"; f() {g.^ int y = 0;}');
- computeFast();
- return computeFull((bool result) {
- assertSuggestInvocationGetter('length', 'int');
- });
- }
-
- @override
- void setUpContributor() {
- contributor = new PrefixedElementContributor();
- }
-
- test_enumConst() {
- addTestSource('enum E { one, two } main() {E.^}');
- return computeFull((bool result) {
- assertNotSuggested('E');
- assertSuggestEnumConst('one');
- assertSuggestEnumConst('two');
- assertNotSuggested('index');
- assertSuggestField('values', 'List<E>');
- });
- }
-
- test_enumConst2() {
- addTestSource('enum E { one, two } main() {E.o^}');
- return computeFull((bool result) {
- assertNotSuggested('E');
- assertSuggestEnumConst('one');
- assertSuggestEnumConst('two');
- assertNotSuggested('index');
- assertSuggestField('values', 'List<E>');
- });
- }
-
- test_enumConst3() {
- addTestSource('enum E { one, two } main() {E.^ int g;}');
- return computeFull((bool result) {
- assertNotSuggested('E');
- assertSuggestEnumConst('one');
- assertSuggestEnumConst('two');
- assertNotSuggested('index');
- assertSuggestField('values', 'List<E>');
- });
- }
-
- test_enumConst_index() {
- addTestSource('enum E { one, two } main() {E.one.^}');
- return computeFull((bool result) {
- assertNotSuggested('E');
- assertNotSuggested('one');
- assertNotSuggested('two');
- assertSuggestField('index', 'int');
- assertNotSuggested('values');
- });
- }
-
- test_enumConst_index2() {
- addTestSource('enum E { one, two } main() {E.one.i^}');
- return computeFull((bool result) {
- assertNotSuggested('E');
- assertNotSuggested('one');
- assertNotSuggested('two');
- assertSuggestField('index', 'int');
- assertNotSuggested('values');
- });
- }
-
- test_enumConst_index3() {
- addTestSource('enum E { one, two } main() {E.one.^ int g;}');
- return computeFull((bool result) {
- assertNotSuggested('E');
- assertNotSuggested('one');
- assertNotSuggested('two');
- assertSuggestField('index', 'int');
- assertNotSuggested('values');
- });
- }
-
- test_generic_field() {
- addTestSource('''
-class C<T> {
- T t;
-}
-void f(C<int> c) {
- c.^
-}
-''');
- return computeFull((bool result) {
- assertSuggestField('t', 'int');
- });
- }
-
- test_generic_getter() {
- addTestSource('''
-class C<T> {
- T get t => null;
-}
-void f(C<int> c) {
- c.^
-}
-''');
- return computeFull((bool result) {
- assertSuggestGetter('t', 'int');
- });
- }
-
- test_generic_method() {
- addTestSource('''
-class C<T> {
- T m(T t) {}
-}
-void f(C<int> c) {
- c.^
-}
-''');
- return computeFull((bool result) {
- CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'int');
- expect(suggestion.parameterTypes[0], 'int');
- expect(suggestion.element.returnType, 'int');
- expect(suggestion.element.parameters, '(int t)');
- });
- }
-
- test_generic_setter() {
- addTestSource('''
-class C<T> {
- set t(T value) {}
-}
-void f(C<int> c) {
- c.^
-}
-''');
- return computeFull((bool result) {
- // TODO(paulberry): modify assertSuggestSetter so that we can pass 'int'
- // as a parmeter to it, and it will check the appropriate field in
- // the suggestion object.
- CompletionSuggestion suggestion = assertSuggestSetter('t');
- expect(suggestion.element.parameters, '(int value)');
- });
- }
-
- test_keyword() {
- addTestSource('class C { static C get instance => null; } main() {C.in^}');
- return computeFull((bool result) {
- assertSuggestGetter('instance', 'C');
- });
- }
-
- test_libraryPrefix() {
- // SimpleIdentifier PrefixedIdentifier ExpressionStatement
- addTestSource('import "dart:async" as bar; foo() {bar.^}');
- return computeFull((bool result) {
- assertSuggestClass('Future');
- assertNotSuggested('loadLibrary');
- });
- }
-
- test_libraryPrefix2() {
- // SimpleIdentifier MethodInvocation ExpressionStatement
- addTestSource('import "dart:async" as bar; foo() {bar.^ print("f")}');
- return computeFull((bool result) {
- assertSuggestClass('Future');
- });
- }
-
- test_libraryPrefix3() {
- // SimpleIdentifier MethodInvocation ExpressionStatement
- addTestSource('import "dart:async" as bar; foo() {new bar.F^ print("f")}');
- return computeFull((bool result) {
- assertSuggestConstructor('Future');
- assertSuggestConstructor('Future.delayed');
- });
- }
-
- test_libraryPrefix_deferred() {
- // SimpleIdentifier PrefixedIdentifier ExpressionStatement
- addTestSource('import "dart:async" deferred as bar; foo() {bar.^}');
- return computeFull((bool result) {
- assertSuggestClass('Future');
- assertSuggestFunction('loadLibrary', 'Future<dynamic>');
- });
- }
-
- test_libraryPrefix_with_exports() {
- addSource('/libA.dart', 'library libA; class A { }');
- addSource('/libB.dart', 'library libB; export "/libA.dart"; class B { }');
- addTestSource('import "/libB.dart" as foo; main() {foo.^} class C { }');
- computeFast();
- return computeFull((bool result) {
- assertSuggestClass('B');
- assertSuggestClass('A');
- });
- }
-
- test_local() {
- addTestSource('foo() {String x = "bar"; x.^}');
- return computeFull((bool result) {
- assertSuggestGetter('length', 'int');
- });
- }
-
- test_local_is() {
- addTestSource('foo() {var x; if (x is String) x.^}');
- return computeFull((bool result) {
- assertSuggestGetter('length', 'int');
- });
- }
-
- test_local_propogatedType() {
- addTestSource('foo() {var x = "bar"; x.^}');
- return computeFull((bool result) {
- assertSuggestGetter('length', 'int');
- });
- }
-
- test_method_parameters_mixed_required_and_named() {
- addTestSource('''
-class C {
- void m(x, {int y}) {}
-}
-void main() {new C().^}''');
- return computeFull((bool result) {
- CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'x');
- expect(suggestion.parameterTypes[0], 'dynamic');
- expect(suggestion.parameterNames[1], 'y');
- expect(suggestion.parameterTypes[1], 'int');
- expect(suggestion.requiredParameterCount, 1);
- expect(suggestion.hasNamedParameters, true);
- });
- }
-
- test_method_parameters_mixed_required_and_positional() {
- addTestSource('''
-class C {
- void m(x, [int y]) {}
-}
-void main() {new C().^}''');
- return computeFull((bool result) {
- CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'x');
- expect(suggestion.parameterTypes[0], 'dynamic');
- expect(suggestion.parameterNames[1], 'y');
- expect(suggestion.parameterTypes[1], 'int');
- expect(suggestion.requiredParameterCount, 1);
- expect(suggestion.hasNamedParameters, false);
- });
- }
-
- test_method_parameters_named() {
- addTestSource('''
-class C {
- void m({x, int y}) {}
-}
-void main() {new C().^}''');
- return computeFull((bool result) {
- CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'x');
- expect(suggestion.parameterTypes[0], 'dynamic');
- expect(suggestion.parameterNames[1], 'y');
- expect(suggestion.parameterTypes[1], 'int');
- expect(suggestion.requiredParameterCount, 0);
- expect(suggestion.hasNamedParameters, true);
- });
- }
-
- test_method_parameters_none() {
- addTestSource('''
-class C {
- void m() {}
-}
-void main() {new C().^}''');
- computeFast();
- return computeFull((bool result) {
- CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
- expect(suggestion.parameterNames, isEmpty);
- expect(suggestion.parameterTypes, isEmpty);
- expect(suggestion.requiredParameterCount, 0);
- expect(suggestion.hasNamedParameters, false);
- });
- }
-
- test_method_parameters_positional() {
- addTestSource('''
-class C {
- void m([x, int y]) {}
-}
-void main() {new C().^}''');
- return computeFull((bool result) {
- CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'x');
- expect(suggestion.parameterTypes[0], 'dynamic');
- expect(suggestion.parameterNames[1], 'y');
- expect(suggestion.parameterTypes[1], 'int');
- expect(suggestion.requiredParameterCount, 0);
- expect(suggestion.hasNamedParameters, false);
- });
- }
-
- test_method_parameters_required() {
- addTestSource('''
-class C {
- void m(x, int y) {}
-}
-void main() {new C().^}''');
- return computeFull((bool result) {
- CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'x');
- expect(suggestion.parameterTypes[0], 'dynamic');
- expect(suggestion.parameterNames[1], 'y');
- expect(suggestion.parameterTypes[1], 'int');
- expect(suggestion.requiredParameterCount, 2);
- expect(suggestion.hasNamedParameters, false);
- });
- }
-
- test_no_parameters_field() {
- addTestSource('''
-class C {
- int x;
-}
-void main() {new C().^}''');
- return computeFull((bool result) {
- CompletionSuggestion suggestion = assertSuggestField('x', 'int');
- assertHasNoParameterInfo(suggestion);
- });
- }
-
- test_no_parameters_getter() {
- addTestSource('''
-class C {
- int get x => null;
-}
-void main() {int y = new C().^}''');
- return computeFull((bool result) {
- CompletionSuggestion suggestion = assertSuggestGetter('x', 'int');
- assertHasNoParameterInfo(suggestion);
- });
- }
-
- test_no_parameters_setter() {
- addTestSource('''
-class C {
- set x(int value) {};
-}
-void main() {int y = new C().^}''');
- return computeFull((bool result) {
- CompletionSuggestion suggestion = assertSuggestSetter('x');
- assertHasNoParameterInfo(suggestion);
- });
- }
-
- test_only_instance() {
- // SimpleIdentifier PropertyAccess ExpressionStatement
- addTestSource('''
-class C {
- int f1;
- static int f2;
- m1() {}
- static m2() {}
-}
-void main() {new C().^}''');
- return computeFull((bool result) {
- assertSuggestInvocationField('f1', 'int');
- assertNotSuggested('f2');
- assertSuggestMethod('m1', 'C', null);
- assertNotSuggested('m2');
- });
- }
-
- test_only_instance2() {
- // SimpleIdentifier MethodInvocation ExpressionStatement
- addTestSource('''
-class C {
- int f1;
- static int f2;
- m1() {}
- static m2() {}
-}
-void main() {new C().^ print("something");}''');
- return computeFull((bool result) {
- assertSuggestInvocationField('f1', 'int');
- assertNotSuggested('f2');
- assertSuggestMethod('m1', 'C', null);
- assertNotSuggested('m2');
- });
- }
-
- test_only_static() {
- // SimpleIdentifier PrefixedIdentifier ExpressionStatement
- addTestSource('''
-class C {
- int f1;
- static int f2;
- m1() {}
- static m2() {}
-}
-void main() {C.^}''');
- return computeFull((bool result) {
- assertNotSuggested('f1');
- assertSuggestInvocationField('f2', 'int');
- assertNotSuggested('m1');
- assertSuggestMethod('m2', 'C', null);
- });
- }
-
- test_only_static2() {
- // SimpleIdentifier MethodInvocation ExpressionStatement
- addTestSource('''
-class C {
- int f1;
- static int f2;
- m1() {}
- static m2() {}
-}
-void main() {C.^ print("something");}''');
- return computeFull((bool result) {
- assertNotSuggested('f1');
- assertSuggestInvocationField('f2', 'int');
- assertNotSuggested('m1');
- assertSuggestMethod('m2', 'C', null);
- });
- }
-
- test_param() {
- addTestSource('foo(String x) {x.^}');
- return computeFull((bool result) {
- assertSuggestGetter('length', 'int');
- });
- }
-
- test_param_is() {
- addTestSource('foo(x) {if (x is String) x.^}');
- return computeFull((bool result) {
- assertSuggestGetter('length', 'int');
- });
- }
-
- test_shadowing_field_over_field() =>
- check_shadowing('int x;', 'int x;', true);
-
- test_shadowing_field_over_getter() =>
- check_shadowing('int x;', 'int get x => null;', true);
-
- test_shadowing_field_over_method() =>
- check_shadowing('int x;', 'void x() {}', true);
-
- test_shadowing_field_over_setter() =>
- check_shadowing('int x;', 'set x(int value) {}', true);
-
- test_shadowing_getter_over_field() =>
- check_shadowing('int get x => null;', 'int x;', true);
-
- test_shadowing_getter_over_getter() =>
- check_shadowing('int get x => null;', 'int get x => null;', true);
-
- test_shadowing_getter_over_method() =>
- check_shadowing('int get x => null;', 'void x() {}', true);
-
- test_shadowing_getter_over_setter() =>
- check_shadowing('int get x => null;', 'set x(int value) {}', true);
-
- test_shadowing_method_over_field() =>
- check_shadowing('void x() {}', 'int x;', true);
-
- test_shadowing_method_over_getter() =>
- check_shadowing('void x() {}', 'int get x => null;', true);
-
- test_shadowing_method_over_method() =>
- check_shadowing('void x() {}', 'void x() {}', true);
-
- test_shadowing_method_over_setter() =>
- check_shadowing('void x() {}', 'set x(int value) {}', true);
-
- test_shadowing_mixin_order() {
- addTestSource('''
-class Base {
-}
-class Mixin1 {
- void f() {}
-}
-class Mixin2 {
- void f() {}
-}
-class Derived extends Base with Mixin1, Mixin2 {
-}
-void test(Derived d) {
- d.^
-}
-''');
- return computeFull((bool result) {
- // Note: due to dartbug.com/22069, analyzer currently analyzes mixins in
- // reverse order. The correct order is that Derived inherits from
- // "Base with Mixin1, Mixin2", which inherits from "Base with Mixin1",
- // which inherits from "Base". So the definition of f in Mixin2 should
- // shadow the definition in Mixin1.
- assertSuggestMethod('f', 'Mixin2', 'void');
- });
- }
-
- test_shadowing_mixin_over_superclass() {
- addTestSource('''
-class Base {
- void f() {}
-}
-class Mixin {
- void f() {}
-}
-class Derived extends Base with Mixin {
-}
-void test(Derived d) {
- d.^
-}
-''');
- return computeFull((bool result) {
- assertSuggestMethod('f', 'Mixin', 'void');
- });
- }
-
- test_shadowing_setter_over_field() =>
- check_shadowing('set x(int value) {}', 'int x;', true);
-
- test_shadowing_setter_over_getter() =>
- check_shadowing('set x(int value) {}', 'int get x => null;', true);
-
- test_shadowing_setter_over_method() =>
- check_shadowing('set x(int value) {}', 'void x() {}', true);
-
- test_shadowing_setter_over_setter() =>
- check_shadowing('set x(int value) {}', 'set x(int value) {}', true);
-
- test_shadowing_superclass_over_interface() {
- addTestSource('''
-class Base {
- void f() {}
-}
-class Interface {
- void f() {}
-}
-class Derived extends Base implements Interface {
-}
-void test(Derived d) {
- d.^
-}
-''');
- return computeFull((bool result) {
- assertSuggestMethod('f', 'Base', 'void');
- });
- }
-
- test_super() {
- // SimpleIdentifier MethodInvocation ExpressionStatement
- addTestSource('''
-class C3 {
- int fi3;
- static int fs3;
- m() {}
- mi3() {}
- static ms3() {}
-}
-class C2 {
- int fi2;
- static int fs2;
- m() {}
- mi2() {}
- static ms2() {}
-}
-class C1 extends C2 implements C3 {
- int fi1;
- static int fs1;
- m() {super.^}
- mi1() {}
- static ms1() {}
-}''');
- return computeFull((bool result) {
- assertNotSuggested('fi1');
- assertNotSuggested('fs1');
- assertNotSuggested('mi1');
- assertNotSuggested('ms1');
- assertSuggestInvocationField('fi2', 'int');
- assertNotSuggested('fs2');
- assertSuggestInvocationMethod('mi2', 'C2', null);
- assertNotSuggested('ms2');
- assertSuggestInvocationMethod('m', 'C2', null,
- relevance: DART_RELEVANCE_HIGH);
- assertNotSuggested('fi3');
- assertNotSuggested('fs3');
- assertNotSuggested('mi3');
- assertNotSuggested('ms3');
- });
- }
-}
diff --git a/pkg/analysis_server/test/services/completion/test_all.dart b/pkg/analysis_server/test/services/completion/test_all.dart
index c4adeb2..41ddfc9 100644
--- a/pkg/analysis_server/test/services/completion/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/test_all.dart
@@ -16,7 +16,6 @@
import 'local_reference_contributor_test.dart'
as local_reference_contributor_test;
import 'optype_test.dart' as optype_test;
-import 'prefixed_element_contributor_test.dart' as invocation_test;
/// Utility for manually running all tests.
main() {
@@ -27,7 +26,6 @@
completion_target_test.main();
dart_contributor_tests.main();
imported_test.main();
- invocation_test.main();
local_declaration_visitor_test.main();
local_reference_contributor_test.main();
optype_test.main();
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index 48e8068..ed3d7d3 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -10,8 +10,10 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/plugin/server_plugin.dart';
import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
@@ -99,13 +101,21 @@
}).toList();
}
+ void processRequiredPlugins() {
+ plugin = new ServerPlugin();
+
+ List<Plugin> plugins = <Plugin>[];
+ plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+ plugins.add(plugin);
+
+ ExtensionManager manager = new ExtensionManager();
+ manager.processPlugins(plugins);
+ }
+
void setUp() {
super.setUp();
offset = 0;
length = 0;
- ExtensionManager manager = new ExtensionManager();
- plugin = new ServerPlugin();
- manager.processPlugins([plugin]);
}
test_addTypeAnnotation_BAD_privateType_closureParameter() async {
@@ -865,6 +875,32 @@
'AAA', DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK);
}
+ test_convertDocumentationIntoBlock_OK_noSpaceBeforeText() async {
+ resolveTestUnit('''
+class A {
+ /// AAAAA
+ ///BBBBB
+ ///
+ /// CCCCC
+ mmm() {}
+}
+''');
+ await assertHasAssistAt(
+ 'AAAAA',
+ DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK,
+ '''
+class A {
+ /**
+ * AAAAA
+ *BBBBB
+ *
+ * CCCCC
+ */
+ mmm() {}
+}
+''');
+ }
+
test_convertDocumentationIntoBlock_OK_onReference() async {
resolveTestUnit('''
/// AAAAAAA [int] AAAAAAA
diff --git a/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart b/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart
index 9ba6cae..476c4dd 100644
--- a/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart
+++ b/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart
@@ -1781,9 +1781,7 @@
}
}
-class MockIndexStore extends TypedMock implements InternalIndexStore {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockIndexStore extends TypedMock implements InternalIndexStore {}
/**
* Information about a relation recorded into {@link IndexStore}.
diff --git a/pkg/analysis_server/test/services/index/store/mocks.dart b/pkg/analysis_server/test/services/index/store/mocks.dart
index 9ed78af..a197342 100644
--- a/pkg/analysis_server/test/services/index/store/mocks.dart
+++ b/pkg/analysis_server/test/services/index/store/mocks.dart
@@ -8,18 +8,10 @@
import 'package:analysis_server/src/services/index/store/codec.dart';
import 'package:typed_mock/typed_mock.dart';
-class MockContextCodec extends TypedMock implements ContextCodec {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockContextCodec extends TypedMock implements ContextCodec {}
-class MockElementCodec extends TypedMock implements ElementCodec {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockElementCodec extends TypedMock implements ElementCodec {}
-class MockLocation extends TypedMock implements LocationImpl {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockLocation extends TypedMock implements LocationImpl {}
-class MockRelationshipCodec extends TypedMock implements RelationshipCodec {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockRelationshipCodec extends TypedMock implements RelationshipCodec {}
diff --git a/pkg/analysis_server/test/services/index/store/split_store_test.dart b/pkg/analysis_server/test/services/index/store/split_store_test.dart
index 17c7e8b..1ae14d5 100644
--- a/pkg/analysis_server/test/services/index/store/split_store_test.dart
+++ b/pkg/analysis_server/test/services/index/store/split_store_test.dart
@@ -420,13 +420,9 @@
}
}
-class _MockFileManager extends TypedMock implements FileManager {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _MockFileManager extends TypedMock implements FileManager {}
-class _MockIndexNode extends TypedMock implements IndexNode {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _MockIndexNode extends TypedMock implements IndexNode {}
@reflectiveTest
class _RelationKeyDataTest {
diff --git a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
index 46a6e67..cae09e7 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
@@ -5,6 +5,7 @@
library test.services.refactoring.extract_local;
import 'dart:async';
+import 'dart:convert';
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/services/correction/status.dart';
@@ -534,7 +535,7 @@
expect(refactoring.names, unorderedEquals(['helloBob', 'bob']));
}
- test_occurrences_differentVariable() {
+ test_occurrences_differentVariable() async {
indexTestUnit('''
main() {
{
@@ -550,7 +551,7 @@
''');
_createRefactoringWithSuffix('v + 1', '); // marker');
// apply refactoring
- return _assertSuccessfulRefactoring('''
+ await _assertSuccessfulRefactoring('''
main() {
{
int v = 1;
@@ -564,6 +565,8 @@
}
}
''');
+ _assertSingleLinkedEditGroup(
+ length: 3, offsets: [36, 59, 85], names: ['object', 'i']);
}
test_occurrences_disableOccurrences() {
@@ -788,7 +791,7 @@
''');
}
- test_singleExpression_inExpressionBody() {
+ test_singleExpression_inExpressionBody() async {
indexTestUnit('''
main() {
print((x) => x.y * x.y + 1);
@@ -796,7 +799,7 @@
''');
_createRefactoringForString('x.y');
// apply refactoring
- return _assertSuccessfulRefactoring('''
+ await _assertSuccessfulRefactoring('''
main() {
print((x) {
var res = x.y;
@@ -804,6 +807,8 @@
});
}
''');
+ _assertSingleLinkedEditGroup(
+ length: 3, offsets: [31, 53, 59], names: ['y']);
}
test_singleExpression_inIfElseIf() {
@@ -987,7 +992,7 @@
''');
}
- test_stringLiteral_part() {
+ test_stringLiteral_part() async {
indexTestUnit('''
main() {
print('abcdefgh');
@@ -995,15 +1000,16 @@
''');
_createRefactoringForString('cde');
// apply refactoring
- return _assertSuccessfulRefactoring(r'''
+ await _assertSuccessfulRefactoring(r'''
main() {
var res = 'cde';
print('ab${res}fgh');
}
''');
+ _assertSingleLinkedEditGroup(length: 3, offsets: [15, 41], names: ['cde']);
}
- test_stringLiteral_whole() {
+ test_stringLiteral_whole() async {
indexTestUnit('''
main() {
print('abc');
@@ -1011,15 +1017,17 @@
''');
_createRefactoringForString("'abc'");
// apply refactoring
- return _assertSuccessfulRefactoring('''
+ await _assertSuccessfulRefactoring('''
main() {
var res = 'abc';
print(res);
}
''');
+ _assertSingleLinkedEditGroup(
+ length: 3, offsets: [15, 36], names: ['object', 's']);
}
- test_stringLiteralPart() {
+ test_stringLiteralPart() async {
indexTestUnit(r'''
main() {
int x = 1;
@@ -1029,7 +1037,7 @@
''');
_createRefactoringForString(r'$x+$y');
// apply refactoring
- return _assertSuccessfulRefactoring(r'''
+ await _assertSuccessfulRefactoring(r'''
main() {
int x = 1;
int y = 2;
@@ -1037,6 +1045,7 @@
print('${res}=${x+y}');
}
''');
+ _assertSingleLinkedEditGroup(length: 3, offsets: [41, 67], names: ['xy']);
}
Future _assertInitialConditions_fatal_selection() async {
@@ -1046,6 +1055,27 @@
'Expression must be selected to activate this refactoring.');
}
+ void _assertSingleLinkedEditGroup(
+ {int length, List<int> offsets, List<String> names}) {
+ String positionsString = offsets
+ .map((offset) => '{"file": "$testFile", "offset": $offset}')
+ .join(',');
+ String suggestionsString =
+ names.map((name) => '{"value": "$name", "kind": "VARIABLE"}').join(',');
+ _assertSingleLinkedEditGroupJson('''
+{
+ "length": $length,
+ "positions": [$positionsString],
+ "suggestions": [$suggestionsString]
+}''');
+ }
+
+ void _assertSingleLinkedEditGroupJson(String expectedJsonString) {
+ List<LinkedEditGroup> editGroups = refactoringChange.linkedEditGroups;
+ expect(editGroups, hasLength(1));
+ expect(editGroups.first.toJson(), JSON.decode(expectedJsonString));
+ }
+
/**
* Checks that all conditions are OK and the result of applying the
* [SourceChange] to [testUnit] is [expectedCode].
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart
index 1453d46..31d826b 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart
@@ -62,9 +62,7 @@
}
}
-class MockIndex extends TypedMock implements Index {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockIndex extends TypedMock implements Index {}
@reflectiveTest
class SearchEngineImplTest extends AbstractSingleUnitTest {
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java b/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java
index af83c5e..ab4020c 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java
@@ -64,11 +64,6 @@
private final int workItemQueueLength;
/**
- * A rolling average of work items in the queue. (A double encoded as a String.)
- */
- private final String workItemQueueLengthAverage;
-
- /**
* Exceptions associated with cache entries.
*/
private final List<String> cacheEntryExceptions;
@@ -76,12 +71,11 @@
/**
* Constructor for {@link ContextData}.
*/
- public ContextData(String name, int explicitFileCount, int implicitFileCount, int workItemQueueLength, String workItemQueueLengthAverage, List<String> cacheEntryExceptions) {
+ public ContextData(String name, int explicitFileCount, int implicitFileCount, int workItemQueueLength, List<String> cacheEntryExceptions) {
this.name = name;
this.explicitFileCount = explicitFileCount;
this.implicitFileCount = implicitFileCount;
this.workItemQueueLength = workItemQueueLength;
- this.workItemQueueLengthAverage = workItemQueueLengthAverage;
this.cacheEntryExceptions = cacheEntryExceptions;
}
@@ -94,7 +88,6 @@
other.explicitFileCount == explicitFileCount &&
other.implicitFileCount == implicitFileCount &&
other.workItemQueueLength == workItemQueueLength &&
- ObjectUtilities.equals(other.workItemQueueLengthAverage, workItemQueueLengthAverage) &&
ObjectUtilities.equals(other.cacheEntryExceptions, cacheEntryExceptions);
}
return false;
@@ -105,9 +98,8 @@
int explicitFileCount = jsonObject.get("explicitFileCount").getAsInt();
int implicitFileCount = jsonObject.get("implicitFileCount").getAsInt();
int workItemQueueLength = jsonObject.get("workItemQueueLength").getAsInt();
- String workItemQueueLengthAverage = jsonObject.get("workItemQueueLengthAverage").getAsString();
List<String> cacheEntryExceptions = JsonUtilities.decodeStringList(jsonObject.get("cacheEntryExceptions").getAsJsonArray());
- return new ContextData(name, explicitFileCount, implicitFileCount, workItemQueueLength, workItemQueueLengthAverage, cacheEntryExceptions);
+ return new ContextData(name, explicitFileCount, implicitFileCount, workItemQueueLength, cacheEntryExceptions);
}
public static List<ContextData> fromJsonArray(JsonArray jsonArray) {
@@ -157,13 +149,6 @@
return workItemQueueLength;
}
- /**
- * A rolling average of work items in the queue. (A double encoded as a String.)
- */
- public String getWorkItemQueueLengthAverage() {
- return workItemQueueLengthAverage;
- }
-
@Override
public int hashCode() {
HashCodeBuilder builder = new HashCodeBuilder();
@@ -171,7 +156,6 @@
builder.append(explicitFileCount);
builder.append(implicitFileCount);
builder.append(workItemQueueLength);
- builder.append(workItemQueueLengthAverage);
builder.append(cacheEntryExceptions);
return builder.toHashCode();
}
@@ -182,7 +166,6 @@
jsonObject.addProperty("explicitFileCount", explicitFileCount);
jsonObject.addProperty("implicitFileCount", implicitFileCount);
jsonObject.addProperty("workItemQueueLength", workItemQueueLength);
- jsonObject.addProperty("workItemQueueLengthAverage", workItemQueueLengthAverage);
JsonArray jsonArrayCacheEntryExceptions = new JsonArray();
for (String elt : cacheEntryExceptions) {
jsonArrayCacheEntryExceptions.add(new JsonPrimitive(elt));
@@ -203,8 +186,6 @@
builder.append(implicitFileCount + ", ");
builder.append("workItemQueueLength=");
builder.append(workItemQueueLength + ", ");
- builder.append("workItemQueueLengthAverage=");
- builder.append(workItemQueueLengthAverage + ", ");
builder.append("cacheEntryExceptions=");
builder.append(StringUtils.join(cacheEntryExceptions, ", "));
builder.append("]");
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java b/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
index a5e439f..346bf63 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
@@ -76,6 +76,11 @@
public static final String INVALID_EXECUTION_CONTEXT = "INVALID_EXECUTION_CONTEXT";
/**
+ * The format of the given file path is invalid, e.g. is not absolute and normalized.
+ */
+ public static final String INVALID_FILE_PATH_FORMAT = "INVALID_FILE_PATH_FORMAT";
+
+ /**
* An "analysis.updateContent" request contained a ChangeContentOverlay object which can't be
* applied, due to an edit having an offset or length that is out of range.
*/
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index fcddc94..3bb6cfe 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -6,7 +6,7 @@
</head>
<body>
<h1>Analysis Server API Specification</h1>
- <h1 style="color:#999999">Version <version>1.13.0</version></h1>
+ <h1 style="color:#999999">Version <version>1.14.0</version></h1>
<p>
This document contains a specification of the API provided by the
analysis server. The API in this document is currently under
@@ -1995,14 +1995,9 @@
</params>
</notification>
</domain>
- <domain name="diagnostic" experimental="true">
+ <domain name="diagnostic">
<p>
- The diagnostic domain contains experimental server diagnostics APIs. Note
- that as an experimental API, docs are not generated for this domain and it
- is subject subject to change without notice.
- Because this experimental domain is not part of the analysis server's API,
- the version number of the API will not be updated when changes are made.
- Caveat emptor!
+ The diagnostic domain contains server diagnostics APIs.
</p>
<request method="getDiagnostics">
<p>Return server diagnostics.</p>
@@ -2496,7 +2491,7 @@
<value><code>PARAMETER</code></value>
</enum>
</type>
- <type name="ContextData" experimental="true">
+ <type name="ContextData">
<p>
Information about an analysis context.
</p>
@@ -2525,12 +2520,6 @@
The number of work items in the queue.
</p>
</field>
- <field name="workItemQueueLengthAverage">
- <ref>String</ref>
- <p>
- A rolling average of work items in the queue. (A double encoded as a String.)
- </p>
- </field>
<field name="cacheEntryExceptions">
<list><ref>String</ref></list>
<p>
@@ -2694,7 +2683,12 @@
<type name="FilePath">
<ref>String</ref>
<p>
- The absolute path of a file.
+ The absolute, normalized path of a file.
+ </p>
+ <p>
+ If the format of a file path in a request is not valid, e.g. the
+ path is not absolute or is not normalized, then an error of type
+ <tt>INVALID_FILE_PATH_FORMAT</tt> will be generated.
</p>
</type>
<type name="FoldingKind">
@@ -3708,6 +3702,13 @@
</p>
</value>
<value>
+ <code>INVALID_FILE_PATH_FORMAT</code>
+ <p>
+ The format of the given file path is invalid, e.g. is not
+ absolute and normalized.
+ </p>
+ </value>
+ <value>
<code>INVALID_OVERLAY_CHANGE</code>
<p>
An "analysis.updateContent" request contained a
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 6ff682d..805dcd8 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,16 @@
+## 0.27.0
+* Support for DEP 37 (Assert with optional message).
+* Lexical support for DEP 40 (Interface libraries). This does not include any semantic checking to ensure that the
+ implementation libraries are compatible with the interface library.
+* Cleaned up the initialization of plugins. Clients are now required to initialize plugins, possibly using the utility
+ method AnalysisEngine.processRequiredPlugins().
+* Removed the old task model and code that supported it. None of the removed code was intended to be public API, but
+ might be in use anyway.
+* Removed previously deprecated API's (marked with the @deprecated annotation).
+
+## 0.26.4
+* Options processing API updated to accept untyped options maps (#25126).
+
## 0.26.3
* (Internal) Support for `_embedder.yaml` discovery and processing.
@@ -88,7 +101,7 @@
## 0.25.2-alpha.0
-* Initial support for analyzing `dart:sdk` extensions from `.sdkext`.
+* Initial support for analyzing `dart:sdk` extensions from `.sdkext`.
## 0.25.1
@@ -112,7 +125,7 @@
## 0.22.0
New API:
-
+
* `Source.uri` added.
Breaking changes:
diff --git a/pkg/analyzer/lib/analyzer.dart b/pkg/analyzer/lib/analyzer.dart
index 83a72a1..d0fdc65 100644
--- a/pkg/analyzer/lib/analyzer.dart
+++ b/pkg/analyzer/lib/analyzer.dart
@@ -6,20 +6,19 @@
import 'dart:io';
+import 'package:analyzer/src/error.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/string_source.dart';
import 'package:path/path.dart' as pathos;
-import 'src/error.dart';
-import 'src/generated/ast.dart';
-import 'src/generated/error.dart';
-import 'src/generated/parser.dart';
-import 'src/generated/scanner.dart';
-import 'src/generated/source_io.dart';
-import 'src/string_source.dart';
-
-export 'src/error.dart';
-export 'src/generated/ast.dart';
-export 'src/generated/error.dart';
-export 'src/generated/utilities_dart.dart';
+export 'package:analyzer/src/error.dart';
+export 'package:analyzer/src/generated/ast.dart';
+export 'package:analyzer/src/generated/error.dart';
+export 'package:analyzer/src/generated/utilities_dart.dart';
/// Parses a string of Dart code into an AST.
///
diff --git a/pkg/analyzer/lib/file_system/file_system.dart b/pkg/analyzer/lib/file_system/file_system.dart
index cbe175f..05bd4e7 100644
--- a/pkg/analyzer/lib/file_system/file_system.dart
+++ b/pkg/analyzer/lib/file_system/file_system.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library file_system;
+library analyzer.file_system.file_system;
import 'dart:async';
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index c276397..dc676bb 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -2,20 +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.
-library memory_file_system;
+library analyzer.file_system.memory_file_system;
import 'dart:async';
import 'dart:collection';
import 'dart:core' hide Resource;
+import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart' show TimestampedData;
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/util/absolute_path.dart';
import 'package:path/path.dart';
import 'package:watcher/watcher.dart';
-import 'file_system.dart';
-
/**
* An in-memory implementation of [ResourceProvider].
* Use `/` as a path separator.
@@ -30,7 +29,7 @@
int nextStamp = 0;
final AbsolutePathContext absolutePathContext =
- new AbsolutePathContext(posix.separator);
+ new AbsolutePathContext(false);
@override
Context get pathContext => posix;
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index 94aa766..18694c0 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -2,20 +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.
-library physical_file_system;
+library analyzer.file_system.physical_file_system;
import 'dart:async';
import 'dart:core' hide Resource;
import 'dart:io' as io;
+import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/java_io.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/util/absolute_path.dart';
import 'package:path/path.dart';
import 'package:watcher/watcher.dart';
-import 'file_system.dart';
-
/**
* A `dart:io` based implementation of [ResourceProvider].
*/
@@ -33,7 +32,7 @@
static final String SERVER_DIR = ".dartServer";
final AbsolutePathContext absolutePathContext =
- new AbsolutePathContext(io.Platform.pathSeparator);
+ new AbsolutePathContext(io.Platform.isWindows);
PhysicalResourceProvider(String fileReadMode(String s)) {
if (fileReadMode != null) {
diff --git a/pkg/analyzer/lib/instrumentation/file_instrumentation.dart b/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
index 7269115..fe36a9e 100644
--- a/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library file_instrumentation;
+library analyzer.instrumentation.file_instrumentation;
import 'dart:async';
import 'dart:io';
diff --git a/pkg/analyzer/lib/instrumentation/instrumentation.dart b/pkg/analyzer/lib/instrumentation/instrumentation.dart
index 8b36303..fe58cdb 100644
--- a/pkg/analyzer/lib/instrumentation/instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/instrumentation.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library instrumentation;
+library analyzer.instrumentation.instrumentation;
import 'dart:async';
import 'dart:convert';
@@ -104,9 +104,7 @@
* Log that the given analysis [task] is being performed in the given
* [context].
*/
- void logAnalysisTask(String context, dynamic task) {
- // TODO(brianwilkerson) When the old task model is removed, change the
- // parameter type to AnalysisTask.
+ void logAnalysisTask(String context, AnalysisTask task) {
if (_instrumentationServer != null) {
String description =
(task is AnalysisTask) ? task.description : task.toString();
diff --git a/pkg/analyzer/lib/plugin/options.dart b/pkg/analyzer/lib/plugin/options.dart
index cec20c2..725315e 100644
--- a/pkg/analyzer/lib/plugin/options.dart
+++ b/pkg/analyzer/lib/plugin/options.dart
@@ -69,7 +69,7 @@
/// options have changed and to handle those changes appropriately. In
/// addition to the [options] map, the associated analysis [context] is
/// provided as well to allow for context-specific configuration.
- void optionsProcessed(AnalysisContext context, Map<String, YamlNode> options);
+ void optionsProcessed(AnalysisContext context, Map<String, Object> options);
}
/// Validates options as defined in an analysis options file.
diff --git a/pkg/analyzer/lib/plugin/task.dart b/pkg/analyzer/lib/plugin/task.dart
index d3eb4cd..2a242de 100644
--- a/pkg/analyzer/lib/plugin/task.dart
+++ b/pkg/analyzer/lib/plugin/task.dart
@@ -8,7 +8,7 @@
*/
library analyzer.plugin.task;
-import 'package:analyzer/src/generated/engine.dart' hide WorkManager;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/plugin/engine_plugin.dart';
import 'package:analyzer/task/model.dart';
import 'package:plugin/plugin.dart';
diff --git a/pkg/analyzer/lib/source/analysis_options_provider.dart b/pkg/analyzer/lib/source/analysis_options_provider.dart
index 64c8c8b..c53bbad 100644
--- a/pkg/analyzer/lib/source/analysis_options_provider.dart
+++ b/pkg/analyzer/lib/source/analysis_options_provider.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library source.analysis_options_provider;
+library analyzer.source.analysis_options_provider;
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
diff --git a/pkg/analyzer/lib/source/embedder.dart b/pkg/analyzer/lib/source/embedder.dart
index 2695989..c82e4f3 100644
--- a/pkg/analyzer/lib/source/embedder.dart
+++ b/pkg/analyzer/lib/source/embedder.dart
@@ -2,10 +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.
-library source.embedder;
+library analyzer.source.embedder;
-import 'dart:core' hide Resource;
import 'dart:collection' show HashMap;
+import 'dart:core' hide Resource;
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
diff --git a/pkg/analyzer/lib/source/error_processor.dart b/pkg/analyzer/lib/source/error_processor.dart
new file mode 100644
index 0000000..b20716a
--- /dev/null
+++ b/pkg/analyzer/lib/source/error_processor.dart
@@ -0,0 +1,105 @@
+// 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 analyzer.source.error_processor;
+
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/task/options.dart';
+import 'package:yaml/yaml.dart';
+
+/// Error processor configuration derived from analysis (or embedder) options.
+class ErrorConfig {
+ /// The processors in this config.
+ final List<ErrorProcessor> processors = <ErrorProcessor>[];
+
+ /// Create an error config for the given error code map.
+ /// For example:
+ /// new ErrorConfig({'missing_return' : 'error'});
+ /// will create a processor config that turns `missing_return` hints into
+ /// errors.
+ ErrorConfig(Object codeMap) {
+ _processMap(codeMap);
+ }
+
+ void _process(String code, Object action) {
+ action = toLowerCase(action);
+ code = toUpperCase(code);
+ if (AnalyzerOptions.ignoreSynonyms.contains(action)) {
+ processors.add(new ErrorProcessor.ignore(code));
+ } else {
+ ErrorSeverity severity = _toSeverity(action);
+ if (severity != null) {
+ processors.add(new ErrorProcessor(code, severity));
+ }
+ }
+ }
+
+ void _processMap(Object codes) {
+ if (codes is YamlMap) {
+ // TODO(pq): stop traversing nodes and unify w/ standard map handling
+ codes.nodes.forEach((k, v) {
+ if (k is YamlScalar && v is YamlScalar) {
+ _process(k.value, v.value);
+ }
+ });
+ } else if (codes is Map) {
+ codes.forEach((k, v) {
+ if (k is String) {
+ _process(k, v);
+ }
+ });
+ }
+ }
+
+ ErrorSeverity _toSeverity(String severity) {
+ switch (severity) {
+ case 'error':
+ return ErrorSeverity.ERROR;
+ case 'info':
+ return ErrorSeverity.INFO;
+ case 'warning':
+ return ErrorSeverity.WARNING;
+ }
+ return null;
+ }
+
+}
+
+/// Process errors by filtering or changing associated [ErrorSeverity].
+class ErrorProcessor {
+ /// The code name of the associated error.
+ final String code;
+
+ /// The desired severity of the processed error.
+ ///
+ /// If `null`, this processor will "filter" the associated error code.
+ final ErrorSeverity severity;
+
+ /// Create an error processor that assigns errors with this [code] the
+ /// given [severity].
+ ///
+ /// If [severity] is `null`, matching errors will be filtered.
+ ErrorProcessor(this.code, [this.severity]);
+
+ /// Create an error processor that ignores the given error by [code].
+ factory ErrorProcessor.ignore(String code) => new ErrorProcessor(code);
+
+ /// Check if this processor applies to the given [error].
+ bool appliesTo(AnalysisError error) => code == error.errorCode.name;
+
+ /// Return an error processor associated with this [context] for the given
+ /// [error], or `null` if none is found.
+ static ErrorProcessor getProcessor(
+ AnalysisContext context, AnalysisError error) {
+ if (context == null) {
+ return null;
+ }
+ List<ErrorProcessor> processors =
+ context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+ return processors.firstWhere((ErrorProcessor p) => p.appliesTo(error),
+ orElse: () => null);
+ }
+}
diff --git a/pkg/analyzer/lib/source/package_map_provider.dart b/pkg/analyzer/lib/source/package_map_provider.dart
index 85b493d..b2eb8b6 100644
--- a/pkg/analyzer/lib/source/package_map_provider.dart
+++ b/pkg/analyzer/lib/source/package_map_provider.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library source.package_map_provider;
+library analyzer.source.package_map_provider;
import 'package:analyzer/file_system/file_system.dart';
diff --git a/pkg/analyzer/lib/source/package_map_resolver.dart b/pkg/analyzer/lib/source/package_map_resolver.dart
index 0fa12ae..4325582 100644
--- a/pkg/analyzer/lib/source/package_map_resolver.dart
+++ b/pkg/analyzer/lib/source/package_map_resolver.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library source.package_map_resolver;
+library analyzer.source.package_map_resolver;
import 'dart:core' hide Resource;
diff --git a/pkg/analyzer/lib/source/path_filter.dart b/pkg/analyzer/lib/source/path_filter.dart
index 7eeada2..f449610 100644
--- a/pkg/analyzer/lib/source/path_filter.dart
+++ b/pkg/analyzer/lib/source/path_filter.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library source.path_filter;
+library analyzer.source.path_filter;
import 'package:analyzer/src/util/glob.dart';
import 'package:path/path.dart' as path;
diff --git a/pkg/analyzer/lib/source/pub_package_map_provider.dart b/pkg/analyzer/lib/source/pub_package_map_provider.dart
index 5daf61d..a7b2c42 100644
--- a/pkg/analyzer/lib/source/pub_package_map_provider.dart
+++ b/pkg/analyzer/lib/source/pub_package_map_provider.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library source.pub_package_map_provider;
+library analyzer.source.pub_package_map_provider;
import 'dart:collection';
import 'dart:convert';
diff --git a/pkg/analyzer/lib/source/sdk_ext.dart b/pkg/analyzer/lib/source/sdk_ext.dart
index 646a19f..fc7155a 100644
--- a/pkg/analyzer/lib/source/sdk_ext.dart
+++ b/pkg/analyzer/lib/source/sdk_ext.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library source.sdk_ext;
+library analyzer.source.sdk_ext;
import 'dart:convert';
import 'dart:core' hide Resource;
diff --git a/pkg/analyzer/lib/src/cancelable_future.dart b/pkg/analyzer/lib/src/cancelable_future.dart
index 733cac5..8ae070b 100644
--- a/pkg/analyzer/lib/src/cancelable_future.dart
+++ b/pkg/analyzer/lib/src/cancelable_future.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library cancelable_future;
+library analyzer.src.cancelable_future;
import 'dart:async';
diff --git a/pkg/analyzer/lib/src/codegen/text_formatter.dart b/pkg/analyzer/lib/src/codegen/text_formatter.dart
index 28669e0..5274901 100644
--- a/pkg/analyzer/lib/src/codegen/text_formatter.dart
+++ b/pkg/analyzer/lib/src/codegen/text_formatter.dart
@@ -8,10 +8,9 @@
*/
library analyzer.src.codegen.text_formatter;
+import 'package:analyzer/src/codegen/tools.dart';
import 'package:html/dom.dart' as dom;
-import 'tools.dart';
-
final RegExp whitespace = new RegExp(r'\s');
/**
diff --git a/pkg/analyzer/lib/src/codegen/tools.dart b/pkg/analyzer/lib/src/codegen/tools.dart
index 87c9edf..6c4048c 100644
--- a/pkg/analyzer/lib/src/codegen/tools.dart
+++ b/pkg/analyzer/lib/src/codegen/tools.dart
@@ -9,12 +9,11 @@
import 'dart:io';
+import 'package:analyzer/src/codegen/html.dart';
+import 'package:analyzer/src/codegen/text_formatter.dart';
import 'package:html/dom.dart' as dom;
import 'package:path/path.dart';
-import 'html.dart';
-import 'text_formatter.dart';
-
final RegExp trailingSpacesInLineRegExp = new RegExp(r' +$', multiLine: true);
final RegExp trailingWhitespaceRegExp = new RegExp(r'[\n ]+$');
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index 2b81cdd..afe0216 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -7,8 +7,7 @@
import 'dart:async';
import 'dart:collection';
-import 'package:analyzer/src/generated/engine.dart'
- show AnalysisEngine, CacheState, InternalAnalysisContext, RetentionPriority;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
@@ -41,9 +40,9 @@
final ReentrantSynchronousStream<InvalidatedResult> onResultInvalidated =
new ReentrantSynchronousStream<InvalidatedResult>();
- final List<
- ReentrantSynchronousStreamSubscription> onResultInvalidatedPartitionSubscriptions = <
- ReentrantSynchronousStreamSubscription>[];
+ final List<ReentrantSynchronousStreamSubscription>
+ onResultInvalidatedPartitionSubscriptions =
+ <ReentrantSynchronousStreamSubscription>[];
/**
* Initialize a newly created cache to have the given [_partitions]. The
@@ -385,7 +384,7 @@
* Return the value of the result represented by the given [descriptor], or
* the default value for the result if this entry does not have a valid value.
*/
- /*<V>*/ dynamic /*V*/ getValue(ResultDescriptor /*<V>*/ descriptor) {
+ dynamic /*=V*/ getValue /*<V>*/ (ResultDescriptor /*<V>*/ descriptor) {
ResultData data = _resultMap[descriptor];
if (data == null) {
return descriptor.defaultValue;
@@ -483,11 +482,8 @@
* Set the value of the result represented by the given [descriptor] to the
* given [value].
*/
- /*<V>*/ void setValue(
- ResultDescriptor /*<V>*/ descriptor,
- dynamic /*V*/
- value,
- List<TargetedResult> dependedOn) {
+ void setValue /*<V>*/ (ResultDescriptor /*<V>*/ descriptor,
+ dynamic /*=V*/ value, List<TargetedResult> dependedOn) {
// {
// String valueStr = '$value';
// if (valueStr.length > 20) {
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 4d3651b..7c2971a 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -15,15 +15,8 @@
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart'
- hide
- AnalysisCache,
- CachePartition,
- SdkCachePartition,
- UniversalCachePartition,
- WorkManager;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart' as ht show HtmlUnit;
import 'package:analyzer/src/generated/incremental_resolver.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/java_engine.dart';
@@ -211,21 +204,6 @@
CompilationUnit incrementalResolutionValidation_lastUnit;
/**
- * A factory to override how the [ResolverVisitor] is created.
- */
- ResolverVisitorFactory resolverVisitorFactory;
-
- /**
- * A factory to override how the [TypeResolverVisitor] is created.
- */
- TypeResolverVisitorFactory typeResolverVisitorFactory;
-
- /**
- * A factory to override how [LibraryResolver] is created.
- */
- LibraryResolverFactory libraryResolverFactory;
-
- /**
* Initialize a newly created analysis context.
*/
AnalysisContextImpl() {
@@ -267,6 +245,7 @@
(this._options.lint && !options.lint) ||
this._options.preserveComments != options.preserveComments ||
this._options.strongMode != options.strongMode ||
+ this._options.enableAssertMessage != options.enableAssertMessage ||
((options is AnalysisOptionsImpl)
? this._options.strongModeHints != options.strongModeHints
: false) ||
@@ -284,6 +263,7 @@
this._options.generateSdkErrors = options.generateSdkErrors;
this._options.dart2jsHint = options.dart2jsHint;
this._options.enableGenericMethods = options.enableGenericMethods;
+ this._options.enableAssertMessage = options.enableAssertMessage;
this._options.enableStrictCallChecks = options.enableStrictCallChecks;
this._options.enableSuperMixins = options.enableSuperMixins;
this._options.hint = options.hint;
@@ -395,9 +375,8 @@
/**
* Make _pendingFutureSources available to unit tests.
*/
- HashMap<AnalysisTarget,
- List<PendingFuture>> get pendingFutureSources_forTesting =>
- _pendingFutureTargets;
+ HashMap<AnalysisTarget, List<PendingFuture>>
+ get pendingFutureSources_forTesting => _pendingFutureTargets;
@override
List<Source> get prioritySources => _priorityOrder;
@@ -458,16 +437,6 @@
return new List<Source>.from(sources);
}
- @override
- AnalysisContextStatistics get statistics {
- AnalysisContextStatisticsImpl statistics =
- new AnalysisContextStatisticsImpl();
- // TODO(brianwilkerson) Implement this.
-// visitCacheItems(statistics._internalPutCacheItem);
-// statistics.partitionData = _cache.partitionData;
- return statistics;
- }
-
List<Source> get test_priorityOrder => _priorityOrder;
@override
@@ -619,14 +588,6 @@
computeResult(source, EXPORTED_LIBRARIES);
@override
- @deprecated
- HtmlElement computeHtmlElement(Source source) {
- // TODO(brianwilkerson) Remove this method after switching to the new task
- // model.
- throw new UnimplementedError('Not supported in the new task model');
- }
-
- @override
List<Source> computeImportedLibraries(Source source) =>
computeResult(source, EXPLICITLY_IMPORTED_LIBRARIES);
@@ -651,26 +612,19 @@
LineInfo computeLineInfo(Source source) => computeResult(source, LINE_INFO);
@override
- @deprecated
- CompilationUnit computeResolvableCompilationUnit(Source source) {
- return null;
- }
-
- @override
CancelableFuture<CompilationUnit> computeResolvedCompilationUnitAsync(
Source unitSource, Source librarySource) {
if (!AnalysisEngine.isDartFileName(unitSource.shortName) ||
!AnalysisEngine.isDartFileName(librarySource.shortName)) {
return new CancelableFuture.error(new AnalysisNotScheduledError());
}
- return new AnalysisFutureHelper<CompilationUnit>(
- this,
- new LibrarySpecificUnit(librarySource, unitSource),
- RESOLVED_UNIT).computeAsync();
+ return new AnalysisFutureHelper<CompilationUnit>(this,
+ new LibrarySpecificUnit(librarySource, unitSource), RESOLVED_UNIT)
+ .computeAsync();
}
@override
- Object /*V*/ computeResult(
+ Object /*=V*/ computeResult /*<V>*/ (
AnalysisTarget target, ResultDescriptor /*<V>*/ descriptor) {
// Make sure we are not trying to invoke the task model in a reentrant
// fashion.
@@ -700,7 +654,7 @@
return new AnalysisCache(<CachePartition>[_privatePartition]);
}
return new AnalysisCache(<CachePartition>[
- AnalysisEngine.instance.partitionManager_new.forSdk(sdk),
+ AnalysisEngine.instance.partitionManager.forSdk(sdk),
_privatePartition
]);
}
@@ -840,14 +794,6 @@
}
@override
- @deprecated
- HtmlElement getHtmlElement(Source source) {
- // TODO(brianwilkerson) Remove this method after switching to the new task
- // model.
- throw new UnimplementedError('Not supported in the new task model');
- }
-
- @override
List<Source> getHtmlFilesReferencing(Source source) {
if (!AnalysisEngine.isDartFileName(source.shortName)) {
return Source.EMPTY_LIST;
@@ -979,14 +925,6 @@
}
@override
- @deprecated
- ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
- // TODO(brianwilkerson) Remove this method after switching to the new task
- // model.
- throw new UnimplementedError('Not supported in the new task model');
- }
-
- @override
Object getResult(AnalysisTarget target, ResultDescriptor result) {
return _cache.getValue(target, result);
}
@@ -1108,14 +1046,6 @@
}
@override
- @deprecated // use parseHtmlDocument(source)
- ht.HtmlUnit parseHtmlUnit(Source source) {
- // TODO(brianwilkerson) Remove this method after switching to the new task
- // model.
- throw new UnimplementedError('Not supported in the new task model');
- }
-
- @override
AnalysisResult performAnalysisTask() {
return PerformanceStatistics.performAnaysis.makeCurrentWhile(() {
_evaluatePendingFutures();
@@ -1225,14 +1155,6 @@
}
@override
- @deprecated
- ht.HtmlUnit resolveHtmlUnit(Source htmlSource) {
- // TODO(brianwilkerson) Remove this method after switching to the new task
- // model.
- throw new UnimplementedError('Not supported in the new task model');
- }
-
- @override
void setChangedContents(Source source, String contents, int offset,
int oldLength, int newLength) {
if (_contentRangeChanged(source, contents, offset, oldLength, newLength)) {
@@ -1252,7 +1174,7 @@
}
@override
- bool shouldErrorsBeAnalyzed(Source source, Object entry) {
+ bool shouldErrorsBeAnalyzed(Source source) {
CacheEntry entry = analysisCache.get(source);
if (source.isInSystemLibrary) {
return _options.generateSdkErrors;
@@ -1332,72 +1254,6 @@
return changedSources.length > 0;
}
- @deprecated
- @override
- void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
- DataDescriptor rowDesc, CacheState state)) {
- // TODO(brianwilkerson) Figure out where this is used and either remove it
- // or adjust the call sites to use CacheEntry's.
-// bool hintsEnabled = _options.hint;
-// bool lintsEnabled = _options.lint;
-// MapIterator<AnalysisTarget, cache.CacheEntry> iterator = _cache.iterator();
-// while (iterator.moveNext()) {
-// Source source = iterator.key;
-// cache.CacheEntry entry = iterator.value;
-// for (DataDescriptor descriptor in entry.descriptors) {
-// if (descriptor == DartEntry.SOURCE_KIND) {
-// // The source kind is always valid, so the state isn't interesting.
-// continue;
-// } else if (descriptor == DartEntry.CONTAINING_LIBRARIES) {
-// // The list of containing libraries is always valid, so the state
-// // isn't interesting.
-// continue;
-// } else if (descriptor == DartEntry.PUBLIC_NAMESPACE) {
-// // The public namespace isn't computed by performAnalysisTask()
-// // and therefore isn't interesting.
-// continue;
-// } else if (descriptor == HtmlEntry.HINTS) {
-// // We are not currently recording any hints related to HTML.
-// continue;
-// }
-// callback(
-// source, entry, descriptor, entry.getState(descriptor));
-// }
-// if (entry is DartEntry) {
-// // get library-specific values
-// List<Source> librarySources = getLibrariesContaining(source);
-// for (Source librarySource in librarySources) {
-// for (DataDescriptor descriptor in entry.libraryDescriptors) {
-// if (descriptor == DartEntry.BUILT_ELEMENT ||
-// descriptor == DartEntry.BUILT_UNIT) {
-// // These values are not currently being computed, so their state
-// // is not interesting.
-// continue;
-// } else if (!entry.explicitlyAdded &&
-// !_generateImplicitErrors &&
-// (descriptor == DartEntry.VERIFICATION_ERRORS ||
-// descriptor == DartEntry.HINTS ||
-// descriptor == DartEntry.LINTS)) {
-// continue;
-// } else if (source.isInSystemLibrary &&
-// !_generateSdkErrors &&
-// (descriptor == DartEntry.VERIFICATION_ERRORS ||
-// descriptor == DartEntry.HINTS ||
-// descriptor == DartEntry.LINTS)) {
-// continue;
-// } else if (!hintsEnabled && descriptor == DartEntry.HINTS) {
-// continue;
-// } else if (!lintsEnabled && descriptor == DartEntry.LINTS) {
-// continue;
-// }
-// callback(librarySource, entry, descriptor,
-// entry.getStateInLibrary(descriptor, librarySource));
-// }
-// }
-// }
-// }
- }
-
@override
void visitContentCache(ContentCacheVisitor visitor) {
_contentCache.accept(visitor);
@@ -1667,7 +1523,7 @@
} else if (state == CacheState.ERROR) {
return;
}
- if (shouldErrorsBeAnalyzed(source, unitEntry)) {
+ if (shouldErrorsBeAnalyzed(source)) {
state = unitEntry.getState(VERIFY_ERRORS);
if (state == CacheState.INVALID ||
(isPriority && state == CacheState.FLUSHED)) {
@@ -1948,7 +1804,6 @@
PoorMansIncrementalResolver resolver = new PoorMansIncrementalResolver(
typeProvider,
unitSource,
- null,
sourceEntry,
unitEntry,
oldUnit,
@@ -2164,8 +2019,7 @@
throw new IllegalArgumentException(
"The source factory for an SDK analysis context must have a DartUriResolver");
}
- return new AnalysisCache(<CachePartition>[
- AnalysisEngine.instance.partitionManager_new.forSdk(sdk)
- ]);
+ return new AnalysisCache(
+ <CachePartition>[AnalysisEngine.instance.partitionManager.forSdk(sdk)]);
}
}
diff --git a/pkg/analyzer/lib/src/error.dart b/pkg/analyzer/lib/src/error.dart
index 60f5cf0..35ffb7c 100644
--- a/pkg/analyzer/lib/src/error.dart
+++ b/pkg/analyzer/lib/src/error.dart
@@ -1,11 +1,11 @@
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library error;
+library analyzer.src.error;
import 'dart:collection';
-import 'generated/error.dart';
+import 'package:analyzer/src/generated/error.dart';
/// The maximum line length when printing extracted source code when converting
/// an [AnalyzerError] to a string.
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index f04a15e..282b8b7 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -2,19 +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.
-library engine.ast;
+library analyzer.src.generated.ast;
import 'dart:collection';
-import 'element.dart';
-import 'engine.dart' show AnalysisEngine;
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'parser.dart';
-import 'scanner.dart';
-import 'source.dart' show LineInfo, Source;
-import 'utilities_collection.dart' show TokenMap;
-import 'utilities_dart.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart' show LineInfo, Source;
+import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap;
+import 'package:analyzer/src/generated/utilities_dart.dart';
/**
* Two or more string literals that are implicitly concatenated because of being
@@ -140,15 +140,6 @@
NodeList<Annotation> get metadata => _metadata;
/**
- * Set the metadata associated with this node to the given [metadata].
- */
- @deprecated // Directly modify the list returned by "this.metadata"
- void set metadata(List<Annotation> metadata) {
- _metadata.clear();
- _metadata.addAll(metadata);
- }
-
- /**
* Return a list containing the comment and annotations associated with this
* node, sorted in lexical order.
*/
@@ -465,37 +456,6 @@
@override
accept(AstVisitor visitor) => visitor.visitArgumentList(this);
- /**
- * If
- * * the given [expression] is a child of this list,
- * * the AST structure has been resolved,
- * * the function being invoked is known based on propagated type information,
- * and
- * * the expression corresponds to one of the parameters of the function being
- * invoked,
- * then return the parameter element representing the parameter to which the
- * value of the given expression will be bound. Otherwise, return `null`.
- */
- @deprecated // Use "expression.propagatedParameterElement"
- ParameterElement getPropagatedParameterElementFor(Expression expression) {
- return _getPropagatedParameterElementFor(expression);
- }
-
- /**
- * If
- * * the given [expression] is a child of this list,
- * * the AST structure has been resolved,
- * * the function being invoked is known based on static type information, and
- * * the expression corresponds to one of the parameters of the function being
- * invoked,
- * then return the parameter element representing the parameter to which the
- * value of the given expression will be bound. Otherwise, return `null`.
- */
- @deprecated // Use "expression.staticParameterElement"
- ParameterElement getStaticParameterElementFor(Expression expression) {
- return _getStaticParameterElementFor(expression);
- }
-
@override
void visitChildren(AstVisitor visitor) {
_arguments.accept(visitor);
@@ -656,6 +616,17 @@
Expression _condition;
/**
+ * The comma, if a message expression was supplied. Otherwise `null`.
+ */
+ Token comma;
+
+ /**
+ * The message to report if the assertion fails. `null` if no message was
+ * supplied.
+ */
+ Expression _message;
+
+ /**
* The right parenthesis.
*/
Token rightParenthesis;
@@ -668,9 +639,16 @@
/**
* Initialize a newly created assert statement.
*/
- AssertStatement(this.assertKeyword, this.leftParenthesis,
- Expression condition, this.rightParenthesis, this.semicolon) {
+ AssertStatement(
+ this.assertKeyword,
+ this.leftParenthesis,
+ Expression condition,
+ this.comma,
+ Expression message,
+ this.rightParenthesis,
+ this.semicolon) {
_condition = _becomeParentOf(condition);
+ _message = _becomeParentOf(message);
}
@override
@@ -681,6 +659,8 @@
..add(assertKeyword)
..add(leftParenthesis)
..add(_condition)
+ ..add(comma)
+ ..add(_message)
..add(rightParenthesis)
..add(semicolon);
@@ -701,17 +681,16 @@
Token get endToken => semicolon;
/**
- * Return the token representing the 'assert' keyword.
+ * Return the message to report if the assertion fails.
*/
- @deprecated // Use "this.assertKeyword"
- Token get keyword => assertKeyword;
+ Expression get message => _message;
/**
- * Set the token representing the 'assert' keyword to the given [token].
+ * Set the message to report if the assertion fails to the given
+ * [expression].
*/
- @deprecated // Use "this.assertKeyword"
- set keyword(Token token) {
- assertKeyword = token;
+ void set message(Expression expression) {
+ _message = _becomeParentOf(expression);
}
@override
@@ -720,6 +699,7 @@
@override
void visitChildren(AstVisitor visitor) {
_safelyVisitChild(_condition, visitor);
+ _safelyVisitChild(message, visitor);
}
}
@@ -828,17 +808,6 @@
int get precedence => 1;
/**
- * If the AST structure has been resolved, and the function being invoked is
- * known based on propagated type information, then return the parameter
- * element representing the parameter to which the value of the right operand
- * will be bound. Otherwise, return `null`.
- */
- @deprecated // Use "expression.propagatedParameterElement"
- ParameterElement get propagatedParameterElementForRightHandSide {
- return _propagatedParameterElementForRightHandSide;
- }
-
- /**
* Return the expression used to compute the right hand side.
*/
Expression get rightHandSide => _rightHandSide;
@@ -853,17 +822,6 @@
/**
* If the AST structure has been resolved, and the function being invoked is
- * known based on static type information, then return the parameter element
- * representing the parameter to which the value of the right operand will be
- * bound. Otherwise, return `null`.
- */
- @deprecated // Use "expression.staticParameterElement"
- ParameterElement get staticParameterElementForRightHandSide {
- return _staticParameterElementForRightHandSide;
- }
-
- /**
- * If the AST structure has been resolved, and the function being invoked is
* known based on propagated type information, then return the parameter
* element representing the parameter to which the value of the right operand
* will be bound. Otherwise, return `null`.
@@ -1037,6 +995,8 @@
cloneToken(node.assertKeyword),
cloneToken(node.leftParenthesis),
cloneNode(node.condition),
+ cloneToken(node.comma),
+ cloneNode(node.message),
cloneToken(node.rightParenthesis),
cloneToken(node.semicolon));
@@ -1163,6 +1123,16 @@
cloneNode(node.elseExpression));
@override
+ Configuration visitConfiguration(Configuration node) => new Configuration(
+ cloneToken(node.ifKeyword),
+ cloneToken(node.leftParenthesis),
+ cloneNode(node.name),
+ cloneToken(node.equalToken),
+ cloneNode(node.value),
+ cloneToken(node.rightParenthesis),
+ cloneNode(node.libraryUri));
+
+ @override
ConstructorDeclaration visitConstructorDeclaration(
ConstructorDeclaration node) =>
new ConstructorDeclaration(
@@ -1226,6 +1196,10 @@
cloneToken(node.semicolon));
@override
+ DottedName visitDottedName(DottedName node) =>
+ new DottedName(cloneNodeList(node.components));
+
+ @override
DoubleLiteral visitDoubleLiteral(DoubleLiteral node) =>
new DoubleLiteral(cloneToken(node.literal), node.value);
@@ -1260,6 +1234,7 @@
cloneNodeList(node.metadata),
cloneToken(node.keyword),
cloneNode(node.uri),
+ cloneNodeList(node.configurations),
cloneNodeList(node.combinators),
cloneToken(node.semicolon));
directive.source = node.source;
@@ -1430,6 +1405,7 @@
cloneNodeList(node.metadata),
cloneToken(node.keyword),
cloneNode(node.uri),
+ cloneNodeList(node.configurations),
cloneToken(node.deferredKeyword),
cloneToken(node.asKeyword),
cloneNode(node.prefix),
@@ -1893,6 +1869,8 @@
return isEqualTokens(node.assertKeyword, other.assertKeyword) &&
isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
isEqualNodes(node.condition, other.condition) &&
+ isEqualTokens(node.comma, other.comma) &&
+ isEqualNodes(node.message, other.message) &&
isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
isEqualTokens(node.semicolon, other.semicolon);
}
@@ -2039,6 +2017,18 @@
}
@override
+ bool visitConfiguration(Configuration node) {
+ Configuration other = _other as Configuration;
+ return isEqualTokens(node.ifKeyword, other.ifKeyword) &&
+ isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+ isEqualNodes(node.name, other.name) &&
+ isEqualTokens(node.equalToken, other.equalToken) &&
+ isEqualNodes(node.value, other.value) &&
+ isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+ isEqualNodes(node.libraryUri, other.libraryUri);
+ }
+
+ @override
bool visitConstructorDeclaration(ConstructorDeclaration node) {
ConstructorDeclaration other = _other as ConstructorDeclaration;
return isEqualNodes(
@@ -2116,6 +2106,12 @@
}
@override
+ bool visitDottedName(DottedName node) {
+ DottedName other = _other as DottedName;
+ return _isEqualNodeLists(node.components, other.components);
+ }
+
+ @override
bool visitDoubleLiteral(DoubleLiteral node) {
DoubleLiteral other = _other as DoubleLiteral;
return isEqualTokens(node.literal, other.literal) &&
@@ -2868,12 +2864,6 @@
/**
* An empty list of AST nodes.
*/
- @deprecated // Use "AstNode.EMPTY_LIST"
- static const List<AstNode> EMPTY_ARRAY = EMPTY_LIST;
-
- /**
- * An empty list of AST nodes.
- */
static const List<AstNode> EMPTY_LIST = const <AstNode>[];
/**
@@ -2883,8 +2873,8 @@
* the same offset, and a positive value if the offset of the first node is
* greater than the offset of the second node.
*/
- static Comparator<AstNode> LEXICAL_ORDER = (AstNode first, AstNode second) =>
- first.offset - second.offset;
+ static Comparator<AstNode> LEXICAL_ORDER =
+ (AstNode first, AstNode second) => first.offset - second.offset;
/**
* The parent of the node, or `null` if the node is the root of an AST
@@ -2966,14 +2956,6 @@
AstNode get parent => _parent;
/**
- * Set the parent of this node to the [newParent].
- */
- @deprecated // Never intended for public use.
- void set parent(AstNode newParent) {
- _parent = newParent;
- }
-
- /**
* Return the node at the root of this node's AST structure. Note that this
* method's performance is linear with respect to the depth of the node in the
* AST structure (O(depth)).
@@ -2992,15 +2974,7 @@
* Use the given [visitor] to visit this node. Return the value returned by
* the visitor as a result of visiting this node.
*/
- /* <E> E */ accept(AstVisitor /*<E>*/ visitor);
-
- /**
- * Make this node the parent of the given [child] node. Return the child node.
- */
- @deprecated // Never intended for public use.
- AstNode becomeParentOf(AstNode child) {
- return _becomeParentOf(child);
- }
+ dynamic /*=E*/ accept /*<E>*/ (AstVisitor /*<E>*/ visitor);
/**
* Return the most immediate ancestor of this node for which the [predicate]
@@ -3028,16 +3002,6 @@
}
/**
- * If the given [child] is not `null`, use the given [visitor] to visit it.
- */
- @deprecated // Never intended for public use.
- void safelyVisitChild(AstNode child, AstVisitor visitor) {
- if (child != null) {
- child.accept(visitor);
- }
- }
-
- /**
* Set the value of the property with the given [name] to the given [value].
* If the value is `null`, the property will effectively be removed.
*/
@@ -3141,6 +3105,8 @@
R visitConditionalExpression(ConditionalExpression node);
+ R visitConfiguration(Configuration node);
+
R visitConstructorDeclaration(ConstructorDeclaration node);
R visitConstructorFieldInitializer(ConstructorFieldInitializer node);
@@ -3155,6 +3121,8 @@
R visitDoStatement(DoStatement node);
+ R visitDottedName(DottedName node);
+
R visitDoubleLiteral(DoubleLiteral node);
R visitEmptyFunctionBody(EmptyFunctionBody node);
@@ -3466,17 +3434,6 @@
int get precedence => operator.type.precedence;
/**
- * If the AST structure has been resolved, and the function being invoked is
- * known based on propagated type information, then return the parameter
- * element representing the parameter to which the value of the right operand
- * will be bound. Otherwise, return `null`.
- */
- @deprecated // Use "expression.propagatedParameterElement"
- ParameterElement get propagatedParameterElementForRightOperand {
- return _propagatedParameterElementForRightOperand;
- }
-
- /**
* Return the expression used to compute the right operand.
*/
Expression get rightOperand => _rightOperand;
@@ -3491,17 +3448,6 @@
/**
* If the AST structure has been resolved, and the function being invoked is
- * known based on static type information, then return the parameter element
- * representing the parameter to which the value of the right operand will be
- * bound. Otherwise, return `null`.
- */
- @deprecated // Use "expression.staticParameterElement"
- ParameterElement get staticParameterElementForRightOperand {
- return _staticParameterElementForRightOperand;
- }
-
- /**
- * If the AST structure has been resolved, and the function being invoked is
* known based on propagated type information, then return the parameter
* element representing the parameter to which the value of the right operand
* will be bound. Otherwise, return `null`.
@@ -3828,20 +3774,6 @@
Token get endToken => semicolon;
/**
- * Return the token representing the 'break' keyword.
- */
- @deprecated // Use "this.breakKeyword"
- Token get keyword => breakKeyword;
-
- /**
- * Set the token representing the 'break' keyword to the given [token].
- */
- @deprecated // Use "this.breakKeyword"
- void set keyword(Token token) {
- breakKeyword = token;
- }
-
- /**
* Return the label associated with the statement, or `null` if there is no
* label.
*/
@@ -5115,6 +5047,85 @@
}
}
+/**
+ * A configuration in either an import or export directive.
+ *
+ * configuration ::=
+ * 'if' '(' test ')' uri
+ *
+ * test ::=
+ * dottedName ('==' stringLiteral)?
+ *
+ * dottedName ::=
+ * identifier ('.' identifier)*
+ */
+class Configuration extends AstNode {
+ Token ifKeyword;
+ Token leftParenthesis;
+ DottedName _name;
+ Token equalToken;
+ StringLiteral _value;
+ Token rightParenthesis;
+ StringLiteral _libraryUri;
+
+ Configuration(
+ this.ifKeyword,
+ this.leftParenthesis,
+ DottedName name,
+ this.equalToken,
+ StringLiteral value,
+ this.rightParenthesis,
+ StringLiteral libraryUri) {
+ _name = _becomeParentOf(name);
+ _value = _becomeParentOf(value);
+ _libraryUri = _becomeParentOf(libraryUri);
+ }
+
+ @override
+ Token get beginToken => ifKeyword;
+
+ @override
+ Iterable get childEntities => new ChildEntities()
+ ..add(ifKeyword)
+ ..add(leftParenthesis)
+ ..add(_name)
+ ..add(equalToken)
+ ..add(_value)
+ ..add(rightParenthesis)
+ ..add(_libraryUri);
+
+ @override
+ Token get endToken => _libraryUri.endToken;
+
+ StringLiteral get libraryUri => _libraryUri;
+
+ void set libraryUri(StringLiteral libraryUri) {
+ _libraryUri = _becomeParentOf(libraryUri);
+ }
+
+ DottedName get name => _name;
+
+ void set name(DottedName name) {
+ _name = _becomeParentOf(name);
+ }
+
+ StringLiteral get value => _value;
+
+ void set value(StringLiteral value) {
+ _value = _becomeParentOf(value);
+ }
+
+ @override
+ accept(AstVisitor visitor) => visitor.visitConfiguration(this);
+
+ @override
+ void visitChildren(AstVisitor visitor) {
+ _safelyVisitChild(_name, visitor);
+ _safelyVisitChild(_value, visitor);
+ _safelyVisitChild(_libraryUri, visitor);
+ }
+}
+
/// Instances of the class [ConstantEvaluator] evaluate constant expressions to
/// produce their compile-time value.
///
@@ -5824,21 +5835,6 @@
_fieldName = _becomeParentOf(identifier);
}
- /**
- * Return the token for the 'this' keyword, or `null` if there is no 'this'
- * keyword.
- */
- @deprecated // Use "this.thisKeyword"
- Token get keyword => thisKeyword;
-
- /**
- * Set the token for the 'this' keyword to the given [token].
- */
- @deprecated // Use "this.thisKeyword"
- set keyword(Token token) {
- thisKeyword = token;
- }
-
@override
accept(AstVisitor visitor) => visitor.visitConstructorFieldInitializer(this);
@@ -6001,21 +5997,6 @@
Token get endToken => semicolon;
/**
- * Return the token for the 'continue' keyword, or `null` if there is no
- * 'continue' keyword.
- */
- @deprecated // Use "this.continueKeyword"
- Token get keyword => continueKeyword;
-
- /**
- * Set the token for the 'continue' keyword to the given [token].
- */
- @deprecated // Use "this.continueKeyword"
- set keyword(Token token) {
- continueKeyword = token;
- }
-
- /**
* Return the label associated with the statement, or `null` if there is no
* label.
*/
@@ -6135,7 +6116,8 @@
/**
* Return `true` if this variable was declared with the 'const' modifier.
*/
- bool get isConst => (keyword is KeywordToken) &&
+ bool get isConst =>
+ (keyword is KeywordToken) &&
(keyword as KeywordToken).keyword == Keyword.CONST;
/**
@@ -6143,7 +6125,8 @@
* Variables that are declared with the 'const' modifier will return `false`
* even though they are implicitly final.
*/
- bool get isFinal => (keyword is KeywordToken) &&
+ bool get isFinal =>
+ (keyword is KeywordToken) &&
(keyword as KeywordToken).keyword == Keyword.FINAL;
/**
@@ -6450,6 +6433,49 @@
}
/**
+ * A dotted name, used in a configuration within an import or export directive.
+ *
+ * > dottedName ::=
+ * > [SimpleIdentifier] ('.' [SimpleIdentifier])*
+ */
+class DottedName extends AstNode {
+ /**
+ * The components of the identifier.
+ */
+ NodeList<SimpleIdentifier> _components;
+
+ /**
+ * Initialize a newly created dotted name.
+ */
+ DottedName(List<SimpleIdentifier> components) {
+ _components = new NodeList<SimpleIdentifier>(this, components);
+ }
+
+ @override
+ Token get beginToken => _components.beginToken;
+
+ @override
+ // TODO(paulberry): add "." tokens.
+ Iterable get childEntities => new ChildEntities()..addAll(_components);
+
+ /**
+ * Return the components of the identifier.
+ */
+ NodeList<SimpleIdentifier> get components => _components;
+
+ @override
+ Token get endToken => _components.endToken;
+
+ @override
+ accept(AstVisitor visitor) => visitor.visitDottedName(this);
+
+ @override
+ void visitChildren(AstVisitor visitor) {
+ _components.accept(visitor);
+ }
+}
+
+/**
* A floating point literal expression.
*
* > doubleLiteral ::=
@@ -6818,21 +6844,6 @@
@override
Token get firstTokenAfterCommentAndMetadata => enumKeyword;
- /**
- * Return the token for the 'enum' keyword, or `null` if there is no
- * 'enum' keyword.
- */
- @deprecated // Use "this.enumKeyword"
- Token get keyword => enumKeyword;
-
- /**
- * Set the token for the 'enum' keyword to the given [token].
- */
- @deprecated // Use "this.enumKeyword"
- set keyword(Token token) {
- enumKeyword = token;
- }
-
@override
accept(AstVisitor visitor) => visitor.visitEnumDeclaration(this);
@@ -6868,9 +6879,16 @@
* corresponding attribute. The list of [combinators] can be `null` if there
* are no combinators.
*/
- ExportDirective(Comment comment, List<Annotation> metadata, Token keyword,
- StringLiteral libraryUri, List<Combinator> combinators, Token semicolon)
- : super(comment, metadata, keyword, libraryUri, combinators, semicolon);
+ ExportDirective(
+ Comment comment,
+ List<Annotation> metadata,
+ Token keyword,
+ StringLiteral libraryUri,
+ List<Configuration> configurations,
+ List<Combinator> combinators,
+ Token semicolon)
+ : super(comment, metadata, keyword, libraryUri, configurations,
+ combinators, semicolon);
@override
Iterable get childEntities => super._childEntities
@@ -6911,12 +6929,6 @@
/**
* An empty list of expressions.
*/
- @deprecated // Use "Expression.EMPTY_LIST"
- static const List<Expression> EMPTY_ARRAY = EMPTY_LIST;
-
- /**
- * An empty list of expressions.
- */
static const List<Expression> EMPTY_LIST = const <Expression>[];
/**
@@ -7239,20 +7251,6 @@
Token get endToken => _superclass.endToken;
/**
- * Return the token for the 'extends' keyword.
- */
- @deprecated // Use "this.extendsKeyword"
- Token get keyword => extendsKeyword;
-
- /**
- * Set the token for the 'extends' keyword to the given [token].
- */
- @deprecated // Use "this.extendsKeyword"
- set keyword(Token token) {
- extendsKeyword = token;
- }
-
- /**
* Return the name of the class that is being extended.
*/
TypeName get superclass => _superclass;
@@ -7448,11 +7446,13 @@
}
@override
- bool get isConst => (keyword is KeywordToken) &&
+ bool get isConst =>
+ (keyword is KeywordToken) &&
(keyword as KeywordToken).keyword == Keyword.CONST;
@override
- bool get isFinal => (keyword is KeywordToken) &&
+ bool get isFinal =>
+ (keyword is KeywordToken) &&
(keyword as KeywordToken).keyword == Keyword.FINAL;
/**
@@ -7470,20 +7470,6 @@
}
/**
- * Return the token representing the 'this' keyword.
- */
- @deprecated // Use "this.thisKeyword"
- Token get thisToken => thisKeyword;
-
- /**
- * Set the token representing the 'this' keyword to the given [token].
- */
- @deprecated // Use "this.thisKeyword"
- set thisToken(Token token) {
- thisKeyword = token;
- }
-
- /**
* Return the name of the declared type of the parameter, or `null` if the
* parameter does not have a declared type. Note that if this is a
* function-typed field formal parameter this is the return type of the
@@ -7581,44 +7567,6 @@
Statement _body;
/**
- * Initialize a newly created for-each statement. The [awaitKeyword] can be
- * `null` if this is not an asynchronous for loop.
- */
- @deprecated // Use new ForEachStatement.withDeclaration(...)
- ForEachStatement.con1(
- this.awaitKeyword,
- this.forKeyword,
- this.leftParenthesis,
- DeclaredIdentifier loopVariable,
- this.inKeyword,
- Expression iterator,
- this.rightParenthesis,
- Statement body) {
- _loopVariable = _becomeParentOf(loopVariable);
- _iterable = _becomeParentOf(iterator);
- _body = _becomeParentOf(body);
- }
-
- /**
- * Initialize a newly created for-each statement. The [awaitKeyword] can be
- * `null` if this is not an asynchronous for loop.
- */
- @deprecated // Use new ForEachStatement.withReference(...)
- ForEachStatement.con2(
- this.awaitKeyword,
- this.forKeyword,
- this.leftParenthesis,
- SimpleIdentifier identifier,
- this.inKeyword,
- Expression iterator,
- this.rightParenthesis,
- Statement body) {
- _identifier = _becomeParentOf(identifier);
- _iterable = _becomeParentOf(iterator);
- _body = _becomeParentOf(body);
- }
-
- /**
* Initialize a newly created for-each statement whose loop control variable
* is declared internally (in the for-loop part). The [awaitKeyword] can be
* `null` if this is not an asynchronous for loop.
@@ -7713,12 +7661,6 @@
}
/**
- * Return the expression evaluated to produce the iterator.
- */
- @deprecated // Use "this.iterable"
- Expression get iterator => iterable;
-
- /**
* Return the declaration of the loop variable, or `null` if the loop variable
* is a simple identifier.
*/
@@ -8224,13 +8166,15 @@
/**
* Return `true` if this function declares a getter.
*/
- bool get isGetter => propertyKeyword != null &&
+ bool get isGetter =>
+ propertyKeyword != null &&
(propertyKeyword as KeywordToken).keyword == Keyword.GET;
/**
* Return `true` if this function declares a setter.
*/
- bool get isSetter => propertyKeyword != null &&
+ bool get isSetter =>
+ propertyKeyword != null &&
(propertyKeyword as KeywordToken).keyword == Keyword.SET;
/**
@@ -8879,6 +8823,9 @@
visitExpression(node);
@override
+ R visitConfiguration(Configuration node) => visitNode(node);
+
+ @override
R visitConstructorDeclaration(ConstructorDeclaration node) =>
visitClassMember(node);
@@ -8909,6 +8856,9 @@
R visitDoStatement(DoStatement node) => visitStatement(node);
@override
+ R visitDottedName(DottedName node) => visitNode(node);
+
+ @override
R visitDoubleLiteral(DoubleLiteral node) => visitLiteral(node);
@override
@@ -9491,20 +9441,6 @@
*/
NodeList<TypeName> get interfaces => _interfaces;
- /**
- * Return the token representing the 'implements' keyword.
- */
- @deprecated // Use "this.implementsKeyword"
- Token get keyword => implementsKeyword;
-
- /**
- * Set the token representing the 'implements' keyword to the given [token].
- */
- @deprecated // Use "this.implementsKeyword"
- set keyword(Token token) {
- implementsKeyword = token;
- }
-
@override
accept(AstVisitor visitor) => visitor.visitImplementsClause(this);
@@ -9647,30 +9583,17 @@
List<Annotation> metadata,
Token keyword,
StringLiteral libraryUri,
+ List<Configuration> configurations,
this.deferredKeyword,
this.asKeyword,
SimpleIdentifier prefix,
List<Combinator> combinators,
Token semicolon)
- : super(comment, metadata, keyword, libraryUri, combinators, semicolon) {
+ : super(comment, metadata, keyword, libraryUri, configurations,
+ combinators, semicolon) {
_prefix = _becomeParentOf(prefix);
}
- /**
- * The token representing the 'as' token, or `null` if the imported names are
- * not prefixed.
- */
- @deprecated // Use "this.asKeyword"
- Token get asToken => asKeyword;
-
- /**
- * The token representing the 'as' token to the given token.
- */
- @deprecated // Use "this.asKeyword"
- set asToken(Token token) {
- asKeyword = token;
- }
-
@override
Iterable get childEntities => super._childEntities
..add(_uri)
@@ -9680,21 +9603,6 @@
..addAll(combinators)
..add(semicolon);
- /**
- * Return the token representing the 'deferred' token, or `null` if the
- * imported is not deferred.
- */
- @deprecated // Use "this.deferredKeyword"
- Token get deferredToken => deferredKeyword;
-
- /**
- * Set the token representing the 'deferred' token to the given token.
- */
- @deprecated // Use "this.deferredKeyword"
- set deferredToken(Token token) {
- deferredKeyword = token;
- }
-
@override
ImportElement get element => super.element as ImportElement;
@@ -9796,6 +9704,8 @@
_mapToken(node.assertKeyword),
_mapToken(node.leftParenthesis),
_cloneNode(node.condition),
+ _mapToken(node.comma),
+ _cloneNode(node.message),
_mapToken(node.rightParenthesis),
_mapToken(node.semicolon));
@@ -9949,6 +9859,16 @@
}
@override
+ Configuration visitConfiguration(Configuration node) => new Configuration(
+ _mapToken(node.ifKeyword),
+ _mapToken(node.leftParenthesis),
+ _cloneNode(node.name),
+ _mapToken(node.equalToken),
+ _cloneNode(node.value),
+ _mapToken(node.rightParenthesis),
+ _cloneNode(node.libraryUri));
+
+ @override
ConstructorDeclaration visitConstructorDeclaration(
ConstructorDeclaration node) {
ConstructorDeclaration copy = new ConstructorDeclaration(
@@ -10018,6 +9938,10 @@
_mapToken(node.semicolon));
@override
+ DottedName visitDottedName(DottedName node) =>
+ new DottedName(_cloneNodeList(node.components));
+
+ @override
DoubleLiteral visitDoubleLiteral(DoubleLiteral node) {
DoubleLiteral copy = new DoubleLiteral(_mapToken(node.literal), node.value);
copy.propagatedType = node.propagatedType;
@@ -10055,6 +9979,7 @@
_cloneNodeList(node.metadata),
_mapToken(node.keyword),
_cloneNode(node.uri),
+ _cloneNodeList(node.configurations),
_cloneNodeList(node.combinators),
_mapToken(node.semicolon));
copy.element = node.element;
@@ -10239,6 +10164,7 @@
_cloneNodeList(node.metadata),
_mapToken(node.keyword),
_cloneNode(node.uri),
+ _cloneNodeList(node.configurations),
_mapToken(node.deferredKeyword),
_mapToken(node.asKeyword),
_cloneNode(node.prefix),
@@ -10905,17 +10831,6 @@
int get precedence => 15;
/**
- * If the AST structure has been resolved, and the function being invoked is
- * known based on propagated type information, then return the parameter
- * element representing the parameter to which the value of the index
- * expression will be bound. Otherwise, return `null`.
- */
- @deprecated // Use "expression.propagatedParameterElement"
- ParameterElement get propagatedParameterElementForIndex {
- return _propagatedParameterElementForIndex;
- }
-
- /**
* Return the expression used to compute the object being indexed. If this
* index expression is not part of a cascade expression, then this is the same
* as [target]. If this index expression is part of a cascade expression, then
@@ -10936,17 +10851,6 @@
}
/**
- * If the AST structure has been resolved, and the function being invoked is
- * known based on static type information, then return the parameter element
- * representing the parameter to which the value of the index expression will
- * be bound. Otherwise, return `null`.
- */
- @deprecated // Use "expression.propagatedParameterElement"
- ParameterElement get staticParameterElementForIndex {
- return _staticParameterElementForIndex;
- }
-
- /**
* Return the expression used to compute the object being indexed, or `null`
* if this index expression is part of a cascade expression.
*
@@ -11130,7 +11034,8 @@
* Return `true` if this creation expression is used to invoke a constant
* constructor.
*/
- bool get isConst => keyword is KeywordToken &&
+ bool get isConst =>
+ keyword is KeywordToken &&
(keyword as KeywordToken).keyword == Keyword.CONST;
@override
@@ -11594,20 +11499,6 @@
Token get keyword => libraryKeyword;
/**
- * Return the token representing the 'library' token.
- */
- @deprecated // Use "this.libraryKeyword"
- Token get libraryToken => libraryKeyword;
-
- /**
- * Set the token representing the 'library' token to the given [token].
- */
- @deprecated // Use "this.libraryKeyword"
- set libraryToken(Token token) {
- libraryKeyword = token;
- }
-
- /**
* Return the name of the library being defined.
*/
LibraryIdentifier get name => _name;
@@ -12096,7 +11987,8 @@
/**
* Return `true` if this method declares a getter.
*/
- bool get isGetter => propertyKeyword != null &&
+ bool get isGetter =>
+ propertyKeyword != null &&
(propertyKeyword as KeywordToken).keyword == Keyword.GET;
/**
@@ -12107,13 +11999,15 @@
/**
* Return `true` if this method declares a setter.
*/
- bool get isSetter => propertyKeyword != null &&
+ bool get isSetter =>
+ propertyKeyword != null &&
(propertyKeyword as KeywordToken).keyword == Keyword.SET;
/**
* Return `true` if this method is declared to be a static method.
*/
- bool get isStatic => modifierKeyword != null &&
+ bool get isStatic =>
+ modifierKeyword != null &&
(modifierKeyword as KeywordToken).keyword == Keyword.STATIC;
/**
@@ -12291,26 +12185,6 @@
_methodName = _becomeParentOf(identifier);
}
- /**
- * The operator that separates the target from the method name, or `null`
- * if there is no target. In an ordinary method invocation this will be a
- * period ('.'). In a cascade section this will be the cascade operator
- * ('..').
- */
- @deprecated // Use this.operator
- Token get period => operator;
-
- /**
- * The operator that separates the target from the method name, or `null`
- * if there is no target. In an ordinary method invocation this will be a
- * period ('.'). In a cascade section this will be the cascade operator
- * ('..').
- */
- @deprecated // Use this.operator
- void set period(Token value) {
- operator = value;
- }
-
@override
int get precedence => 15;
@@ -12512,6 +12386,12 @@
Token keyword;
/**
+ * The configurations used to control which library will actually be loaded at
+ * run-time.
+ */
+ NodeList<Configuration> _configurations;
+
+ /**
* The combinators used to control which names are imported or exported.
*/
NodeList<Combinator> _combinators;
@@ -12527,9 +12407,16 @@
* corresponding attribute. The list of [combinators] can be `null` if there
* are no combinators.
*/
- NamespaceDirective(Comment comment, List<Annotation> metadata, this.keyword,
- StringLiteral libraryUri, List<Combinator> combinators, this.semicolon)
+ NamespaceDirective(
+ Comment comment,
+ List<Annotation> metadata,
+ this.keyword,
+ StringLiteral libraryUri,
+ List<Configuration> configurations,
+ List<Combinator> combinators,
+ this.semicolon)
: super(comment, metadata, libraryUri) {
+ _configurations = new NodeList<Configuration>(this, configurations);
_combinators = new NodeList<Combinator>(this, combinators);
}
@@ -12538,6 +12425,12 @@
*/
NodeList<Combinator> get combinators => _combinators;
+ /**
+ * Return the configurations used to control which library will actually be
+ * loaded at run-time.
+ */
+ NodeList<Configuration> get configurations => _configurations;
+
@override
Token get endToken => semicolon;
@@ -12583,20 +12476,6 @@
Token get endToken => _name.endToken;
/**
- * Get the token representing the 'native' keyword.
- */
- @deprecated // Use "this.nativeKeyword"
- Token get keyword => nativeKeyword;
-
- /**
- * Set the token representing the 'native' keyword to the given [token].
- */
- @deprecated // Use "this.nativeKeyword"
- set keyword(Token token) {
- nativeKeyword = token;
- }
-
- /**
* Return the name of the native object that implements the class.
*/
StringLiteral get name => _name;
@@ -12664,22 +12543,6 @@
Token get endToken => semicolon;
/**
- * Return the token representing 'native' that marks the start of the function
- * body.
- */
- @deprecated // Use "this.nativeKeyword"
- Token get nativeToken => nativeKeyword;
-
- /**
- * Set the token representing 'native' that marks the start of the function
- * body to the given [token].
- */
- @deprecated // Use "this.nativeKeyword"
- set nativeToken(Token token) {
- nativeKeyword = token;
- }
-
- /**
* Return the string literal representing the string after the 'native' token.
*/
StringLiteral get stringLiteral => _stringLiteral;
@@ -12750,7 +12613,8 @@
int get length => _elements.length;
@deprecated // Never intended for public use.
- void set length(int value) {
+ @override
+ void set length(int newLength) {
throw new UnsupportedError("Cannot resize NodeList.");
}
@@ -12824,12 +12688,6 @@
_elements.removeAt(index);
return removedNode;
}
-
- /**
- * Create an empty list with the given [owner].
- */
- @deprecated // Use "new NodeList<E>(owner)"
- static NodeList create(AstNode owner) => new NodeList(owner);
}
/**
@@ -12865,22 +12723,6 @@
this._endOffset = endOffset == null ? startOffset : endOffset;
/**
- * Initialize a newly created locator to locate an [AstNode] by locating the
- * node within an AST structure that corresponds to the given [offset] in the
- * source.
- */
- @deprecated // Use new NodeLocator(offset)
- NodeLocator.con1(int offset) : this(offset);
-
- /**
- * Initialize a newly created locator to locate an [AstNode] by locating the
- * node within an AST structure that corresponds to the given range of
- * characters (between the [startOffset] and [endOffset] in the source.
- */
- @deprecated // Use new NodeLocator(startOffset, endOffset)
- NodeLocator.con2(this._startOffset, this._endOffset);
-
- /**
* Return the node that was found that corresponds to the given source range
* or `null` if there is no such node.
*/
@@ -13120,6 +12962,10 @@
node.condition = _newNode as Expression;
return true;
}
+ if (identical(node._message, _oldNode)) {
+ node.message = _newNode as Expression;
+ return true;
+ }
return visitNode(node);
}
@@ -13304,6 +13150,21 @@
}
@override
+ bool visitConfiguration(Configuration node) {
+ if (identical(node.name, _oldNode)) {
+ node.name = _newNode as DottedName;
+ return true;
+ } else if (identical(node.value, _oldNode)) {
+ node.value = _newNode as StringLiteral;
+ return true;
+ } else if (identical(node.libraryUri, _oldNode)) {
+ node.libraryUri = _newNode as StringLiteral;
+ return true;
+ }
+ return visitNode(node);
+ }
+
+ @override
bool visitConstructorDeclaration(ConstructorDeclaration node) {
if (identical(node.returnType, _oldNode)) {
node.returnType = _newNode as Identifier;
@@ -13396,6 +13257,14 @@
}
@override
+ bool visitDottedName(DottedName node) {
+ if (_replaceInList(node.components)) {
+ return true;
+ }
+ return visitNode(node);
+ }
+
+ @override
bool visitDoubleLiteral(DoubleLiteral node) => visitNode(node);
@override
@@ -14479,20 +14348,6 @@
@override
Token get keyword => partKeyword;
- /**
- * Return the token representing the 'part' token.
- */
- @deprecated // Use "this.partKeyword"
- Token get partToken => partKeyword;
-
- /**
- * Set the token representing the 'part' token to the given [token].
- */
- @deprecated // Use "this.partKeyword"
- set partToken(Token token) {
- partKeyword = token;
- }
-
@override
CompilationUnitElement get uriElement => element as CompilationUnitElement;
@@ -14568,34 +14423,6 @@
_libraryName = _becomeParentOf(libraryName);
}
- /**
- * Return the token representing the 'of' token.
- */
- @deprecated // Use "this.ofKeyword"
- Token get ofToken => ofKeyword;
-
- /**
- * Set the token representing the 'of' token to the given [token].
- */
- @deprecated // Use "this.ofKeyword"
- set ofToken(Token token) {
- ofKeyword = token;
- }
-
- /**
- * Return the token representing the 'part' token.
- */
- @deprecated // Use "this.partKeyword"
- Token get partToken => partKeyword;
-
- /**
- * Set the token representing the 'part' token to the given [token].
- */
- @deprecated // Use "this.partKeyword"
- set partToken(Token token) {
- partKeyword = token;
- }
-
@override
accept(AstVisitor visitor) => visitor.visitPartOfDirective(this);
@@ -14692,28 +14519,6 @@
* element representing the parameter to which the value of the operand will
* be bound. Otherwise, return `null`.
*/
- @deprecated // Use "expression.propagatedParameterElement"
- ParameterElement get propagatedParameterElementForOperand {
- return _propagatedParameterElementForOperand;
- }
-
- /**
- * If the AST structure has been resolved, and the function being invoked is
- * known based on static type information, then return the parameter element
- * representing the parameter to which the value of the operand will be bound.
- * Otherwise, return `null`.
- */
- @deprecated // Use "expression.propagatedParameterElement"
- ParameterElement get staticParameterElementForOperand {
- return _staticParameterElementForOperand;
- }
-
- /**
- * If the AST structure has been resolved, and the function being invoked is
- * known based on propagated type information, then return the parameter
- * element representing the parameter to which the value of the operand will
- * be bound. Otherwise, return `null`.
- */
ParameterElement get _propagatedParameterElementForOperand {
if (propagatedElement == null) {
return null;
@@ -14965,28 +14770,6 @@
* element representing the parameter to which the value of the operand will
* be bound. Otherwise, return `null`.
*/
- @deprecated // Use "expression.propagatedParameterElement"
- ParameterElement get propagatedParameterElementForOperand {
- return _propagatedParameterElementForOperand;
- }
-
- /**
- * If the AST structure has been resolved, and the function being invoked is
- * known based on static type information, then return the parameter element
- * representing the parameter to which the value of the operand will be bound.
- * Otherwise, return `null`.
- */
- @deprecated // Use "expression.propagatedParameterElement"
- ParameterElement get staticParameterElementForOperand {
- return _staticParameterElementForOperand;
- }
-
- /**
- * If the AST structure has been resolved, and the function being invoked is
- * known based on propagated type information, then return the parameter
- * element representing the parameter to which the value of the operand will
- * be bound. Otherwise, return `null`.
- */
ParameterElement get _propagatedParameterElementForOperand {
if (propagatedElement == null) {
return null;
@@ -15279,6 +15062,12 @@
}
@override
+ R visitConfiguration(Configuration node) {
+ node.visitChildren(this);
+ return null;
+ }
+
+ @override
R visitConstructorDeclaration(ConstructorDeclaration node) {
node.visitChildren(this);
return null;
@@ -15321,6 +15110,12 @@
}
@override
+ R visitDottedName(DottedName node) {
+ node.visitChildren(this);
+ return null;
+ }
+
+ @override
R visitDoubleLiteral(DoubleLiteral node) {
node.visitChildren(this);
return null;
@@ -15883,20 +15678,6 @@
@override
Token get endToken => _argumentList.endToken;
- /**
- * Return the token for the 'this' keyword.
- */
- @deprecated // Use "this.thisKeyword"
- Token get keyword => thisKeyword;
-
- /**
- * Set the token for the 'this' keyword to the given [token].
- */
- @deprecated // Use "this.thisKeyword"
- set keyword(Token token) {
- thisKeyword = token;
- }
-
@override
accept(AstVisitor visitor) =>
visitor.visitRedirectingConstructorInvocation(this);
@@ -15934,20 +15715,6 @@
@override
Token get endToken => rethrowKeyword;
- /**
- * Return the token representing the 'rethrow' keyword.
- */
- @deprecated // Use "this.rethrowKeyword"
- Token get keyword => rethrowKeyword;
-
- /**
- * Set the token representing the 'rethrow' keyword to the given [token].
- */
- @deprecated // Use "this.rethrowKeyword"
- set keyword(Token token) {
- rethrowKeyword = token;
- }
-
@override
int get precedence => 0;
@@ -16015,20 +15782,6 @@
_expression = _becomeParentOf(expression);
}
- /**
- * Return the token representing the 'return' keyword.
- */
- @deprecated // Use "this.returnKeyword"
- Token get keyword => returnKeyword;
-
- /**
- * Set the token representing the 'return' keyword to the given [token].
- */
- @deprecated // Use "this.returnKeyword"
- set keyword(Token token) {
- returnKeyword = token;
- }
-
@override
accept(AstVisitor visitor) => visitor.visitReturnStatement(this);
@@ -16370,6 +16123,9 @@
R visitConditionalExpression(ConditionalExpression node) => null;
@override
+ R visitConfiguration(Configuration node) => null;
+
+ @override
R visitConstructorDeclaration(ConstructorDeclaration node) => null;
@override
@@ -16391,6 +16147,9 @@
R visitDoStatement(DoStatement node) => null;
@override
+ R visitDottedName(DottedName node) => null;
+
+ @override
R visitDoubleLiteral(DoubleLiteral node) => null;
@override
@@ -16686,11 +16445,13 @@
Token get endToken => identifier.endToken;
@override
- bool get isConst => (keyword is KeywordToken) &&
+ bool get isConst =>
+ (keyword is KeywordToken) &&
(keyword as KeywordToken).keyword == Keyword.CONST;
@override
- bool get isFinal => (keyword is KeywordToken) &&
+ bool get isFinal =>
+ (keyword is KeywordToken) &&
(keyword as KeywordToken).keyword == Keyword.FINAL;
/**
@@ -17063,12 +16824,6 @@
String _value;
/**
- * The toolkit specific element associated with this literal, or `null`.
- */
- @deprecated // No replacement
- Element toolkitElement;
-
- /**
* Initialize a newly created simple string literal.
*/
SimpleStringLiteral(this.literal, String value) {
@@ -17393,14 +17148,6 @@
* [IllegalArgumentException] if the string is not a constant string without
* any string interpolation.
*/
- @deprecated // Use "this.stringValue"
- void appendStringValue(StringBuffer buffer) => _appendStringValue(buffer);
-
- /**
- * Append the value of this string literal to the given [buffer]. Throw an
- * [IllegalArgumentException] if the string is not a constant string without
- * any string interpolation.
- */
void _appendStringValue(StringBuffer buffer);
}
@@ -17492,20 +17239,6 @@
@override
Token get endToken => _argumentList.endToken;
- /**
- * Return the token for the 'super' keyword.
- */
- @deprecated // Use "this.superKeyword"
- Token get keyword => superKeyword;
-
- /**
- * Set the token for the 'super' keyword to the given [token].
- */
- @deprecated // Use "this.superKeyword"
- set keyword(Token token) {
- superKeyword = token;
- }
-
@override
accept(AstVisitor visitor) => visitor.visitSuperConstructorInvocation(this);
@@ -17542,20 +17275,6 @@
@override
Token get endToken => superKeyword;
- /**
- * Return the token for the 'super' keyword.
- */
- @deprecated // Use "this.superKeyword"
- Token get keyword => superKeyword;
-
- /**
- * Set the token for the 'super' keyword to the given [token].
- */
- @deprecated // Use "this.superKeyword"
- set keyword(Token token) {
- superKeyword = token;
- }
-
@override
int get precedence => 16;
@@ -17810,20 +17529,6 @@
}
/**
- * Return the token representing the 'switch' keyword.
- */
- @deprecated // Use "this.switchKeyword"
- Token get keyword => switchKeyword;
-
- /**
- * Set the token representing the 'switch' keyword to the given [token].
- */
- @deprecated // Use "this.switchKeyword"
- set keyword(Token token) {
- switchKeyword = token;
- }
-
- /**
* Return the switch members that can be selected by the expression.
*/
NodeList<SwitchMember> get members => _members;
@@ -17907,20 +17612,6 @@
@override
Token get endToken => thisKeyword;
- /**
- * Return the token representing the 'this' keyword.
- */
- @deprecated // Use "this.thisKeyword"
- Token get keyword => thisKeyword;
-
- /**
- * Set the token representing the 'this' keyword to the given [token].
- */
- @deprecated // Use "this.thisKeyword"
- set keyword(Token token) {
- thisKeyword = token;
- }
-
@override
int get precedence => 16;
@@ -17985,20 +17676,6 @@
_expression = _becomeParentOf(expression);
}
- /**
- * Return the token representing the 'throw' keyword.
- */
- @deprecated // Use "this.throwKeyword"
- Token get keyword => throwKeyword;
-
- /**
- * Set the token representing the 'throw' keyword to the given [token].
- */
- @deprecated // Use "this.throwKeyword"
- set keyword(Token token) {
- throwKeyword = token;
- }
-
@override
int get precedence => 0;
@@ -18127,6 +17804,10 @@
Object visitAssertStatement(AssertStatement node) {
_writer.print("assert (");
_visitNode(node.condition);
+ if (node.message != null) {
+ _writer.print(', ');
+ _visitNode(node.message);
+ }
_writer.print(");");
return null;
}
@@ -18281,6 +17962,16 @@
}
@override
+ Object visitConfiguration(Configuration node) {
+ _writer.print('if (');
+ _visitNode(node.name);
+ _visitNodeWithPrefix(" == ", node.value);
+ _writer.print(') ');
+ _visitNode(node.libraryUri);
+ return null;
+ }
+
+ @override
Object visitConstructorDeclaration(ConstructorDeclaration node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_visitTokenWithSuffix(node.externalKeyword, " ");
@@ -18350,6 +18041,12 @@
}
@override
+ Object visitDottedName(DottedName node) {
+ _visitNodeListWithSeparator(node.components, ".");
+ return null;
+ }
+
+ @override
Object visitDoubleLiteral(DoubleLiteral node) {
_writer.print(node.literal.lexeme);
return null;
@@ -19347,20 +19044,6 @@
@override
Token get firstTokenAfterCommentAndMetadata => typedefKeyword;
-
- /**
- * Return the token representing the 'typedef' keyword.
- */
- @deprecated // Use "this.typedefKeyword"
- Token get keyword => typedefKeyword;
-
- /**
- * Set the token representing the 'typedef' keyword to the given [token].
- */
- @deprecated // Use "this.typedefKeyword"
- set keyword(Token token) {
- typedefKeyword = token;
- }
}
/**
@@ -19643,21 +19326,6 @@
Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
/**
- * Return the token representing the 'extends' keyword, or `null` if there is
- * no explicit upper bound.
- */
- @deprecated // Use "this.extendsKeyword"
- Token get keyword => extendsKeyword;
-
- /**
- * Set the token representing the 'extends' keyword to the given [token].
- */
- @deprecated // Use "this.extendsKeyword"
- set keyword(Token token) {
- extendsKeyword = token;
- }
-
- /**
* Return the name of the type parameter.
*/
SimpleIdentifier get name => _name;
@@ -19808,6 +19476,9 @@
R visitConditionalExpression(ConditionalExpression node) => visitNode(node);
@override
+ R visitConfiguration(Configuration node) => visitNode(node);
+
+ @override
R visitConstructorDeclaration(ConstructorDeclaration node) => visitNode(node);
@override
@@ -19830,6 +19501,9 @@
R visitDoStatement(DoStatement node) => visitNode(node);
@override
+ R visitDottedName(DottedName node) => visitNode(node);
+
+ @override
R visitDoubleLiteral(DoubleLiteral node) => visitNode(node);
@override
@@ -20404,7 +20078,8 @@
* Return `true` if the variables in this list were declared with the 'const'
* modifier.
*/
- bool get isConst => keyword is KeywordToken &&
+ bool get isConst =>
+ keyword is KeywordToken &&
(keyword as KeywordToken).keyword == Keyword.CONST;
/**
@@ -20413,7 +20088,8 @@
* `false` even though they are implicitly final. (In other words, this is a
* syntactic check rather than a semantic check.)
*/
- bool get isFinal => keyword is KeywordToken &&
+ bool get isFinal =>
+ keyword is KeywordToken &&
(keyword as KeywordToken).keyword == Keyword.FINAL;
/**
@@ -20583,20 +20259,6 @@
@override
Token get endToken => _body.endToken;
- /**
- * Return the token representing the 'while' keyword.
- */
- @deprecated // Use "this.whileKeyword"
- Token get keyword => whileKeyword;
-
- /**
- * Set the token representing the 'while' keyword to the given [token].
- */
- @deprecated // Use "this.whileKeyword"
- set keyword(Token token) {
- whileKeyword = token;
- }
-
@override
accept(AstVisitor visitor) => visitor.visitWhileStatement(this);
@@ -20644,14 +20306,6 @@
Token get endToken => _mixinTypes.endToken;
/**
- * Set the token representing the 'with' keyword to the given [token].
- */
- @deprecated // Use "this.withKeyword"
- void set mixinKeyword(Token token) {
- this.withKeyword = token;
- }
-
- /**
* Return the names of the mixins that were specified.
*/
NodeList<TypeName> get mixinTypes => _mixinTypes;
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index 8638c84..f2a8c96 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -2,26 +2,27 @@
// for 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 engine.constant;
+library analyzer.src.generated.constant;
import 'dart:collection';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/engine.dart'
+ show AnalysisEngine, RecordingErrorListener;
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
+import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType;
+import 'package:analyzer/src/generated/source.dart' show Source;
+import 'package:analyzer/src/generated/type_system.dart'
+ show TypeSystem, TypeSystemImpl;
+import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart' show ParameterKind;
import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:analyzer/src/task/dart.dart';
-import 'ast.dart';
-import 'element.dart';
-import 'engine.dart' show AnalysisEngine, RecordingErrorListener;
-import 'error.dart';
-import 'java_core.dart';
-import 'resolver.dart' show TypeProvider;
-import 'scanner.dart' show Token, TokenType;
-import 'source.dart' show Source;
-import 'type_system.dart' show TypeSystem, TypeSystemImpl;
-import 'utilities_collection.dart';
-import 'utilities_dart.dart' show ParameterKind;
-
/**
* Callback used by [ReferenceFinder] to report that a dependency was found.
*/
@@ -57,9 +58,6 @@
BoolState(this.value);
@override
- bool get hasExactValue => true;
-
- @override
int get hashCode => value == null ? 0 : (value ? 2 : 3);
@override
@@ -1972,33 +1970,6 @@
*/
abstract class DartObject {
/**
- * Return the boolean value of this object, or `null` if either the value of
- * this object is not known or this object is not of type 'bool'.
- *
- * Deprecated. Use [toBoolValue].
- */
- @deprecated
- bool get boolValue;
-
- /**
- * Return the floating point value of this object, or `null` if either the
- * value of this object is not known or this object is not of type 'double'.
- *
- * Deprecated. Use [toDoubleValue].
- */
- @deprecated
- double get doubleValue;
-
- /**
- * Return `true` if this object's value can be represented exactly.
- *
- * Deprecated. The semantics of this method were not clear. One semantic is
- * covered by [hasKnownValue].
- */
- @deprecated
- bool get hasExactValue;
-
- /**
* Return `true` if the value of the object being represented is known.
*
* This method will return `false` if
@@ -2017,45 +1988,11 @@
bool get hasKnownValue;
/**
- * Return the integer value of this object, or `null` if either the value of
- * this object is not known or this object is not of type 'int'.
- *
- * Deprecated. Use [toIntValue].
- */
- @deprecated
- int get intValue;
-
- /**
- * Return `true` if this object represents the value 'false'.
- *
- * Deprecated. Use `object.toBoolValue() == false`.
- */
- @deprecated
- bool get isFalse;
-
- /**
* Return `true` if the object being represented represents the value 'null'.
*/
bool get isNull;
/**
- * Return `true` if this object represents the value 'true'.
- *
- * Deprecated. Use `object.toBoolValue() == true`.
- */
- @deprecated
- bool get isTrue;
-
- /**
- * Return the string value of this object, or `null` if either the value of
- * this object is not known or this object is not of type 'String'.
- *
- * Deprecated. Use [toStringValue].
- */
- @deprecated
- String get stringValue;
-
- /**
* Return a representation of the type of the object being represented.
*
* For values resulting from the invocation of a 'const' constructor, this
@@ -2080,16 +2017,6 @@
ParameterizedType get type;
/**
- * Return this object's value if it can be represented exactly, or `null` if
- * either the value cannot be represented exactly or if the value is `null`.
- * Clients should use `hasExactValue` to distinguish between these two cases.
- *
- * Deprecated. Use one of the `isXValue()` methods.
- */
- @deprecated
- Object get value;
-
- /**
* Return a representation of the value of the field with the given [name].
*
* Return `null` if either the object being represented does not have a field
@@ -2169,7 +2096,7 @@
* * this object is not of type 'Type', or
* * the value of the object being represented is `null`.
*/
- ParameterizedType toTypeValue();
+ DartType toTypeValue();
}
/**
@@ -2566,30 +2493,14 @@
return new DartObjectImpl(type, GenericState.UNKNOWN_VALUE);
}
- @deprecated
- @override
- bool get boolValue => toBoolValue();
-
- @deprecated
- @override
- double get doubleValue => toDoubleValue();
-
HashMap<String, DartObjectImpl> get fields => _state.fields;
- @deprecated
- @override
- bool get hasExactValue => _state.hasExactValue;
-
@override
int get hashCode => JenkinsSmiHash.hash2(type.hashCode, _state.hashCode);
@override
bool get hasKnownValue => !_state.isUnknown;
- @deprecated
- @override
- int get intValue => toIntValue();
-
/**
* Return `true` if this object represents an object whose type is 'bool'.
*/
@@ -2601,18 +2512,9 @@
*/
bool get isBoolNumStringOrNull => _state.isBoolNumStringOrNull;
- @deprecated
- @override
- bool get isFalse => toBoolValue() == false;
-
@override
bool get isNull => _state is NullState;
- @deprecated
- @override
- bool get isTrue =>
- _state is BoolState && identical((_state as BoolState).value, true);
-
/**
* Return `true` if this object represents an unknown value.
*/
@@ -2624,14 +2526,6 @@
*/
bool get isUserDefinedObject => _state is GenericState;
- @deprecated
- @override
- String get stringValue => toStringValue();
-
- @deprecated
- @override
- Object get value => _state.value;
-
@override
bool operator ==(Object object) {
if (object is! DartObjectImpl) {
@@ -3130,13 +3024,10 @@
}
@override
- ParameterizedType toTypeValue() {
+ DartType toTypeValue() {
if (_state is TypeState) {
- Element element = (_state as TypeState).value;
- if (element is ClassElement) {
- return element.type;
- }
- if (element is FunctionElement) {
+ Element element = (_state as TypeState)._element;
+ if (element is TypeDefiningElement) {
return element.type;
}
}
@@ -3240,9 +3131,6 @@
DoubleState(this.value);
@override
- bool get hasExactValue => true;
-
- @override
int get hashCode => value == null ? 0 : value.hashCode;
@override
@@ -3817,14 +3705,6 @@
this._errors = errors == null ? <AnalysisError>[] : errors;
}
- @deprecated // Use new EvaluationResultImpl(value)
- EvaluationResultImpl.con1(this.value) {
- this._errors = new List<AnalysisError>(0);
- }
-
- @deprecated // Use new EvaluationResultImpl(value, errors)
- EvaluationResultImpl.con2(this.value, List<AnalysisError> this._errors);
-
List<AnalysisError> get errors => _errors;
bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) {
@@ -4021,11 +3901,6 @@
HashMap<String, DartObjectImpl> get fields => null;
/**
- * Return `true` if this object's value can be represented exactly.
- */
- bool get hasExactValue => false;
-
- /**
* Return `true` if this object represents an object whose type is 'bool'.
*/
bool get isBool => false;
@@ -4047,13 +3922,6 @@
String get typeName;
/**
- * Return this object's value if it can be represented exactly, or `null` if
- * either the value cannot be represented exactly or if the value is `null`.
- * Clients should use [hasExactValue] to distinguish between these two cases.
- */
- Object get value => null;
-
- /**
* Return the result of invoking the '+' operator on this object with the
* [rightOperand].
*
@@ -4448,9 +4316,6 @@
IntState(this.value);
@override
- bool get hasExactValue => true;
-
- @override
int get hashCode => value == null ? 0 : value.hashCode;
@override
@@ -4907,17 +4772,6 @@
ListState(this._elements);
@override
- bool get hasExactValue {
- int count = _elements.length;
- for (int i = 0; i < count; i++) {
- if (!_elements[i].hasExactValue) {
- return false;
- }
- }
- return true;
- }
-
- @override
int get hashCode {
int value = 0;
int count = _elements.length;
@@ -4931,20 +4785,6 @@
String get typeName => "List";
@override
- List<Object> get value {
- int count = _elements.length;
- List<Object> result = new List<Object>(count);
- for (int i = 0; i < count; i++) {
- DartObjectImpl element = _elements[i];
- if (!element.hasExactValue) {
- return null;
- }
- result[i] = element.value;
- }
- return result;
- }
-
- @override
bool operator ==(Object object) {
if (object is! ListState) {
return false;
@@ -5015,16 +4855,6 @@
MapState(this._entries);
@override
- bool get hasExactValue {
- for (DartObjectImpl key in _entries.keys) {
- if (!key.hasExactValue || !_entries[key].hasExactValue) {
- return false;
- }
- }
- return true;
- }
-
- @override
int get hashCode {
int value = 0;
for (DartObjectImpl key in _entries.keys.toSet()) {
@@ -5037,19 +4867,6 @@
String get typeName => "Map";
@override
- Map<Object, Object> get value {
- HashMap<Object, Object> result = new HashMap<Object, Object>();
- for (DartObjectImpl key in _entries.keys) {
- DartObjectImpl value = _entries[key];
- if (!key.hasExactValue || !value.hasExactValue) {
- return null;
- }
- result[key.value] = value.value;
- }
- return result;
- }
-
- @override
bool operator ==(Object object) {
if (object is! MapState) {
return false;
@@ -5119,9 +4936,6 @@
static NullState NULL_STATE = new NullState();
@override
- bool get hasExactValue => true;
-
- @override
int get hashCode => 0;
@override
@@ -5378,9 +5192,6 @@
StringState(this.value);
@override
- bool get hasExactValue => true;
-
- @override
int get hashCode => value == null ? 0 : value.hashCode;
@override
@@ -5466,9 +5277,6 @@
SymbolState(this.value);
@override
- bool get hasExactValue => true;
-
- @override
int get hashCode => value == null ? 0 : value.hashCode;
@override
@@ -5534,9 +5342,6 @@
String get typeName => "Type";
@override
- Element get value => _element;
-
- @override
bool operator ==(Object object) =>
object is TypeState && (_element == object._element);
diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
index 334f4e8..fcf2511 100644
--- a/pkg/analyzer/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -2,28 +2,28 @@
// for 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 engine.element;
+library analyzer.src.generated.element;
import 'dart:collection';
import 'dart:math' show min;
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart'
+ show DartObject, EvaluationResultImpl;
+import 'package:analyzer/src/generated/engine.dart'
+ show AnalysisContext, AnalysisEngine, AnalysisException;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart' show Keyword;
+import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/task/model.dart' show AnalysisTarget;
-import 'ast.dart';
-import 'constant.dart' show DartObject, EvaluationResultImpl;
-import 'engine.dart' show AnalysisContext, AnalysisEngine;
-import 'html.dart' show XmlAttributeNode, XmlTagNode;
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'resolver.dart';
-import 'scanner.dart' show Keyword;
-import 'sdk.dart' show DartSdk;
-import 'source.dart';
-import 'utilities_collection.dart';
-import 'utilities_dart.dart';
-
/**
* For AST nodes that could be in both the getter and setter contexts
* ([IndexExpression]s and [SimpleIdentifier]s), the additional resolved
@@ -215,13 +215,6 @@
bool get isProxy;
/**
- * Return `true` if this class is a mixin application. Deprecated--please
- * use [isMixinApplication] instead.
- */
- @deprecated
- bool get isTypedef;
-
- /**
* Return `true` if this class can validly be used as a mixin when defining
* another class. The behavior of this method is defined by the Dart Language
* Specification in section 9:
@@ -483,12 +476,6 @@
*/
class ClassElementImpl extends ElementImpl implements ClassElement {
/**
- * An empty list of class elements.
- */
- @deprecated // Use ClassElement.EMPTY_LIST
- static const List<ClassElement> EMPTY_ARRAY = const <ClassElement>[];
-
- /**
* A list containing all of the accessors (getters and setters) contained in
* this class.
*/
@@ -765,10 +752,6 @@
}
@override
- @deprecated
- bool get isTypedef => isMixinApplication;
-
- @override
bool get isValidMixin => hasModifier(Modifier.MIXIN);
@override
@@ -1424,13 +1407,6 @@
class CompilationUnitElementImpl extends UriReferencedElementImpl
implements CompilationUnitElement {
/**
- * An empty list of compilation unit elements.
- */
- @deprecated // Use CompilationUnitElement.EMPTY_LIST
- static const List<CompilationUnitElement> EMPTY_ARRAY =
- const <CompilationUnitElement>[];
-
- /**
* The source that corresponds to this compilation unit.
*/
Source source;
@@ -1735,19 +1711,6 @@
/**
* Initialize a newly created field element to have the given [name].
*/
- @deprecated // Use new ConstFieldElementImpl.forNode(name)
- ConstFieldElementImpl.con1(Identifier name) : super.forNode(name);
-
- /**
- * Initialize a newly created synthetic field element to have the given
- * [name] and [offset].
- */
- @deprecated // Use new ConstFieldElementImpl(name, offset)
- ConstFieldElementImpl.con2(String name, int offset) : super(name, offset);
-
- /**
- * Initialize a newly created field element to have the given [name].
- */
ConstFieldElementImpl.forNode(Identifier name) : super.forNode(name);
@override
@@ -1860,13 +1823,6 @@
class ConstructorElementImpl extends ExecutableElementImpl
implements ConstructorElement {
/**
- * An empty list of constructor elements.
- */
- @deprecated // Use ConstructorElement.EMPTY_LIST
- static const List<ConstructorElement> EMPTY_ARRAY =
- const <ConstructorElement>[];
-
- /**
* The constructor to which this constructor is redirecting.
*/
ConstructorElement redirectedConstructor;
@@ -1990,10 +1946,13 @@
class ConstructorMember extends ExecutableMember implements ConstructorElement {
/**
* Initialize a newly created element to represent a constructor, based on the
- * [baseElement], defined by the [definingType].
+ * [baseElement], defined by the [definingType]. If [type] is passed, it
+ * represents the full type of the member, and will take precedence over
+ * the [definingType].
*/
- ConstructorMember(ConstructorElement baseElement, InterfaceType definingType)
- : super(baseElement, definingType);
+ ConstructorMember(ConstructorElement baseElement, InterfaceType definingType,
+ [FunctionType type])
+ : super(baseElement, definingType, type);
@override
ConstructorElement get baseElement => super.baseElement as ConstructorElement;
@@ -2081,10 +2040,7 @@
if (baseType == substitutedType) {
return constructor;
}
- // TODO(brianwilkerson) Consider caching the substituted type in the
- // instance. It would use more memory but speed up some operations.
- // We need to see how often the type is being re-computed.
- return new ConstructorMember(constructor, definingType);
+ return new ConstructorMember(constructor, definingType, substitutedType);
}
}
@@ -2202,17 +2158,6 @@
String get name;
/**
- * Return the least upper bound of this type and the given [type], or `null`
- * if there is no least upper bound.
- *
- * Deprecated, since it is impossible to implement the correct algorithm
- * without access to a [TypeProvider]. Please use
- * [TypeSystem.getLeastUpperBound] instead.
- */
- @deprecated
- DartType getLeastUpperBound(DartType type);
-
- /**
* Return `true` if this type is assignable to the given [type]. A type
* <i>T</i> may be assigned to a type <i>S</i>, written <i>T</i> ⇔
* <i>S</i>, iff either <i>T</i> <: <i>S</i> or <i>S</i> <: <i>T</i>.
@@ -2449,9 +2394,9 @@
* Elements with a smaller offset will be sorted to be before elements with a
* larger name offset.
*/
- static final Comparator<Element> SORT_BY_OFFSET = (Element firstElement,
- Element secondElement) =>
- firstElement.nameOffset - secondElement.nameOffset;
+ static final Comparator<Element> SORT_BY_OFFSET =
+ (Element firstElement, Element secondElement) =>
+ firstElement.nameOffset - secondElement.nameOffset;
/**
* Return the analysis context in which this element is defined.
@@ -2562,21 +2507,6 @@
int get nameOffset;
/**
- * **DEPRECATED** Use `computeNode()` instead.
- *
- * Return the resolved [AstNode] node that declares this element, or `null` if
- * this element is synthetic or isn't contained in a compilation unit, such as
- * a [LibraryElement].
- *
- * This method is expensive, because resolved AST might be evicted from cache,
- * so parsing and resolving will be performed.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- @deprecated
- AstNode get node;
-
- /**
* Return the source that contains this element, or `null` if this element is
* not contained in a source.
*/
@@ -2702,13 +2632,6 @@
*/
class ElementAnnotationImpl implements ElementAnnotation {
/**
- * An empty list of annotations.
- */
- @deprecated // Use ElementAnnotation.EMPTY_LIST
- static const List<ElementAnnotationImpl> EMPTY_ARRAY =
- const <ElementAnnotationImpl>[];
-
- /**
* The name of the class used to mark an element as being deprecated.
*/
static String _DEPRECATED_CLASS_NAME = "Deprecated";
@@ -3001,10 +2924,6 @@
_cachedLocation = null;
}
- @deprecated
- @override
- AstNode get node => computeNode();
-
@override
Source get source {
if (_enclosingElement == null) {
@@ -3475,14 +3394,8 @@
R visitConstructorElement(ConstructorElement element);
- @deprecated
- R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element);
-
R visitExportElement(ExportElement element);
- @deprecated
- R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element);
-
R visitFieldElement(FieldElement element);
R visitFieldFormalParameterElement(FieldFormalParameterElement element);
@@ -3491,9 +3404,6 @@
R visitFunctionTypeAliasElement(FunctionTypeAliasElement element);
- @deprecated
- R visitHtmlElement(HtmlElement element);
-
R visitImportElement(ImportElement element);
R visitLabelElement(LabelElement element);
@@ -3518,62 +3428,10 @@
}
/**
- * A script tag in an HTML file having content that defines a Dart library.
- */
-@deprecated
-abstract class EmbeddedHtmlScriptElement implements HtmlScriptElement {
- /**
- * Return the library element defined by the content of the script tag.
- */
- LibraryElement get scriptLibrary;
-}
-
-/**
- * A concrete implementation of an [EmbeddedHtmlScriptElement].
- */
-@deprecated
-class EmbeddedHtmlScriptElementImpl extends HtmlScriptElementImpl
- implements EmbeddedHtmlScriptElement {
- /**
- * The library defined by the script tag's content.
- */
- LibraryElement _scriptLibrary;
-
- /**
- * Initialize a newly created script element to represent the given [node].
- */
- EmbeddedHtmlScriptElementImpl(XmlTagNode node) : super(node);
-
- @override
- ElementKind get kind => ElementKind.EMBEDDED_HTML_SCRIPT;
-
- @override
- LibraryElement get scriptLibrary => _scriptLibrary;
-
- /**
- * Set the script library defined by the script tag's content to the given
- * [library].
- */
- void set scriptLibrary(LibraryElementImpl library) {
- library.enclosingElement = this;
- _scriptLibrary = library;
- }
-
- @override
- accept(ElementVisitor visitor) =>
- visitor.visitEmbeddedHtmlScriptElement(this);
-
- @override
- void visitChildren(ElementVisitor visitor) {
- safelyVisitChild(_scriptLibrary, visitor);
- }
-}
-
-/**
* An element representing an executable object, including functions, methods,
* constructors, getters, and setters.
*/
-abstract class ExecutableElement implements TypeParameterizedElement {
+abstract class ExecutableElement implements FunctionTypedElement {
/**
* An empty list of executable elements.
*/
@@ -3649,24 +3507,6 @@
* executable element.
*/
List<LocalVariableElement> get localVariables;
-
- /**
- * Return a list containing all of the parameters defined by this executable
- * element.
- */
- List<ParameterElement> get parameters;
-
- /**
- * Return the return type defined by this executable element. If the element
- * model is fully populated, then the [returnType] will not be `null`, even
- * if no return type was explicitly specified.
- */
- DartType get returnType;
-
- /**
- * Return the type of function defined by this executable element.
- */
- FunctionType get type;
}
/**
@@ -3675,13 +3515,6 @@
abstract class ExecutableElementImpl extends ElementImpl
implements ExecutableElement {
/**
- * An empty list of executable elements.
- */
- @deprecated // Use ExecutableElement.EMPTY_LIST
- static const List<ExecutableElement> EMPTY_ARRAY =
- const <ExecutableElement>[];
-
- /**
* A list containing all of the functions defined within this executable
* element.
*/
@@ -3941,12 +3774,21 @@
* type parameters are known.
*/
abstract class ExecutableMember extends Member implements ExecutableElement {
+ @override
+ final FunctionType type;
+
/**
- * Initialize a newly created element to represent a constructor, based on the
- * [baseElement], defined by the [definingType].
+ * Initialize a newly created element to represent a callable element (like a
+ * method or function or property), based on the [baseElement], defined by the
+ * [definingType]. If [type] is passed, it represents the full type of the
+ * member, and will take precedence over the [definingType].
*/
- ExecutableMember(ExecutableElement baseElement, InterfaceType definingType)
- : super(baseElement, definingType);
+ ExecutableMember(ExecutableElement baseElement, InterfaceType definingType,
+ [FunctionType type])
+ : type = type ??
+ baseElement.type.substitute2(definingType.typeArguments,
+ TypeParameterTypeImpl.getTypes(definingType.typeParameters)),
+ super(baseElement, definingType);
@override
ExecutableElement get baseElement => super.baseElement as ExecutableElement;
@@ -3999,26 +3841,10 @@
}
@override
- List<ParameterElement> get parameters {
- List<ParameterElement> baseParameters = baseElement.parameters;
- int parameterCount = baseParameters.length;
- if (parameterCount == 0) {
- return baseParameters;
- }
- List<ParameterElement> parameterizedParameters =
- new List<ParameterElement>(parameterCount);
- for (int i = 0; i < parameterCount; i++) {
- parameterizedParameters[i] =
- ParameterMember.from(baseParameters[i], definingType);
- }
- return parameterizedParameters;
- }
+ List<ParameterElement> get parameters => type.parameters;
@override
- DartType get returnType => substituteFor(baseElement.returnType);
-
- @override
- FunctionType get type => substituteFor(baseElement.type);
+ DartType get returnType => type.returnType;
@override
List<TypeParameterElement> get typeParameters => baseElement.typeParameters;
@@ -4042,12 +3868,6 @@
/**
* An empty list of export elements.
*/
- @deprecated // Use ExportElement.EMPTY_LIST
- static const List<ExportElement> EMPTY_ARRAY = const <ExportElement>[];
-
- /**
- * An empty list of export elements.
- */
static const List<ExportElement> EMPTY_LIST = const <ExportElement>[];
/**
@@ -4101,44 +3921,6 @@
}
/**
- * A script tag in an HTML file having a `source` attribute that references a
- * Dart library source file.
- */
-@deprecated
-abstract class ExternalHtmlScriptElement implements HtmlScriptElement {
- /**
- * Return the source referenced by this element, or `null` if this element
- * does not reference a Dart library source file.
- */
- Source get scriptSource;
-}
-
-/**
- * A concrete implementation of an [ExternalHtmlScriptElement].
- */
-@deprecated
-class ExternalHtmlScriptElementImpl extends HtmlScriptElementImpl
- implements ExternalHtmlScriptElement {
- /**
- * The source specified in the `source` attribute or `null` if unspecified.
- */
- Source scriptSource;
-
- /**
- * Initialize a newly created script element to correspond to the given
- * [node].
- */
- ExternalHtmlScriptElementImpl(XmlTagNode node) : super(node);
-
- @override
- ElementKind get kind => ElementKind.EXTERNAL_HTML_SCRIPT;
-
- @override
- accept(ElementVisitor visitor) =>
- visitor.visitExternalHtmlScriptElement(this);
-}
-
-/**
* A field defined within a type.
*/
abstract class FieldElement
@@ -4170,12 +3952,6 @@
class FieldElementImpl extends PropertyInducingElementImpl
implements FieldElement {
/**
- * An empty list of field elements.
- */
- @deprecated // Use FieldElement.EMPTY_LIST
- static const List<FieldElement> EMPTY_ARRAY = const <FieldElement>[];
-
- /**
* Initialize a newly created synthetic field element to have the given [name]
* at the given [offset].
*/
@@ -4258,18 +4034,21 @@
class FieldFormalParameterMember extends ParameterMember
implements FieldFormalParameterElement {
/**
- * Initialize a newly created element to represent a constructor, based on the
- * [baseElement], defined by the [definingType].
+ * Initialize a newly created element to represent a field formal parameter,
+ * based on the [baseElement], defined by the [definingType]. If [type]
+ * is passed it will be used as the substituted type for this member.
*/
FieldFormalParameterMember(
- FieldFormalParameterElement baseElement, ParameterizedType definingType)
- : super(baseElement, definingType);
+ FieldFormalParameterElement baseElement, ParameterizedType definingType,
+ [DartType type])
+ : super(baseElement, definingType, type);
@override
FieldElement get field {
FieldElement field = (baseElement as FieldFormalParameterElement).field;
if (field is FieldElement) {
- return FieldMember.from(field, definingType);
+ return FieldMember.from(
+ field, substituteFor(field.enclosingElement.type));
}
return field;
}
@@ -4285,7 +4064,7 @@
*/
class FieldMember extends VariableMember implements FieldElement {
/**
- * Initialize a newly created element to represent a constructor, based on the
+ * Initialize a newly created element to represent a field, based on the
* [baseElement], defined by the [definingType].
*/
FieldMember(FieldElement baseElement, InterfaceType definingType)
@@ -4295,9 +4074,6 @@
FieldElement get baseElement => super.baseElement as FieldElement;
@override
- InterfaceType get definingType => super.definingType as InterfaceType;
-
- @override
ClassElement get enclosingElement => baseElement.enclosingElement;
@override
@@ -4330,7 +4106,7 @@
* field. Return the member that was created, or the base field if no member
* was created.
*/
- static FieldElement from(FieldElement field, InterfaceType definingType) {
+ static FieldElement from(FieldElement field, ParameterizedType definingType) {
if (!_isChangedByTypeSubstitution(field, definingType)) {
return field;
}
@@ -4346,11 +4122,12 @@
* arguments from the defining type.
*/
static bool _isChangedByTypeSubstitution(
- FieldElement field, InterfaceType definingType) {
+ FieldElement field, ParameterizedType definingType) {
List<DartType> argumentTypes = definingType.typeArguments;
if (field != null && argumentTypes.length != 0) {
DartType baseType = field.type;
- List<DartType> parameterTypes = definingType.element.type.typeArguments;
+ List<DartType> parameterTypes =
+ TypeParameterTypeImpl.getTypes(definingType.typeParameters);
if (baseType != null) {
DartType substitutedType =
baseType.substitute2(argumentTypes, parameterTypes);
@@ -4428,12 +4205,6 @@
class FunctionElementImpl extends ExecutableElementImpl
implements FunctionElement {
/**
- * An empty list of function elements.
- */
- @deprecated // Use FunctionElement.EMPTY_LIST
- static const List<FunctionElement> EMPTY_ARRAY = const <FunctionElement>[];
-
- /**
* The offset to the beginning of the visible range for this element.
*/
int _visibleRangeOffset = 0;
@@ -4525,6 +4296,70 @@
}
/**
+ * An element of a generic function, where the type parameters are known.
+ */
+// TODO(jmesserly): the term "function member" is a bit weird, but it allows
+// a certain consistency.
+class FunctionMember extends ExecutableMember implements FunctionElement {
+ /**
+ * Initialize a newly created element to represent a function, based on the
+ * [baseElement], with the corresponding function [type].
+ */
+ FunctionMember(FunctionElement baseElement, [DartType type])
+ : super(baseElement, null, type);
+
+ @override
+ FunctionElement get baseElement => super.baseElement as FunctionElement;
+
+ @override
+ Element get enclosingElement => baseElement.enclosingElement;
+
+ @override
+ bool get isEntryPoint => baseElement.isEntryPoint;
+
+ @override
+ SourceRange get visibleRange => baseElement.visibleRange;
+
+ @override
+ accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
+
+ @override
+ FunctionDeclaration computeNode() => baseElement.computeNode();
+
+ @override
+ String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.write(baseElement.displayName);
+ (type as FunctionTypeImpl).appendTo(buffer);
+ return buffer.toString();
+ }
+
+ /**
+ * If the given [method]'s type is different when any type parameters from the
+ * defining type's declaration are replaced with the actual type arguments
+ * from the [definingType], create a method member representing the given
+ * method. Return the member that was created, or the base method if no member
+ * was created.
+ */
+ static MethodElement from(
+ MethodElement method, ParameterizedType definingType) {
+ if (method == null || definingType.typeArguments.length == 0) {
+ return method;
+ }
+ FunctionType baseType = method.type;
+ List<DartType> argumentTypes = definingType.typeArguments;
+ List<DartType> parameterTypes =
+ TypeParameterTypeImpl.getTypes(definingType.typeParameters);
+ FunctionType substitutedType =
+ baseType.substitute2(argumentTypes, parameterTypes);
+ if (baseType == substitutedType) {
+ return method;
+ }
+ return new MethodMember(method, definingType, substitutedType);
+ }
+}
+
+/**
* The type of a function, method, constructor, getter, or setter. Function
* types come in three variations:
*
@@ -4669,7 +4504,7 @@
* A function type alias (`typedef`).
*/
abstract class FunctionTypeAliasElement
- implements TypeDefiningElement, TypeParameterizedElement {
+ implements TypeDefiningElement, FunctionTypedElement {
/**
* An empty array of type alias elements.
*/
@@ -4683,19 +4518,6 @@
CompilationUnitElement get enclosingElement;
/**
- * Return a list containing all of the parameters defined by this type alias.
- */
- List<ParameterElement> get parameters;
-
- /**
- * Return the return type defined by this type alias.
- */
- DartType get returnType;
-
- @override
- FunctionType get type;
-
- /**
* Return the resolved function type alias node that declares this element.
*
* This method is expensive, because resolved AST might be evicted from cache,
@@ -4711,13 +4533,6 @@
class FunctionTypeAliasElementImpl extends ElementImpl
implements FunctionTypeAliasElement {
/**
- * An empty array of type alias elements.
- */
- @deprecated // Use FunctionTypeAliasElement.EMPTY_LIST
- static List<FunctionTypeAliasElement> EMPTY_ARRAY =
- new List<FunctionTypeAliasElement>(0);
-
- /**
* A list containing all of the parameters defined by this type alias.
*/
List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
@@ -4853,6 +4668,31 @@
}
/**
+ * An element that has a [FunctionType] as its [type].
+ *
+ * This also provides convenient access to the parameters and return type.
+ */
+abstract class FunctionTypedElement implements TypeParameterizedElement {
+ /**
+ * Return a list containing all of the parameters defined by this executable
+ * element.
+ */
+ List<ParameterElement> get parameters;
+
+ /**
+ * Return the return type defined by this element. If the element model is
+ * fully populated, then the [returnType] will not be `null`, even
+ * if no return type was explicitly specified.
+ */
+ DartType get returnType;
+
+ /**
+ * Return the type of function defined by this element.
+ */
+ FunctionType get type;
+}
+
+/**
* The type of a function, method, constructor, getter, or setter.
*/
class FunctionTypeImpl extends TypeImpl implements FunctionType {
@@ -4890,21 +4730,6 @@
* Initialize a newly created function type to be declared by the given
* [element].
*/
- @deprecated // Use new FunctionTypeImpl(element)
- FunctionTypeImpl.con1(ExecutableElement element) : this(element);
-
- /**
- * Initialize a newly created function type to be declared by the given
- * [element].
- */
- @deprecated // Use new FunctionTypeImpl.forTypedef(element)
- FunctionTypeImpl.con2(FunctionTypeAliasElement element)
- : this.forTypedef(element);
-
- /**
- * Initialize a newly created function type to be declared by the given
- * [element].
- */
FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element,
[List<FunctionTypeAliasElement> prunedTypedefs])
: this._(element, element?.name, prunedTypedefs, null, null, null);
@@ -4957,26 +4782,12 @@
/**
* Return the base parameter elements of this function element.
*/
- List<ParameterElement> get baseParameters {
- Element element = this.element;
- if (element is ExecutableElement) {
- return element.parameters;
- } else {
- return (element as FunctionTypeAliasElement).parameters;
- }
- }
+ List<ParameterElement> get baseParameters => element.parameters;
/**
* Return the return type defined by this function's element.
*/
- DartType get baseReturnType {
- Element element = this.element;
- if (element is ExecutableElement) {
- return element.returnType;
- } else {
- return (element as FunctionTypeAliasElement).returnType;
- }
- }
+ DartType get baseReturnType => element.returnType;
@override
List<TypeParameterElement> get boundTypeParameters => _boundTypeParameters;
@@ -5053,6 +4864,9 @@
}
@override
+ FunctionTypedElement get element => super.element;
+
+ @override
int get hashCode {
if (element == null) {
return 0;
@@ -5075,6 +4889,26 @@
return code;
}
+ /**
+ * The type arguments that were used to instantiate this function type, if
+ * any, otherwise this will return an empty list.
+ *
+ * Given a function type `f`:
+ *
+ * f == f.originalFunction.instantiate(f.instantiatedTypeArguments)
+ *
+ * Will always hold.
+ */
+ List<DartType> get instantiatedTypeArguments {
+ int typeParameterCount = element.type.boundTypeParameters.length;
+ if (typeParameterCount == 0) {
+ return DartType.EMPTY_LIST;
+ }
+ // The substituted types at the end should be our bound type parameters.
+ int skipCount = typeArguments.length - typeParameterCount;
+ return new List<DartType>.from(typeArguments.skip(skipCount));
+ }
+
@override
Map<String, DartType> get namedParameterTypes {
LinkedHashMap<String, DartType> namedParameterTypes =
@@ -5172,6 +5006,20 @@
return types;
}
+ /**
+ * If this is an instantiation of a generic function type, this will get
+ * the original function from which it was instantiated.
+ *
+ * Otherwise, this will return `this`.
+ */
+ FunctionTypeImpl get originalFunction {
+ if (element.type.boundTypeParameters.isEmpty) {
+ return this;
+ }
+ return (element.type as FunctionTypeImpl).substitute2(typeArguments,
+ TypeParameterTypeImpl.getTypes(typeParameters), prunedTypedefs);
+ }
+
@override
List<ParameterElement> get parameters {
List<ParameterElement> baseParameters = this.baseParameters;
@@ -5229,9 +5077,22 @@
// variables, and see if the result is equal.
if (boundTypeParameters.isNotEmpty) {
List<DartType> instantiateTypeArgs = new List<DartType>();
- for (TypeParameterElement e in boundTypeParameters) {
- instantiateTypeArgs.add(new TypeParameterTypeImpl(
- new TypeParameterElementImpl(e.name, -1)));
+ List<DartType> variablesThis = new List<DartType>();
+ List<DartType> variablesOther = new List<DartType>();
+ for (int i = 0; i < boundTypeParameters.length; i++) {
+ TypeParameterElement pThis = boundTypeParameters[i];
+ TypeParameterElement pOther = otherType.boundTypeParameters[i];
+ TypeParameterTypeImpl pFresh = new TypeParameterTypeImpl(
+ new TypeParameterElementImpl(pThis.name, -1));
+ instantiateTypeArgs.add(pFresh);
+ variablesThis.add(pThis.type);
+ variablesOther.add(pOther.type);
+ // Check that the bounds are equal after equating the previous
+ // bound variables.
+ if (pThis.bound?.substitute2(instantiateTypeArgs, variablesThis) !=
+ pOther.bound?.substitute2(instantiateTypeArgs, variablesOther)) {
+ return false;
+ }
}
// After instantiation, they will no longer have boundTypeParameters,
// so we will continue below.
@@ -5263,6 +5124,7 @@
}
List<DartType> instantiateTypeArgs = new List<DartType>();
+ List<DartType> variables = new List<DartType>();
buffer.write("<");
for (TypeParameterElement e in boundTypeParameters) {
if (e != boundTypeParameters[0]) {
@@ -5283,6 +5145,13 @@
new TypeParameterTypeImpl(new TypeParameterElementImpl(name, -1));
t.appendTo(buffer);
instantiateTypeArgs.add(t);
+ variables.add(e.type);
+ if (e.bound != null) {
+ buffer.write(" extends ");
+ TypeImpl renamed =
+ e.bound.substitute2(instantiateTypeArgs, variables);
+ renamed.appendTo(buffer);
+ }
}
buffer.write(">");
@@ -5813,22 +5682,12 @@
return null;
}
- @override
- @deprecated
- R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element) =>
- visitHtmlScriptElement(element);
-
R visitExecutableElement(ExecutableElement element) => visitElement(element);
@override
R visitExportElement(ExportElement element) => visitElement(element);
@override
- @deprecated
- R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element) =>
- visitHtmlScriptElement(element);
-
- @override
R visitFieldElement(FieldElement element) =>
visitPropertyInducingElement(element);
@@ -5844,13 +5703,6 @@
visitElement(element);
@override
- @deprecated
- R visitHtmlElement(HtmlElement element) => visitElement(element);
-
- @deprecated
- R visitHtmlScriptElement(HtmlScriptElement element) => visitElement(element);
-
- @override
R visitImportElement(ImportElement element) => visitElement(element);
@override
@@ -5945,156 +5797,12 @@
}
/**
- * An HTML file.
- */
-@deprecated
-abstract class HtmlElement implements Element {
- /**
- * An empty list of HTML file elements.
- */
- static const List<HtmlElement> EMPTY_LIST = const <HtmlElement>[];
-
- /**
- * Return a list containing all of the script elements contained in the HTML
- * file. This includes scripts with libraries that are defined by the content
- * of a script tag as well as libraries that are referenced in the `source`
- * attribute of a script tag.
- */
- List<HtmlScriptElement> get scripts;
-}
-
-/**
- * A concrete implementation of an [HtmlElement].
- */
-@deprecated
-class HtmlElementImpl extends ElementImpl implements HtmlElement {
- /**
- * An empty list of HTML file elements.
- */
- @deprecated // Use HtmlElement.EMPTY_LIST
- static const List<HtmlElement> EMPTY_ARRAY = const <HtmlElement>[];
-
- /**
- * The analysis context in which this library is defined.
- */
- final AnalysisContext context;
-
- /**
- * The scripts contained in or referenced from script tags in the HTML file.
- */
- List<HtmlScriptElement> _scripts = HtmlScriptElement.EMPTY_LIST;
-
- /**
- * The source that corresponds to this HTML file.
- */
- Source source;
-
- /**
- * Initialize a newly created HTML element in the given [context] to have the
- * given [name].
- */
- HtmlElementImpl(this.context, String name) : super(name, -1);
-
- @override
- int get hashCode => source.hashCode;
-
- @override
- String get identifier => source.encoding;
-
- @override
- ElementKind get kind => ElementKind.HTML;
-
- @override
- List<HtmlScriptElement> get scripts => _scripts;
-
- /**
- * Set the scripts contained in the HTML file to the given [scripts].
- */
- void set scripts(List<HtmlScriptElement> scripts) {
- if (scripts.length == 0) {
- this._scripts = HtmlScriptElement.EMPTY_LIST;
- return;
- }
- for (HtmlScriptElement script in scripts) {
- (script as HtmlScriptElementImpl).enclosingElement = this;
- }
- this._scripts = scripts;
- }
-
- @override
- bool operator ==(Object object) {
- if (identical(object, this)) {
- return true;
- }
- return object is HtmlElementImpl && source == object.source;
- }
-
- @override
- accept(ElementVisitor visitor) => visitor.visitHtmlElement(this);
-
- @override
- void appendTo(StringBuffer buffer) {
- if (source == null) {
- buffer.write("{HTML file}");
- } else {
- buffer.write(source.fullName);
- }
- }
-
- @override
- void visitChildren(ElementVisitor visitor) {
- super.visitChildren(visitor);
- safelyVisitChildren(_scripts, visitor);
- }
-}
-
-/**
- * A script tag in an HTML file.
- *
- * See [EmbeddedHtmlScriptElement], and [ExternalHtmlScriptElement].
- */
-@deprecated
-abstract class HtmlScriptElement implements Element {
- /**
- * An empty list of HTML script elements.
- */
- static const List<HtmlScriptElement> EMPTY_LIST = const <HtmlScriptElement>[];
-}
-
-/**
- * A concrete implementation of an [HtmlScriptElement].
- */
-@deprecated
-abstract class HtmlScriptElementImpl extends ElementImpl
- implements HtmlScriptElement {
- /**
- * An empty list of HTML script elements.
- */
- @deprecated // Use HtmlScriptElement.EMPTY_LIST
- static const List<HtmlScriptElement> EMPTY_ARRAY =
- const <HtmlScriptElement>[];
-
- /**
- * Initialize a newly created script element corresponding to the given
- * [node].
- */
- HtmlScriptElementImpl(XmlTagNode node)
- : super(node.tag, node.tagToken.offset);
-}
-
-/**
* A single import directive within a library.
*/
abstract class ImportElement implements Element, UriReferencedElement {
/**
* An empty list of import elements.
*/
- @deprecated // Use ImportElement.EMPTY_LIST
- static const List<ImportElement> EMPTY_ARRAY = const <ImportElement>[];
-
- /**
- * An empty list of import elements.
- */
static const List<ImportElement> EMPTY_LIST = const <ImportElement>[];
/**
@@ -6203,12 +5911,6 @@
/**
* An empty list of types.
*/
- @deprecated // Use InterfaceType.EMPTY_LIST
- static const List<InterfaceType> EMPTY_ARRAY = const <InterfaceType>[];
-
- /**
- * An empty list of types.
- */
static const List<InterfaceType> EMPTY_LIST = const <InterfaceType>[];
/**
@@ -6264,24 +5966,6 @@
PropertyAccessorElement getGetter(String name);
/**
- * Return the least upper bound of this type and the given [type], or `null`
- * if there is no least upper bound.
- *
- * Given two interfaces <i>I</i> and <i>J</i>, let <i>S<sub>I</sub></i> be the
- * set of superinterfaces of <i>I<i>, let <i>S<sub>J</sub></i> be the set of
- * superinterfaces of <i>J</i> and let <i>S = (I ∪ S<sub>I</sub>) ∩
- * (J ∪ S<sub>J</sub>)</i>. Furthermore, we define <i>S<sub>n</sub> =
- * {T | T ∈ S ∧ depth(T) = n}</i> for any finite <i>n</i>, where
- * <i>depth(T)</i> is the number of steps in the longest inheritance path from
- * <i>T</i> to <i>Object</i>. Let <i>q</i> be the largest number such that
- * <i>S<sub>q</sub></i> has cardinality one. The least upper bound of <i>I</i>
- * and <i>J</i> is the sole element of <i>S<sub>q</sub></i>.
- */
- @override
- @deprecated
- DartType getLeastUpperBound(DartType type);
-
- /**
* Return the element representing the method with the given [name] that is
* declared in this class, or `null` if this class does not declare a method
* with the given name.
@@ -6551,7 +6235,9 @@
if (first.element == second.element) {
return _leastUpperBound(first, second);
}
- return first.getLeastUpperBound(second);
+ AnalysisContext context = first.element.context;
+ return context.typeSystem
+ .getLeastUpperBound(context.typeProvider, first, second);
}
/**
@@ -6622,23 +6308,6 @@
: super(element, element.displayName);
/**
- * Initialize a newly created type to be declared by the given [element].
- */
- @deprecated // Use new InterfaceTypeImpl(element)
- InterfaceTypeImpl.con1(ClassElement element)
- : prunedTypedefs = null,
- super(element, element.displayName);
-
- /**
- * Initialize a newly created type to have the given [name]. This constructor
- * should only be used in cases where there is no declaration of the type.
- */
- @deprecated // Use new InterfaceTypeImpl.named(name)
- InterfaceTypeImpl.con2(String name)
- : prunedTypedefs = null,
- super(null, name);
-
- /**
* Initialize a newly created type to have the given [name]. This constructor
* should only be used in cases where there is no declaration of the type.
*/
@@ -6824,26 +6493,6 @@
.from((element as ClassElementImpl).getGetter(getterName), this);
@override
- @deprecated
- DartType getLeastUpperBound(DartType type) {
- // quick check for self
- if (identical(type, this)) {
- return this;
- }
- // dynamic
- DartType dynamicType = DynamicTypeImpl.instance;
- if (identical(this, dynamicType) || identical(type, dynamicType)) {
- return dynamicType;
- }
- // TODO (jwren) opportunity here for a better, faster algorithm if this
- // turns out to be a bottle-neck
- if (type is! InterfaceType) {
- return null;
- }
- return computeLeastUpperBound(this, type);
- }
-
- @override
MethodElement getMethod(String methodName) => MethodMember.from(
(element as ClassElementImpl).getMethod(methodName), this);
@@ -7469,12 +7118,6 @@
*/
class LabelElementImpl extends ElementImpl implements LabelElement {
/**
- * An empty list of label elements.
- */
- @deprecated // Use LabelElement.EMPTY_LIST
- static const List<LabelElement> EMPTY_ARRAY = const <LabelElement>[];
-
- /**
* A flag indicating whether this label is associated with a `switch`
* statement.
*/
@@ -7663,12 +7306,6 @@
*/
class LibraryElementImpl extends ElementImpl implements LibraryElement {
/**
- * An empty list of library elements.
- */
- @deprecated // Use LibraryElement.EMPTY_LIST
- static const List<LibraryElement> EMPTY_ARRAY = const <LibraryElement>[];
-
- /**
* The analysis context in which this library is defined.
*/
final AnalysisContext context;
@@ -8014,7 +7651,8 @@
}
@override
- bool operator ==(Object object) => object is LibraryElementImpl &&
+ bool operator ==(Object object) =>
+ object is LibraryElementImpl &&
_definingCompilationUnit == object.definingCompilationUnit;
@override
@@ -8253,16 +7891,6 @@
*/
static const List<LocalVariableElement> EMPTY_LIST =
const <LocalVariableElement>[];
-
- /**
- * Return the resolved [VariableDeclaration] node that declares this
- * [LocalVariableElement].
- *
- * This method is expensive, because resolved AST might be evicted from cache,
- * so parsing and resolving will be performed.
- */
- @override
- VariableDeclaration computeNode();
}
/**
@@ -8271,13 +7899,6 @@
class LocalVariableElementImpl extends VariableElementImpl
implements LocalVariableElement {
/**
- * An empty list of field elements.
- */
- @deprecated // Use LocalVariableElement.EMPTY_LIST
- static const List<LocalVariableElement> EMPTY_ARRAY =
- const <LocalVariableElement>[];
-
- /**
* The offset to the beginning of the visible range for this element.
*/
int _visibleRangeOffset = 0;
@@ -8380,7 +8001,7 @@
final ParameterizedType _definingType;
/**
- * Initialize a newly created element to represent a constructor, based on the
+ * Initialize a newly created element to represent a member, based on the
* [baseElement], defined by the [definingType].
*/
Member(this._baseElement, this._definingType);
@@ -8442,10 +8063,6 @@
@override
int get nameOffset => _baseElement.nameOffset;
- @deprecated
- @override
- AstNode get node => computeNode();
-
@override
Source get source => _baseElement.source;
@@ -8497,6 +8114,7 @@
* Return the type that results from replacing the type parameters in the
* given [type] with the type arguments associated with this member.
*/
+ @deprecated
DartType substituteFor(DartType type) {
if (type == null) {
return null;
@@ -8507,20 +8125,6 @@
return type.substitute2(argumentTypes, parameterTypes);
}
- /**
- * Return the list of types that results from replacing the type parameters in
- * the given [types] with the type arguments associated with this member.
- */
- @deprecated
- List<InterfaceType> substituteFor2(List<InterfaceType> types) {
- int count = types.length;
- List<InterfaceType> substitutedTypes = new List<InterfaceType>(count);
- for (int i = 0; i < count; i++) {
- substitutedTypes[i] = substituteFor(types[i]);
- }
- return substitutedTypes;
- }
-
@override
void visitChildren(ElementVisitor visitor) {
// There are no children to visit
@@ -8552,12 +8156,6 @@
*/
class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
/**
- * An empty list of method elements.
- */
- @deprecated // Use MethodElement.EMPTY_LIST
- static const List<MethodElement> EMPTY_ARRAY = const <MethodElement>[];
-
- /**
* Initialize a newly created method element to have the given [name] at the
* given [offset].
*/
@@ -8644,11 +8242,14 @@
*/
class MethodMember extends ExecutableMember implements MethodElement {
/**
- * Initialize a newly created element to represent a constructor, based on the
- * [baseElement], defined by the [definingType].
+ * Initialize a newly created element to represent a method, based on the
+ * [baseElement], defined by the [definingType]. If [type] is passed, it
+ * represents the full type of the member, and will take precedence over
+ * the [definingType].
*/
- MethodMember(MethodElement baseElement, InterfaceType definingType)
- : super(baseElement, definingType);
+ MethodMember(MethodElement baseElement, InterfaceType definingType,
+ [DartType type])
+ : super(baseElement, definingType, type);
@override
MethodElement get baseElement => super.baseElement as MethodElement;
@@ -8706,10 +8307,7 @@
if (baseType == substitutedType) {
return method;
}
- // TODO(brianwilkerson) Consider caching the substituted type in the
- // instance. It would use more memory but speed up some operations.
- // We need to see how often the type is being re-computed.
- return new MethodMember(method, definingType);
+ return new MethodMember(method, definingType, substitutedType);
}
}
@@ -8962,10 +8560,6 @@
@override
int get nameOffset => -1;
- @deprecated
- @override
- AstNode get node => null;
-
@override
Source get source => null;
@@ -9142,13 +8736,6 @@
/**
* An empty list of namespace combinators.
*/
- @deprecated // Use NamespaceCombinator.EMPTY_LIST
- static const List<NamespaceCombinator> EMPTY_ARRAY =
- const <NamespaceCombinator>[];
-
- /**
- * An empty list of namespace combinators.
- */
static const List<NamespaceCombinator> EMPTY_LIST =
const <NamespaceCombinator>[];
}
@@ -9209,12 +8796,6 @@
with ParameterElementMixin
implements ParameterElement {
/**
- * An empty list of parameter elements.
- */
- @deprecated // Use ParameterElement.EMPTY_LIST
- static const List<ParameterElement> EMPTY_ARRAY = const <ParameterElement>[];
-
- /**
* A list containing all of the parameters defined by this parameter element.
* There will only be parameters if this parameter is a function typed
* parameter.
@@ -9436,11 +9017,13 @@
with ParameterElementMixin
implements ParameterElement {
/**
- * Initialize a newly created element to represent a constructor, based on the
- * [baseElement], defined by the [definingType].
+ * Initialize a newly created element to represent a parameter, based on the
+ * [baseElement], defined by the [definingType]. If [type] is passed it will
+ * represent the already substituted type.
*/
- ParameterMember(ParameterElement baseElement, ParameterizedType definingType)
- : super(baseElement, definingType);
+ ParameterMember(ParameterElement baseElement, ParameterizedType definingType,
+ [DartType type])
+ : super._(baseElement, definingType, type);
@override
ParameterElement get baseElement => super.baseElement as ParameterElement;
@@ -9462,18 +9045,11 @@
@override
List<ParameterElement> get parameters {
- List<ParameterElement> baseParameters = baseElement.parameters;
- int parameterCount = baseParameters.length;
- if (parameterCount == 0) {
- return baseParameters;
+ DartType type = this.type;
+ if (type is FunctionType) {
+ return type.parameters;
}
- List<ParameterElement> parameterizedParameters =
- new List<ParameterElement>(parameterCount);
- for (int i = 0; i < parameterCount; i++) {
- parameterizedParameters[i] =
- ParameterMember.from(baseParameters[i], definingType);
- }
- return parameterizedParameters;
+ return ParameterElement.EMPTY_LIST;
}
@override
@@ -9482,6 +9058,8 @@
@override
SourceRange get visibleRange => baseElement.visibleRange;
+ // TODO(jmesserly): this equality is broken. It should consider the defining
+ // type as well, otherwise we're dropping the substitution.
@override
bool operator ==(Object object) =>
object is ParameterMember && baseElement == object.baseElement;
@@ -9548,8 +9126,9 @@
// Check if parameter type depends on defining type type arguments.
// It is possible that we did not resolve field formal parameter yet,
// so skip this check for it.
- bool isFieldFormal = parameter is FieldFormalParameterElement;
- if (!isFieldFormal) {
+ if (parameter is FieldFormalParameterElement) {
+ return new FieldFormalParameterMember(parameter, definingType);
+ } else {
DartType baseType = parameter.type;
List<DartType> argumentTypes = definingType.typeArguments;
List<DartType> parameterTypes =
@@ -9559,15 +9138,8 @@
if (baseType == substitutedType) {
return parameter;
}
+ return new ParameterMember(parameter, definingType, substitutedType);
}
- // TODO(brianwilkerson) Consider caching the substituted type in the
- // instance. It would use more memory but speed up some operations.
- // We need to see how often the type is being re-computed.
- if (isFieldFormal) {
- return new FieldFormalParameterMember(
- parameter as FieldFormalParameterElement, definingType);
- }
- return new ParameterMember(parameter, definingType);
}
}
@@ -9599,12 +9171,6 @@
*/
class PrefixElementImpl extends ElementImpl implements PrefixElement {
/**
- * An empty list of prefix elements.
- */
- @deprecated // Use PrefixElement.EMPTY_LIST
- static const List<PrefixElement> EMPTY_ARRAY = const <PrefixElement>[];
-
- /**
* A list containing all of the libraries that are imported using this prefix.
*/
List<LibraryElement> _importedLibraries = LibraryElement.EMPTY_LIST;
@@ -9712,13 +9278,6 @@
class PropertyAccessorElementImpl extends ExecutableElementImpl
implements PropertyAccessorElement {
/**
- * An empty list of property accessor elements.
- */
- @deprecated // Use PropertyAccessorElement.EMPTY_LIST
- static const List<PropertyAccessorElement> EMPTY_ARRAY =
- const <PropertyAccessorElement>[];
-
- /**
* The variable associated with this accessor.
*/
PropertyInducingElement variable;
@@ -9820,7 +9379,8 @@
}
@override
- bool operator ==(Object object) => super == object &&
+ bool operator ==(Object object) =>
+ super == object &&
isGetter == (object as PropertyAccessorElement).isGetter;
@override
@@ -9855,7 +9415,7 @@
class PropertyAccessorMember extends ExecutableMember
implements PropertyAccessorElement {
/**
- * Initialize a newly created element to represent a constructor, based on the
+ * Initialize a newly created element to represent a property, based on the
* [baseElement], defined by the [definingType].
*/
PropertyAccessorMember(
@@ -10041,13 +9601,6 @@
abstract class PropertyInducingElementImpl extends VariableElementImpl
implements PropertyInducingElement {
/**
- * An empty list of elements.
- */
- @deprecated // Use PropertyInducingElement.EMPTY_LIST
- static const List<PropertyInducingElement> EMPTY_ARRAY =
- const <PropertyInducingElement>[];
-
- /**
* The getter associated with this element.
*/
PropertyAccessorElement getter;
@@ -10108,26 +9661,12 @@
}
@override
- @deprecated
- R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element) {
- element.visitChildren(this);
- return null;
- }
-
- @override
R visitExportElement(ExportElement element) {
element.visitChildren(this);
return null;
}
@override
- @deprecated
- R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element) {
- element.visitChildren(this);
- return null;
- }
-
- @override
R visitFieldElement(FieldElement element) {
element.visitChildren(this);
return null;
@@ -10152,13 +9691,6 @@
}
@override
- @deprecated
- R visitHtmlElement(HtmlElement element) {
- element.visitChildren(this);
- return null;
- }
-
- @override
R visitImportElement(ImportElement element) {
element.visitChildren(this);
return null;
@@ -10301,17 +9833,9 @@
R visitConstructorElement(ConstructorElement element) => null;
@override
- @deprecated
- R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element) => null;
-
- @override
R visitExportElement(ExportElement element) => null;
@override
- @deprecated
- R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element) => null;
-
- @override
R visitFieldElement(FieldElement element) => null;
@override
@@ -10325,10 +9849,6 @@
R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) => null;
@override
- @deprecated
- R visitHtmlElement(HtmlElement element) => null;
-
- @override
R visitImportElement(ImportElement element) => null;
@override
@@ -10382,13 +9902,6 @@
class TopLevelVariableElementImpl extends PropertyInducingElementImpl
implements TopLevelVariableElement {
/**
- * An empty list of top-level variable elements.
- */
- @deprecated // Use TopLevelVariableElement.EMPTY_LIST
- static const List<TopLevelVariableElement> EMPTY_ARRAY =
- const <TopLevelVariableElement>[];
-
- /**
* Initialize a newly created synthetic top-level variable element to have the
* given [name] and [offset].
*/
@@ -10430,12 +9943,6 @@
*/
abstract class TypeImpl implements DartType {
/**
- * An empty list of types.
- */
- @deprecated // Use DartType.EMPTY_LIST
- static const List<DartType> EMPTY_ARRAY = const <DartType>[];
-
- /**
* The element representing the declaration of this type, or `null` if the
* type has not, or cannot, be associated with an element.
*/
@@ -10488,9 +9995,6 @@
}
}
- @override
- DartType getLeastUpperBound(DartType type) => null;
-
/**
* Return `true` if this type is assignable to the given [type] (written in
* the spec as "T <=> S", where T=[this] and S=[type]).
@@ -10658,13 +10162,6 @@
class TypeParameterElementImpl extends ElementImpl
implements TypeParameterElement {
/**
- * An empty list of type parameter elements.
- */
- @deprecated // Use TypeParameterElement.EMPTY_LIST
- static const List<TypeParameterElement> EMPTY_ARRAY =
- const <TypeParameterElement>[];
-
- /**
* The type defined by this type parameter.
*/
TypeParameterType type;
@@ -10734,13 +10231,6 @@
*/
class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
/**
- * An empty list of type parameter types.
- */
- @deprecated // Use TypeParameterType.EMPTY_LIST
- static const List<TypeParameterType> EMPTY_ARRAY =
- const <TypeParameterType>[];
-
- /**
* Initialize a newly created type parameter type to be declared by the given
* [element] and to have the given name.
*/
@@ -11064,12 +10554,6 @@
abstract class VariableElementImpl extends ElementImpl
implements VariableElement {
/**
- * An empty list of variable elements.
- */
- @deprecated // Use VariableElement.EMPTY_LIST
- static const List<VariableElement> EMPTY_ARRAY = const <VariableElement>[];
-
- /**
* The declared type of this variable.
*/
DartType type;
@@ -11194,12 +10678,25 @@
* type parameters are known.
*/
abstract class VariableMember extends Member implements VariableElement {
+ @override
+ final DartType type;
+
/**
- * Initialize a newly created element to represent a constructor, based on the
+ * Initialize a newly created element to represent a variable, based on the
* [baseElement], defined by the [definingType].
*/
- VariableMember(VariableElement baseElement, ParameterizedType definingType)
- : super(baseElement, definingType);
+ VariableMember(VariableElement baseElement, ParameterizedType definingType,
+ [DartType type])
+ : type = type ??
+ baseElement.type.substitute2(definingType.typeArguments,
+ TypeParameterTypeImpl.getTypes(definingType.typeParameters)),
+ super(baseElement, definingType);
+
+ // TODO(jmesserly): this is temporary to allow the ParameterMember subclass.
+ // Apparently mixins don't work with optional params.
+ VariableMember._(VariableElement baseElement, ParameterizedType definingType,
+ DartType type)
+ : this(baseElement, definingType, type);
@override
VariableElement get baseElement => super.baseElement as VariableElement;
@@ -11238,9 +10735,6 @@
bool get isStatic => baseElement.isStatic;
@override
- DartType get type => substituteFor(baseElement.type);
-
- @override
void visitChildren(ElementVisitor visitor) {
// TODO(brianwilkerson) We need to finish implementing the accessors used
// below so that we can safely invoke them.
diff --git a/pkg/analyzer/lib/src/generated/element_handle.dart b/pkg/analyzer/lib/src/generated/element_handle.dart
index f496602..09e23c0 100644
--- a/pkg/analyzer/lib/src/generated/element_handle.dart
+++ b/pkg/analyzer/lib/src/generated/element_handle.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.element_handle;
+library analyzer.src.generated.element_handle;
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/constant.dart';
@@ -68,10 +68,6 @@
bool get isProxy => actualElement.isProxy;
@override
- @deprecated
- bool get isTypedef => actualElement.isMixinApplication;
-
- @override
bool get isValidMixin => actualElement.isValidMixin;
@override
@@ -380,10 +376,6 @@
@override
int get nameOffset => actualElement.nameOffset;
- @deprecated
- @override
- AstNode get node => computeNode();
-
@override
Source get source => actualElement.source;
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 8c981ff..70defdf 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -2,17 +2,17 @@
// for 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 engine.resolver.element_resolver;
+library analyzer.src.generated.element_resolver;
import 'dart:collection';
-import 'ast.dart';
-import 'element.dart';
-import 'engine.dart';
-import 'error.dart';
-import 'resolver.dart';
-import 'scanner.dart' as sc;
-import 'utilities_dart.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart' as sc;
+import 'package:analyzer/src/generated/utilities_dart.dart';
/**
* An object used by instances of [ResolverVisitor] to resolve references within
@@ -102,7 +102,7 @@
/**
* The type representing the type 'type'.
*/
- DartType _typeType;
+ InterfaceType _typeType;
/**
* A utility class for the resolver to answer the question of "what are my
@@ -594,8 +594,6 @@
}
Element staticElement;
Element propagatedElement;
- DartType staticType = null;
- DartType propagatedType = null;
if (target == null) {
staticElement = _resolveInvokedElement(methodName);
propagatedElement = null;
@@ -611,8 +609,6 @@
methodName.staticElement = importedLibrary.loadLibraryFunction;
return null;
} else {
- staticType = _getStaticType(target);
- propagatedType = _getPropagatedType(target);
//
// If this method invocation is of the form 'C.m' where 'C' is a class,
// then we don't call resolveInvokedElement(...) which walks up the class
@@ -622,8 +618,13 @@
bool isConditional = node.operator.type == sc.TokenType.QUESTION_PERIOD;
ClassElementImpl typeReference = getTypeReference(target);
if (typeReference != null) {
+ if (node.isCascaded) {
+ typeReference = _typeType.element;
+ }
staticElement = _resolveElement(typeReference, methodName);
} else {
+ DartType staticType = _getStaticType(target);
+ DartType propagatedType = _getPropagatedType(target);
staticElement = _resolveInvokedElementWithTarget(
target, staticType, methodName, isConditional);
// If we have propagated type information use it (since it should
@@ -635,6 +636,46 @@
}
}
}
+ //
+ // Check for a generic method & apply type arguments if any were passed.
+ //
+ if (staticElement is MethodElement || staticElement is FunctionElement) {
+ FunctionType type = (staticElement as ExecutableElement).type;
+ List<TypeParameterElement> parameters = type.boundTypeParameters;
+
+ NodeList<TypeName> arguments = node.typeArguments?.arguments;
+ if (arguments != null && arguments.length != parameters.length) {
+ // Wrong number of type arguments. Ignore them
+ arguments = null;
+ _resolver.reportErrorForNode(
+ StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
+ methodName,
+ [type, parameters.length, arguments.length]);
+ }
+ if (parameters.isNotEmpty) {
+ List<DartType> typeArgs;
+ if (arguments == null) {
+ typeArgs = new List<DartType>.filled(
+ parameters.length, DynamicTypeImpl.instance);
+ } else {
+ typeArgs = new List<DartType>.from(arguments.map((n) => n.type));
+ }
+ type = type.instantiate(typeArgs);
+
+ if (staticElement is MethodMember) {
+ MethodMember member = staticElement;
+ staticElement =
+ new MethodMember(member.baseElement, member.definingType, type);
+ } else if (staticElement is MethodElement) {
+ ClassElement clazz = staticElement.enclosingElement;
+ staticElement = new MethodMember(staticElement, clazz.type, type);
+ } else {
+ staticElement =
+ new FunctionMember(staticElement as FunctionElement, type);
+ }
+ }
+ }
+
staticElement = _convertSetterToGetter(staticElement);
propagatedElement = _convertSetterToGetter(propagatedElement);
//
@@ -733,17 +774,19 @@
// resolveArgumentsToParameters(node.getArgumentList(), invokedFunction);
return null;
}
- ClassElementImpl typeReference = getTypeReference(target);
- if (typeReference != null) {
- ConstructorElement constructor =
- typeReference.getNamedConstructor(methodName.name);
- if (constructor != null) {
- _recordUndefinedNode(
- typeReference,
- StaticTypeWarningCode.UNDEFINED_METHOD_WITH_CONSTRUCTOR,
- methodName,
- [methodName.name, typeReference.name]);
- return null;
+ if (!node.isCascaded) {
+ ClassElementImpl typeReference = getTypeReference(target);
+ if (typeReference != null) {
+ ConstructorElement constructor =
+ typeReference.getNamedConstructor(methodName.name);
+ if (constructor != null) {
+ _recordUndefinedNode(
+ typeReference,
+ StaticTypeWarningCode.UNDEFINED_METHOD_WITH_CONSTRUCTOR,
+ methodName,
+ [methodName.name, typeReference.name]);
+ return null;
+ }
}
}
targetTypeName = targetType == null ? null : targetType.displayName;
@@ -883,7 +926,7 @@
// Otherwise, the prefix is really an expression that happens to be a simple
// identifier and this is really equivalent to a property access node.
//
- _resolvePropertyAccess(prefix, identifier);
+ _resolvePropertyAccess(prefix, identifier, false);
return null;
}
@@ -939,7 +982,7 @@
return null;
}
SimpleIdentifier propertyName = node.propertyName;
- _resolvePropertyAccess(target, propertyName);
+ _resolvePropertyAccess(target, propertyName, node.isCascaded);
return null;
}
@@ -2211,7 +2254,7 @@
}
void _resolvePropertyAccess(
- Expression target, SimpleIdentifier propertyName) {
+ Expression target, SimpleIdentifier propertyName, bool isCascaded) {
DartType staticType = _getStaticType(target);
DartType propagatedType = _getPropagatedType(target);
Element staticElement = null;
@@ -2224,6 +2267,9 @@
//
ClassElementImpl typeReference = getTypeReference(target);
if (typeReference != null) {
+ if (isCascaded) {
+ typeReference = _typeType.element;
+ }
// TODO(brianwilkerson) Why are we setting the propagated element here?
// It looks wrong.
staticElement =
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index fbb9825..bafc908 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -2,50 +2,36 @@
// for 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 engine;
+library analyzer.src.generated.engine;
import 'dart:async';
import 'dart:collection';
-import 'dart:math' as math;
+import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/source/embedder.dart';
import 'package:analyzer/src/cancelable_future.dart';
-import 'package:analyzer/src/context/cache.dart' as cache;
-import 'package:analyzer/src/context/context.dart' as newContext;
-import 'package:analyzer/src/generated/incremental_resolution_validator.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:analyzer/src/plugin/command_line_plugin.dart';
import 'package:analyzer/src/plugin/engine_plugin.dart';
import 'package:analyzer/src/plugin/options_plugin.dart';
-import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/task/manager.dart';
import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/model.dart' as newContext;
import 'package:analyzer/task/model.dart';
import 'package:html/dom.dart' show Document;
import 'package:path/path.dart' as pathos;
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
-import '../../instrumentation/instrumentation.dart';
-import 'ast.dart';
-import 'constant.dart';
-import 'element.dart';
-import 'error.dart';
-import 'error_verifier.dart';
-import 'html.dart' as ht;
-import 'incremental_resolver.dart'
- show IncrementalResolver, PoorMansIncrementalResolver;
-import 'incremental_scanner.dart';
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'parser.dart' show Parser, IncrementalParser;
-import 'resolver.dart';
-import 'scanner.dart';
-import 'sdk.dart' show DartSdk;
-import 'source.dart';
-import 'utilities_collection.dart';
-import 'utilities_general.dart';
-
/**
* Used by [AnalysisOptions] to allow function bodies to be analyzed in some
* sources but not others.
@@ -53,226 +39,6 @@
typedef bool AnalyzeFunctionBodiesPredicate(Source source);
/**
- * Type of callback functions used by PendingFuture. Functions of this type
- * should perform a computation based on the data in [sourceEntry] and return
- * it. If the computation can't be performed yet because more analysis is
- * needed, null should be returned.
- *
- * The function may also throw an exception, in which case the corresponding
- * future will be completed with failure.
- *
- * Since this function is called while the state of analysis is being updated,
- * it should be free of side effects so that it doesn't cause reentrant
- * changes to the analysis state.
- */
-typedef T PendingFutureComputer<T>(SourceEntry sourceEntry);
-
-/**
- * An LRU cache of information related to analysis.
- */
-class AnalysisCache {
- /**
- * A flag used to control whether trace information should be produced when
- * the content of the cache is modified.
- */
- static bool _TRACE_CHANGES = false;
-
- /**
- * A list containing the partitions of which this cache is comprised.
- */
- final List<CachePartition> _partitions;
-
- /**
- * Initialize a newly created cache to have the given [_partitions]. The
- * partitions will be searched in the order in which they appear in the list,
- * so the most specific partition (usually an [SdkCachePartition]) should be
- * first and the most general (usually a [UniversalCachePartition]) last.
- */
- AnalysisCache(this._partitions);
-
- /**
- * Return the number of entries in this cache that have an AST associated with
- * them.
- */
- int get astSize => _partitions[_partitions.length - 1].astSize;
-
- /**
- * Return information about each of the partitions in this cache.
- */
- List<AnalysisContextStatistics_PartitionData> get partitionData {
- int count = _partitions.length;
- List<AnalysisContextStatistics_PartitionData> data =
- new List<AnalysisContextStatistics_PartitionData>(count);
- for (int i = 0; i < count; i++) {
- CachePartition partition = _partitions[i];
- data[i] = new AnalysisContextStatisticsImpl_PartitionDataImpl(
- partition.astSize, partition.map.length);
- }
- return data;
- }
-
- /**
- * Record that the AST associated with the given [source] was just read from
- * the cache.
- */
- void accessedAst(Source source) {
- int count = _partitions.length;
- for (int i = 0; i < count; i++) {
- if (_partitions[i].contains(source)) {
- _partitions[i].accessedAst(source);
- return;
- }
- }
- }
-
- /**
- * Return the entry associated with the given [source].
- */
- SourceEntry get(Source source) {
- int count = _partitions.length;
- for (int i = 0; i < count; i++) {
- if (_partitions[i].contains(source)) {
- return _partitions[i].get(source);
- }
- }
- //
- // We should never get to this point because the last partition should
- // always be a universal partition, except in the case of the SDK context,
- // in which case the source should always be part of the SDK.
- //
- return null;
- }
-
- /**
- * Return context that owns the given [source].
- */
- InternalAnalysisContext getContextFor(Source source) {
- int count = _partitions.length;
- for (int i = 0; i < count; i++) {
- if (_partitions[i].contains(source)) {
- return _partitions[i].context;
- }
- }
- //
- // We should never get to this point because the last partition should
- // always be a universal partition, except in the case of the SDK context,
- // in which case the source should always be part of the SDK.
- //
- AnalysisEngine.instance.logger.logInformation(
- "Could not find context for ${source.fullName}",
- new CaughtException(new AnalysisException(), null));
- return null;
- }
-
- /**
- * Return an iterator returning all of the map entries mapping sources to
- * cache entries.
- */
- MapIterator<Source, SourceEntry> iterator() {
- int count = _partitions.length;
- List<Map<Source, SourceEntry>> maps =
- new List<Map<Source, SourceEntry>>(count);
- for (int i = 0; i < count; i++) {
- maps[i] = _partitions[i].map;
- }
- return new MultipleMapIterator<Source, SourceEntry>(maps);
- }
-
- /**
- * Associate the given [entry] with the given [source].
- */
- void put(Source source, SourceEntry entry) {
- entry.fixExceptionState();
- int count = _partitions.length;
- for (int i = 0; i < count; i++) {
- if (_partitions[i].contains(source)) {
- if (_TRACE_CHANGES) {
- try {
- SourceEntry oldEntry = _partitions[i].get(source);
- if (oldEntry == null) {
- AnalysisEngine.instance.logger.logInformation(
- "Added a cache entry for '${source.fullName}'.");
- } else {
- AnalysisEngine.instance.logger.logInformation(
- "Modified the cache entry for ${source.fullName}'. Diff = ${entry.getDiff(oldEntry)}");
- }
- } catch (exception) {
- // Ignored
- JavaSystem.currentTimeMillis();
- }
- }
- _partitions[i].put(source, entry);
- return;
- }
- }
- }
-
- /**
- * Remove all information related to the given [source] from this cache.
- * Return the entry associated with the source, or `null` if there was cache
- * entry for the source.
- */
- SourceEntry remove(Source source) {
- int count = _partitions.length;
- for (int i = 0; i < count; i++) {
- if (_partitions[i].contains(source)) {
- if (_TRACE_CHANGES) {
- try {
- AnalysisEngine.instance.logger.logInformation(
- "Removed the cache entry for ${source.fullName}'.");
- } catch (exception) {
- // Ignored
- JavaSystem.currentTimeMillis();
- }
- }
- return _partitions[i].remove(source);
- }
- }
- return null;
- }
-
- /**
- * Record that the AST associated with the given [source] was just removed
- * from the cache.
- */
- void removedAst(Source source) {
- int count = _partitions.length;
- for (int i = 0; i < count; i++) {
- if (_partitions[i].contains(source)) {
- _partitions[i].removedAst(source);
- return;
- }
- }
- }
-
- /**
- * Return the number of sources that are mapped to cache entries.
- */
- int size() {
- int size = 0;
- int count = _partitions.length;
- for (int i = 0; i < count; i++) {
- size += _partitions[i].size();
- }
- return size;
- }
-
- /**
- * Record that the AST associated with the given [source] was just stored to
- * the cache.
- */
- void storedAst(Source source) {
- int count = _partitions.length;
- for (int i = 0; i < count; i++) {
- if (_partitions[i].contains(source)) {
- _partitions[i].storedAst(source);
- return;
- }
- }
- }
-}
-
-/**
* A context in which a single analysis can be performed and incrementally
* maintained. The context includes such information as the version of the SDK
* being analyzed against as well as the package-root used to resolve 'package:'
@@ -486,24 +252,6 @@
List<AnalysisError> computeErrors(Source source);
/**
- * Return the element model corresponding to the HTML file defined by the
- * given [source]. If the element model does not yet exist it will be created.
- * The process of creating an element model for an HTML file can be
- * long-running, depending on the size of the file and the number of libraries
- * that are defined in it (via script tags) that also need to have a model
- * built for them.
- *
- * Throws AnalysisException if the element model could not be determined
- * because the analysis could not be performed.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- *
- * See [getHtmlElement].
- */
- @deprecated
- HtmlElement computeHtmlElement(Source source);
-
- /**
* Return the kind of the given [source], computing it's kind if it is not
* already known. Return [SourceKind.UNKNOWN] if the source is not contained
* in this context.
@@ -564,7 +312,7 @@
* Perform work until the given [result] has been computed for the given
* [target]. Return the computed value.
*/
- Object /*V*/ computeResult(
+ Object /*=V*/ computeResult /*<V>*/ (
AnalysisTarget target, ResultDescriptor /*<V>*/ result);
/**
@@ -629,17 +377,6 @@
AnalysisErrorInfo getErrors(Source source);
/**
- * Return the element model corresponding to the HTML file defined by the
- * given [source], or `null` if the source does not represent an HTML file,
- * the element representing the file has not yet been created, or the analysis
- * of the HTML file failed for some reason.
- *
- * See [computeHtmlElement].
- */
- @deprecated
- HtmlElement getHtmlElement(Source source);
-
- /**
* Return the sources for the HTML files that reference the compilation unit
* with the given [source]. If the source does not represent a Dart source or
* is not known to this context, the returned list will be empty. The contents
@@ -732,21 +469,12 @@
Source unitSource, Source librarySource);
/**
- * Return the fully resolved HTML unit defined by the given [htmlSource], or
- * `null` if the resolved unit is not already computed.
- *
- * See [resolveHtmlUnit].
- */
- @deprecated
- ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource);
-
- /**
* Return the value of the given [result] for the given [target].
*
* If the corresponding [target] does not exist, or the [result] is not
* computed yet, then the default value is returned.
*/
- Object /*V*/ getResult(
+ Object /*=V*/ getResult /*<V>*/ (
AnalysisTarget target, ResultDescriptor /*<V>*/ result);
/**
@@ -811,18 +539,6 @@
Document parseHtmlDocument(Source source);
/**
- * Parse a single HTML [source] to produce an AST structure. The resulting
- * HTML AST structure may or may not be resolved, and may have a slightly
- * different structure depending upon whether it is resolved.
- *
- * Throws an [AnalysisException] if the analysis could not be performed
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- @deprecated // use parseHtmlDocument(source)
- ht.HtmlUnit parseHtmlUnit(Source source);
-
- /**
* Perform the next unit of work required to keep the analysis results
* up-to-date and return information about the consequent changes to the
* analysis results. This method can be long running.
@@ -877,17 +593,6 @@
Source unitSource, Source librarySource);
/**
- * Parse and resolve a single [htmlSource] within the given context to produce
- * a fully resolved AST.
- *
- * Throws an [AnalysisException] if the analysis could not be performed.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- @deprecated
- ht.HtmlUnit resolveHtmlUnit(Source htmlSource);
-
- /**
* Set the contents of the given [source] to the given [contents] and mark the
* source as having changed. The additional [offset] and [length] information
* is used by the context to determine what reanalysis is necessary.
@@ -920,4880 +625,6 @@
}
/**
- * An [AnalysisContext].
- */
-class AnalysisContextImpl implements InternalAnalysisContext {
- /**
- * The difference between the maximum cache size and the maximum priority
- * order size. The priority list must be capped so that it is less than the
- * cache size. Failure to do so can result in an infinite loop in
- * performAnalysisTask() because re-caching one AST structure can cause
- * another priority source's AST structure to be flushed.
- */
- static int _PRIORITY_ORDER_SIZE_DELTA = 4;
-
- /**
- * A flag indicating whether trace output should be produced as analysis tasks
- * are performed. Used for debugging.
- */
- static bool _TRACE_PERFORM_TASK = false;
-
- /**
- * The next context identifier.
- */
- static int _NEXT_ID = 0;
-
- /**
- * The unique identifier of this context.
- */
- final int _id = _NEXT_ID++;
-
- /**
- * A client-provided name used to identify this context, or `null` if the
- * client has not provided a name.
- */
- String name;
-
- /**
- * Configuration data associated with this context.
- */
- final HashMap<ResultDescriptor, Object> _configurationData =
- new HashMap<ResultDescriptor, Object>();
-
- /**
- * The set of analysis options controlling the behavior of this context.
- */
- AnalysisOptionsImpl _options = new AnalysisOptionsImpl();
-
- /// The embedder yaml locator for this context.
- EmbedderYamlLocator _embedderYamlLocator = new EmbedderYamlLocator(null);
-
- /**
- * A flag indicating whether errors related to implicitly analyzed sources
- * should be generated and reported.
- */
- bool _generateImplicitErrors = true;
-
- /**
- * A flag indicating whether errors related to sources in the SDK should be
- * generated and reported.
- */
- bool _generateSdkErrors = true;
-
- /**
- * A flag indicating whether this context is disposed.
- */
- bool _disposed = false;
-
- /**
- * A cache of content used to override the default content of a source.
- */
- ContentCache _contentCache = new ContentCache();
-
- /**
- * The source factory used to create the sources that can be analyzed in this
- * context.
- */
- SourceFactory _sourceFactory;
-
- /**
- * The set of declared variables used when computing constant values.
- */
- DeclaredVariables _declaredVariables = new DeclaredVariables();
-
- /**
- * A source representing the core library.
- */
- Source _coreLibrarySource;
-
- /**
- * A source representing the async library.
- */
- Source _asyncLibrarySource;
-
- /**
- * The partition that contains analysis results that are not shared with other
- * contexts.
- */
- CachePartition _privatePartition;
-
- /**
- * A table mapping the sources known to the context to the information known
- * about the source.
- */
- AnalysisCache _cache;
-
- /**
- * A list containing sources for which data should not be flushed.
- */
- List<Source> _priorityOrder = Source.EMPTY_LIST;
-
- /**
- * A map from all sources for which there are futures pending to a list of
- * the corresponding PendingFuture objects. These sources will be analyzed
- * in the same way as priority sources, except with higher priority.
- *
- * TODO(paulberry): since the size of this map is not constrained (as it is
- * for _priorityOrder), we run the risk of creating an analysis loop if
- * re-caching one AST structure causes the AST structure for another source
- * with pending futures to be flushed. However, this is unlikely to happen
- * in practice since sources are removed from this hash set as soon as their
- * futures have completed.
- */
- HashMap<Source, List<PendingFuture>> _pendingFutureSources =
- new HashMap<Source, List<PendingFuture>>();
-
- /**
- * A list containing sources whose AST structure is needed in order to resolve
- * the next library to be resolved.
- */
- HashSet<Source> _neededForResolution = null;
-
- /**
- * A table mapping sources to the change notices that are waiting to be
- * returned related to that source.
- */
- HashMap<Source, ChangeNoticeImpl> _pendingNotices =
- new HashMap<Source, ChangeNoticeImpl>();
-
- /**
- * The object used to record the results of performing an analysis task.
- */
- AnalysisContextImpl_AnalysisTaskResultRecorder _resultRecorder;
-
- /**
- * Cached information used in incremental analysis or `null` if none.
- */
- IncrementalAnalysisCache _incrementalAnalysisCache;
-
- /**
- * The [TypeProvider] for this context, `null` if not yet created.
- */
- TypeProvider _typeProvider;
-
- /**
- * The [TypeSystem] for this context, `null` if not yet created.
- */
- TypeSystem _typeSystem;
-
- /**
- * The object used to manage the list of sources that need to be analyzed.
- */
- WorkManager _workManager = new WorkManager();
-
- /**
- * The [Stopwatch] of the current "perform tasks cycle".
- */
- Stopwatch _performAnalysisTaskStopwatch;
-
- /**
- * The controller for sending [SourcesChangedEvent]s.
- */
- StreamController<SourcesChangedEvent> _onSourcesChangedController;
-
- /**
- * A subscription for a stream of events indicating when files are (and are
- * not) being implicitly analyzed.
- */
- StreamController<ImplicitAnalysisEvent> _implicitAnalysisEventsController;
-
- /**
- * The listeners that are to be notified when various analysis results are
- * produced in this context.
- */
- List<AnalysisListener> _listeners = new List<AnalysisListener>();
-
- /**
- * The most recently incrementally resolved source, or `null` when it was
- * already validated, or the most recent change was not incrementally resolved.
- */
- Source incrementalResolutionValidation_lastUnitSource;
-
- /**
- * The most recently incrementally resolved library source, or `null` when it
- * was already validated, or the most recent change was not incrementally
- * resolved.
- */
- Source incrementalResolutionValidation_lastLibrarySource;
-
- /**
- * The result of incremental resolution result of
- * [incrementalResolutionValidation_lastSource].
- */
- CompilationUnit incrementalResolutionValidation_lastUnit;
-
- /**
- * A factory to override how the [ResolverVisitor] is created.
- */
- ResolverVisitorFactory resolverVisitorFactory;
-
- /**
- * A factory to override how the [TypeResolverVisitor] is created.
- */
- TypeResolverVisitorFactory typeResolverVisitorFactory;
-
- /**
- * A factory to override how [LibraryResolver] is created.
- */
- LibraryResolverFactory libraryResolverFactory;
-
- /**
- * Initialize a newly created analysis context.
- */
- AnalysisContextImpl() {
- _resultRecorder = new AnalysisContextImpl_AnalysisTaskResultRecorder(this);
- _privatePartition = new UniversalCachePartition(
- this,
- AnalysisOptionsImpl.DEFAULT_CACHE_SIZE,
- new AnalysisContextImpl_ContextRetentionPolicy(this));
- _cache = createCacheFromSourceFactory(null);
- _onSourcesChangedController =
- new StreamController<SourcesChangedEvent>.broadcast();
- _implicitAnalysisEventsController =
- new StreamController<ImplicitAnalysisEvent>.broadcast();
- }
-
- @override
- AnalysisCache get analysisCache => _cache;
-
- @override
- AnalysisOptions get analysisOptions => _options;
-
- @override
- void set analysisOptions(AnalysisOptions options) {
- bool needsRecompute = this._options.analyzeFunctionBodiesPredicate !=
- options.analyzeFunctionBodiesPredicate ||
- this._options.generateImplicitErrors !=
- options.generateImplicitErrors ||
- this._options.generateSdkErrors != options.generateSdkErrors ||
- this._options.dart2jsHint != options.dart2jsHint ||
- (this._options.hint && !options.hint) ||
- this._options.preserveComments != options.preserveComments ||
- this._options.strongMode != options.strongMode ||
- ((options is AnalysisOptionsImpl)
- ? this._options.strongModeHints != options.strongModeHints
- : false) ||
- this._options.enableStrictCallChecks !=
- options.enableStrictCallChecks ||
- this._options.enableSuperMixins != options.enableSuperMixins;
- int cacheSize = options.cacheSize;
- if (this._options.cacheSize != cacheSize) {
- this._options.cacheSize = cacheSize;
- //cache.setMaxCacheSize(cacheSize);
- _privatePartition.maxCacheSize = cacheSize;
- //
- // Cap the size of the priority list to being less than the cache size.
- // Failure to do so can result in an infinite loop in
- // performAnalysisTask() because re-caching one AST structure
- // can cause another priority source's AST structure to be flushed.
- //
- // TODO(brianwilkerson) Remove this constraint when the new task model is
- // implemented.
- //
- int maxPriorityOrderSize = cacheSize - _PRIORITY_ORDER_SIZE_DELTA;
- if (_priorityOrder.length > maxPriorityOrderSize) {
- _priorityOrder = _priorityOrder.sublist(0, maxPriorityOrderSize);
- }
- }
- this._options.analyzeFunctionBodiesPredicate =
- options.analyzeFunctionBodiesPredicate;
- this._options.generateImplicitErrors = options.generateImplicitErrors;
- this._options.generateSdkErrors = options.generateSdkErrors;
- this._options.dart2jsHint = options.dart2jsHint;
- this._options.enableStrictCallChecks = options.enableStrictCallChecks;
- this._options.enableSuperMixins = options.enableSuperMixins;
- this._options.hint = options.hint;
- this._options.incremental = options.incremental;
- this._options.incrementalApi = options.incrementalApi;
- this._options.incrementalValidation = options.incrementalValidation;
- this._options.lint = options.lint;
- this._options.preserveComments = options.preserveComments;
- this._options.strongMode = options.strongMode;
- if (options is AnalysisOptionsImpl) {
- this._options.strongModeHints = options.strongModeHints;
- }
- _generateImplicitErrors = options.generateImplicitErrors;
- _generateSdkErrors = options.generateSdkErrors;
- if (needsRecompute) {
- _invalidateAllLocalResolutionInformation(false);
- }
- }
-
- @override
- void set analysisPriorityOrder(List<Source> sources) {
- if (sources == null || sources.isEmpty) {
- _priorityOrder = Source.EMPTY_LIST;
- } else {
- while (sources.remove(null)) {
- // Nothing else to do.
- }
- if (sources.isEmpty) {
- _priorityOrder = Source.EMPTY_LIST;
- }
- //
- // Cap the size of the priority list to being less than the cache size.
- // Failure to do so can result in an infinite loop in
- // performAnalysisTask() because re-caching one AST structure
- // can cause another priority source's AST structure to be flushed.
- //
- int count = math.min(
- sources.length, _options.cacheSize - _PRIORITY_ORDER_SIZE_DELTA);
- _priorityOrder = new List<Source>(count);
- for (int i = 0; i < count; i++) {
- _priorityOrder[i] = sources[i];
- }
- // Ensure entries for every priority source.
- for (var source in _priorityOrder) {
- SourceEntry entry = _getReadableSourceEntry(source);
- if (entry == null) {
- _createSourceEntry(source, false);
- }
- }
- }
- }
-
- @override
- set contentCache(ContentCache value) {
- _contentCache = value;
- }
-
- @override
- DeclaredVariables get declaredVariables => _declaredVariables;
-
- @override
- EmbedderYamlLocator get embedderYamlLocator => _embedderYamlLocator;
-
- @override
- List<AnalysisTarget> get explicitTargets {
- List<AnalysisTarget> targets = <AnalysisTarget>[];
- MapIterator<Source, SourceEntry> iterator = _cache.iterator();
- while (iterator.moveNext()) {
- if (iterator.value.explicitlyAdded) {
- targets.add(iterator.key);
- }
- }
- return targets;
- }
-
- @override
- List<Source> get htmlSources => _getSources(SourceKind.HTML);
-
- @override
- Stream<ImplicitAnalysisEvent> get implicitAnalysisEvents =>
- _implicitAnalysisEventsController.stream;
-
- @override
- bool get isDisposed => _disposed;
-
- @override
- List<Source> get launchableClientLibrarySources {
- // TODO(brianwilkerson) This needs to filter out libraries that do not
- // reference dart:html, either directly or indirectly.
- List<Source> sources = new List<Source>();
- MapIterator<Source, SourceEntry> iterator = _cache.iterator();
- while (iterator.moveNext()) {
- Source source = iterator.key;
- SourceEntry sourceEntry = iterator.value;
- if (sourceEntry.kind == SourceKind.LIBRARY && !source.isInSystemLibrary) {
-// DartEntry dartEntry = (DartEntry) sourceEntry;
-// if (dartEntry.getValue(DartEntry.IS_LAUNCHABLE) && dartEntry.getValue(DartEntry.IS_CLIENT)) {
- sources.add(source);
-// }
- }
- }
- return sources;
- }
-
- @override
- List<Source> get launchableServerLibrarySources {
- // TODO(brianwilkerson) This needs to filter out libraries that reference
- // dart:html, either directly or indirectly.
- List<Source> sources = new List<Source>();
- MapIterator<Source, SourceEntry> iterator = _cache.iterator();
- while (iterator.moveNext()) {
- Source source = iterator.key;
- SourceEntry sourceEntry = iterator.value;
- if (sourceEntry.kind == SourceKind.LIBRARY && !source.isInSystemLibrary) {
-// DartEntry dartEntry = (DartEntry) sourceEntry;
-// if (dartEntry.getValue(DartEntry.IS_LAUNCHABLE) && !dartEntry.getValue(DartEntry.IS_CLIENT)) {
- sources.add(source);
-// }
- }
- }
- return sources;
- }
-
- @override
- List<Source> get librarySources => _getSources(SourceKind.LIBRARY);
-
- /**
- * Look through the cache for a task that needs to be performed. Return the
- * task that was found, or `null` if there is no more work to be done.
- */
- AnalysisTask get nextAnalysisTask {
- bool hintsEnabled = _options.hint;
- bool lintsEnabled = _options.lint;
- bool hasBlockedTask = false;
- //
- // Look for incremental analysis
- //
- if (_incrementalAnalysisCache != null &&
- _incrementalAnalysisCache.hasWork) {
- AnalysisTask task =
- new IncrementalAnalysisTask(this, _incrementalAnalysisCache);
- _incrementalAnalysisCache = null;
- return task;
- }
- //
- // Look for a source that needs to be analyzed because it has futures
- // pending.
- //
- if (_pendingFutureSources.isNotEmpty) {
- List<Source> sourcesToRemove = <Source>[];
- AnalysisTask task;
- for (Source source in _pendingFutureSources.keys) {
- SourceEntry sourceEntry = _cache.get(source);
- List<PendingFuture> pendingFutures = _pendingFutureSources[source];
- for (int i = 0; i < pendingFutures.length;) {
- if (pendingFutures[i].evaluate(sourceEntry)) {
- pendingFutures.removeAt(i);
- } else {
- i++;
- }
- }
- if (pendingFutures.isEmpty) {
- sourcesToRemove.add(source);
- continue;
- }
- AnalysisContextImpl_TaskData taskData = _getNextAnalysisTaskForSource(
- source, sourceEntry, true, hintsEnabled, lintsEnabled);
- task = taskData.task;
- if (task != null) {
- break;
- } else if (taskData.isBlocked) {
- hasBlockedTask = true;
- } else {
- // There is no more work to do for this task, so forcibly complete
- // all its pending futures.
- for (PendingFuture pendingFuture in pendingFutures) {
- pendingFuture.forciblyComplete();
- }
- sourcesToRemove.add(source);
- }
- }
- for (Source source in sourcesToRemove) {
- _pendingFutureSources.remove(source);
- }
- if (task != null) {
- return task;
- }
- }
- //
- // Look for a priority source that needs to be analyzed.
- //
- int priorityCount = _priorityOrder.length;
- for (int i = 0; i < priorityCount; i++) {
- Source source = _priorityOrder[i];
- AnalysisContextImpl_TaskData taskData = _getNextAnalysisTaskForSource(
- source, _cache.get(source), true, hintsEnabled, lintsEnabled);
- AnalysisTask task = taskData.task;
- if (task != null) {
- return task;
- } else if (taskData.isBlocked) {
- hasBlockedTask = true;
- }
- }
- if (_neededForResolution != null) {
- List<Source> sourcesToRemove = new List<Source>();
- for (Source source in _neededForResolution) {
- SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry;
- if (!dartEntry.hasResolvableCompilationUnit) {
- if (dartEntry.getState(DartEntry.PARSED_UNIT) == CacheState.ERROR) {
- sourcesToRemove.add(source);
- } else {
- AnalysisContextImpl_TaskData taskData =
- _createParseDartTask(source, dartEntry);
- AnalysisTask task = taskData.task;
- if (task != null) {
- return task;
- } else if (taskData.isBlocked) {
- hasBlockedTask = true;
- }
- }
- }
- }
- }
- int count = sourcesToRemove.length;
- for (int i = 0; i < count; i++) {
- _neededForResolution.remove(sourcesToRemove[i]);
- }
- }
- //
- // Look for a non-priority source that needs to be analyzed.
- //
- List<Source> sourcesToRemove = new List<Source>();
- WorkManager_WorkIterator sources = _workManager.iterator();
- try {
- while (sources.hasNext) {
- Source source = sources.next();
- AnalysisContextImpl_TaskData taskData = _getNextAnalysisTaskForSource(
- source, _cache.get(source), false, hintsEnabled, lintsEnabled);
- AnalysisTask task = taskData.task;
- if (task != null) {
- return task;
- } else if (taskData.isBlocked) {
- hasBlockedTask = true;
- } else {
- sourcesToRemove.add(source);
- }
- }
- } finally {
- int count = sourcesToRemove.length;
- for (int i = 0; i < count; i++) {
- _workManager.remove(sourcesToRemove[i]);
- }
- }
- if (hasBlockedTask) {
- // All of the analysis work is blocked waiting for an asynchronous task
- // to complete.
- return WaitForAsyncTask.instance;
- }
- return null;
- }
-
- @override
- Stream<SourcesChangedEvent> get onSourcesChanged =>
- _onSourcesChangedController.stream;
-
- /**
- * Make _pendingFutureSources available to unit tests.
- */
- HashMap<Source, List<PendingFuture>> get pendingFutureSources_forTesting =>
- _pendingFutureSources;
-
- @override
- List<Source> get prioritySources => _priorityOrder;
-
- @override
- List<AnalysisTarget> get priorityTargets => prioritySources;
-
- @override
- CachePartition get privateAnalysisCachePartition => _privatePartition;
-
- @override
- SourceFactory get sourceFactory => _sourceFactory;
-
- @override
- void set sourceFactory(SourceFactory factory) {
- if (identical(_sourceFactory, factory)) {
- return;
- } else if (factory.context != null) {
- throw new IllegalStateException(
- "Source factories cannot be shared between contexts");
- }
- if (_sourceFactory != null) {
- _sourceFactory.context = null;
- }
- factory.context = this;
- _sourceFactory = factory;
- _coreLibrarySource = _sourceFactory.forUri(DartSdk.DART_CORE);
- _asyncLibrarySource = _sourceFactory.forUri(DartSdk.DART_ASYNC);
- _cache = createCacheFromSourceFactory(factory);
- _invalidateAllLocalResolutionInformation(true);
- }
-
- @override
- List<Source> get sources {
- List<Source> sources = new List<Source>();
- MapIterator<Source, SourceEntry> iterator = _cache.iterator();
- while (iterator.moveNext()) {
- sources.add(iterator.key);
- }
- return sources;
- }
-
- /**
- * Return a list of the sources that would be processed by
- * [performAnalysisTask]. This method duplicates, and must therefore be kept
- * in sync with, [getNextAnalysisTask]. This method is intended to be used for
- * testing purposes only.
- */
- List<Source> get sourcesNeedingProcessing {
- HashSet<Source> sources = new HashSet<Source>();
- bool hintsEnabled = _options.hint;
- bool lintsEnabled = _options.lint;
-
- //
- // Look for priority sources that need to be analyzed.
- //
- for (Source source in _priorityOrder) {
- _getSourcesNeedingProcessing(source, _cache.get(source), true,
- hintsEnabled, lintsEnabled, sources);
- }
- //
- // Look for non-priority sources that need to be analyzed.
- //
- WorkManager_WorkIterator iterator = _workManager.iterator();
- while (iterator.hasNext) {
- Source source = iterator.next();
- _getSourcesNeedingProcessing(source, _cache.get(source), false,
- hintsEnabled, lintsEnabled, sources);
- }
- return new List<Source>.from(sources);
- }
-
- @override
- AnalysisContextStatistics get statistics {
- AnalysisContextStatisticsImpl statistics =
- new AnalysisContextStatisticsImpl();
- visitCacheItems(statistics._internalPutCacheItem);
- statistics.partitionData = _cache.partitionData;
- return statistics;
- }
-
- IncrementalAnalysisCache get test_incrementalAnalysisCache {
- return _incrementalAnalysisCache;
- }
-
- set test_incrementalAnalysisCache(IncrementalAnalysisCache value) {
- _incrementalAnalysisCache = value;
- }
-
- List<Source> get test_priorityOrder => _priorityOrder;
-
- @override
- TypeProvider get typeProvider {
- if (_typeProvider != null) {
- return _typeProvider;
- }
- Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE);
- if (coreSource == null) {
- throw new AnalysisException("Could not create a source for dart:core");
- }
- LibraryElement coreElement = computeLibraryElement(coreSource);
- if (coreElement == null) {
- throw new AnalysisException("Could not create an element for dart:core");
- }
- Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
- if (asyncSource == null) {
- throw new AnalysisException("Could not create a source for dart:async");
- }
- LibraryElement asyncElement = computeLibraryElement(asyncSource);
- if (asyncElement == null) {
- throw new AnalysisException("Could not create an element for dart:async");
- }
- _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
- return _typeProvider;
- }
-
- /**
- * Sets the [TypeProvider] for this context.
- */
- void set typeProvider(TypeProvider typeProvider) {
- _typeProvider = typeProvider;
- }
-
- @override
- TypeSystem get typeSystem {
- if (_typeSystem == null) {
- _typeSystem = TypeSystem.create(this);
- }
- return _typeSystem;
- }
-
- @override
- List<newContext.WorkManager> get workManagers {
- throw new NotImplementedException('In not task-based AnalysisContext.');
- }
-
- @override
- void addListener(AnalysisListener listener) {
- if (!_listeners.contains(listener)) {
- _listeners.add(listener);
- }
- }
-
- @override
- void applyAnalysisDelta(AnalysisDelta delta) {
- ChangeSet changeSet = new ChangeSet();
- delta.analysisLevels.forEach((Source source, AnalysisLevel level) {
- if (level == AnalysisLevel.NONE) {
- changeSet.removedSource(source);
- } else {
- changeSet.addedSource(source);
- }
- });
- applyChanges(changeSet);
- }
-
- @override
- ApplyChangesStatus applyChanges(ChangeSet changeSet) {
- if (changeSet.isEmpty) {
- return new ApplyChangesStatus(false);
- }
- //
- // First, compute the list of sources that have been removed.
- //
- List<Source> removedSources =
- new List<Source>.from(changeSet.removedSources);
- for (SourceContainer container in changeSet.removedContainers) {
- _addSourcesInContainer(removedSources, container);
- }
- //
- // Then determine which cached results are no longer valid.
- //
- for (Source source in changeSet.addedSources) {
- _sourceAvailable(source);
- }
- for (Source source in changeSet.changedSources) {
- if (_contentCache.getContents(source) != null) {
- // This source is overridden in the content cache, so the change will
- // have no effect. Just ignore it to avoid wasting time doing
- // re-analysis.
- continue;
- }
- _sourceChanged(source);
- }
- changeSet.changedContents.forEach((Source key, String value) {
- _contentsChanged(key, value, false);
- });
- changeSet.changedRanges
- .forEach((Source source, ChangeSet_ContentChange change) {
- _contentRangeChanged(source, change.contents, change.offset,
- change.oldLength, change.newLength);
- });
- for (Source source in changeSet.deletedSources) {
- _sourceDeleted(source);
- }
- for (Source source in removedSources) {
- _sourceRemoved(source);
- }
- _onSourcesChangedController.add(new SourcesChangedEvent(changeSet));
- return new ApplyChangesStatus(true);
- }
-
- @override
- String computeDocumentationComment(Element element) {
- if (element == null) {
- return null;
- }
- Source source = element.source;
- if (source == null) {
- return null;
- }
- SourceRange docRange = element.docRange;
- if (docRange == null) {
- return null;
- }
- String code = getContents(source).data;
- String comment = code.substring(docRange.offset, docRange.end);
- return comment.replaceAll('\r\n', '\n');
- }
-
- @override
- List<AnalysisError> computeErrors(Source source) {
- bool enableHints = _options.hint;
- bool enableLints = _options.lint;
-
- SourceEntry sourceEntry = _getReadableSourceEntry(source);
- if (sourceEntry is DartEntry) {
- List<AnalysisError> errors = new List<AnalysisError>();
- try {
- DartEntry dartEntry = sourceEntry;
- ListUtilities.addAll(
- errors, _getDartScanData(source, dartEntry, DartEntry.SCAN_ERRORS));
- dartEntry = _getReadableDartEntry(source);
- ListUtilities.addAll(errors,
- _getDartParseData(source, dartEntry, DartEntry.PARSE_ERRORS));
- dartEntry = _getReadableDartEntry(source);
- if (dartEntry.getValue(DartEntry.SOURCE_KIND) == SourceKind.LIBRARY) {
- ListUtilities.addAll(
- errors,
- _getDartResolutionData(
- source, source, dartEntry, DartEntry.RESOLUTION_ERRORS));
- dartEntry = _getReadableDartEntry(source);
- ListUtilities.addAll(
- errors,
- _getDartVerificationData(
- source, source, dartEntry, DartEntry.VERIFICATION_ERRORS));
- if (enableHints) {
- dartEntry = _getReadableDartEntry(source);
- ListUtilities.addAll(errors,
- _getDartHintData(source, source, dartEntry, DartEntry.HINTS));
- }
- if (enableLints) {
- dartEntry = _getReadableDartEntry(source);
- ListUtilities.addAll(errors,
- _getDartLintData(source, source, dartEntry, DartEntry.LINTS));
- }
- } else {
- List<Source> libraries = getLibrariesContaining(source);
- for (Source librarySource in libraries) {
- ListUtilities.addAll(
- errors,
- _getDartResolutionData(source, librarySource, dartEntry,
- DartEntry.RESOLUTION_ERRORS));
- dartEntry = _getReadableDartEntry(source);
- ListUtilities.addAll(
- errors,
- _getDartVerificationData(source, librarySource, dartEntry,
- DartEntry.VERIFICATION_ERRORS));
- if (enableHints) {
- dartEntry = _getReadableDartEntry(source);
- ListUtilities.addAll(
- errors,
- _getDartHintData(
- source, librarySource, dartEntry, DartEntry.HINTS));
- }
- if (enableLints) {
- dartEntry = _getReadableDartEntry(source);
- ListUtilities.addAll(
- errors,
- _getDartLintData(
- source, librarySource, dartEntry, DartEntry.LINTS));
- }
- }
- }
- } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
- AnalysisEngine.instance.logger.logInformation(
- "Could not compute errors",
- new CaughtException(exception, stackTrace));
- }
- if (errors.isEmpty) {
- return AnalysisError.NO_ERRORS;
- }
- return errors;
- } else if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry;
- try {
- return _getHtmlResolutionData2(
- source, htmlEntry, HtmlEntry.RESOLUTION_ERRORS);
- } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
- AnalysisEngine.instance.logger.logInformation(
- "Could not compute errors",
- new CaughtException(exception, stackTrace));
- }
- }
- return AnalysisError.NO_ERRORS;
- }
-
- @override
- List<Source> computeExportedLibraries(Source source) => _getDartParseData2(
- source, DartEntry.EXPORTED_LIBRARIES, Source.EMPTY_LIST);
-
- @override
- @deprecated
- HtmlElement computeHtmlElement(Source source) =>
- _getHtmlResolutionData(source, HtmlEntry.ELEMENT, null);
-
- @override
- List<Source> computeImportedLibraries(Source source) => _getDartParseData2(
- source, DartEntry.IMPORTED_LIBRARIES, Source.EMPTY_LIST);
-
- @override
- SourceKind computeKindOf(Source source) {
- SourceEntry sourceEntry = _getReadableSourceEntry(source);
- if (sourceEntry == null) {
- return SourceKind.UNKNOWN;
- } else if (sourceEntry is DartEntry) {
- try {
- return _getDartParseData(source, sourceEntry, DartEntry.SOURCE_KIND);
- } on AnalysisException {
- return SourceKind.UNKNOWN;
- }
- }
- return sourceEntry.kind;
- }
-
- @override
- LibraryElement computeLibraryElement(Source source) =>
- _getDartResolutionData2(source, source, DartEntry.ELEMENT, null);
-
- @override
- LineInfo computeLineInfo(Source source) {
- SourceEntry sourceEntry = _getReadableSourceEntry(source);
- try {
- if (sourceEntry is HtmlEntry) {
- return _getHtmlParseData(source, SourceEntry.LINE_INFO, null);
- } else if (sourceEntry is DartEntry) {
- return _getDartScanData2(source, SourceEntry.LINE_INFO, null);
- }
- } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
- AnalysisEngine.instance.logger.logInformation(
- "Could not compute ${SourceEntry.LINE_INFO}",
- new CaughtException(exception, stackTrace));
- }
- return null;
- }
-
- @override
- CompilationUnit computeResolvableCompilationUnit(Source source) {
- DartEntry dartEntry = _getReadableDartEntry(source);
- if (dartEntry == null) {
- throw new AnalysisException(
- "computeResolvableCompilationUnit for non-Dart: ${source.fullName}");
- }
- dartEntry = _cacheDartParseData(source, dartEntry, DartEntry.PARSED_UNIT);
- CompilationUnit unit = dartEntry.resolvableCompilationUnit;
- if (unit == null) {
- throw new AnalysisException(
- "Internal error: computeResolvableCompilationUnit could not parse ${source.fullName}",
- new CaughtException(dartEntry.exception, null));
- }
- return unit;
- }
-
- @override
- CancelableFuture<CompilationUnit> computeResolvedCompilationUnitAsync(
- Source unitSource, Source librarySource) {
- return new _AnalysisFutureHelper<CompilationUnit>(this)
- .computeAsync(unitSource, (SourceEntry sourceEntry) {
- if (sourceEntry is DartEntry) {
- if (sourceEntry.getStateInLibrary(
- DartEntry.RESOLVED_UNIT, librarySource) ==
- CacheState.ERROR) {
- throw sourceEntry.exception;
- }
- return sourceEntry.getValueInLibrary(
- DartEntry.RESOLVED_UNIT, librarySource);
- }
- throw new AnalysisNotScheduledError();
- });
- }
-
- @override
- Object computeResult(AnalysisTarget target, ResultDescriptor result) {
- return result.defaultValue;
- }
-
- /**
- * Create an analysis cache based on the given source [factory].
- */
- AnalysisCache createCacheFromSourceFactory(SourceFactory factory) {
- if (factory == null) {
- return new AnalysisCache(<CachePartition>[_privatePartition]);
- }
- DartSdk sdk = factory.dartSdk;
- if (sdk == null) {
- return new AnalysisCache(<CachePartition>[_privatePartition]);
- }
- return new AnalysisCache(<CachePartition>[
- AnalysisEngine.instance.partitionManager.forSdk(sdk),
- _privatePartition
- ]);
- }
-
- @override
- void dispose() {
- _disposed = true;
- for (List<PendingFuture> pendingFutures in _pendingFutureSources.values) {
- for (PendingFuture pendingFuture in pendingFutures) {
- pendingFuture.forciblyComplete();
- }
- }
- _pendingFutureSources.clear();
- }
-
- @override
- List<CompilationUnit> ensureResolvedDartUnits(Source unitSource) {
- SourceEntry sourceEntry = _cache.get(unitSource);
- if (sourceEntry is! DartEntry) {
- return null;
- }
- DartEntry dartEntry = sourceEntry;
- // Check every library.
- List<CompilationUnit> units = <CompilationUnit>[];
- List<Source> containingLibraries = dartEntry.containingLibraries;
- for (Source librarySource in containingLibraries) {
- CompilationUnit unit =
- dartEntry.getValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource);
- if (unit == null) {
- units = null;
- break;
- }
- units.add(unit);
- }
- // Invalidate the flushed RESOLVED_UNIT to force it eventually.
- if (units == null) {
- bool shouldBeScheduled = false;
- for (Source librarySource in containingLibraries) {
- if (dartEntry.getStateInLibrary(
- DartEntry.RESOLVED_UNIT, librarySource) ==
- CacheState.FLUSHED) {
- dartEntry.setStateInLibrary(
- DartEntry.RESOLVED_UNIT, librarySource, CacheState.INVALID);
- shouldBeScheduled = true;
- }
- }
- if (shouldBeScheduled) {
- _workManager.add(unitSource, SourcePriority.UNKNOWN);
- }
- // We cannot provide resolved units right now,
- // but the future analysis will.
- return null;
- }
- // done
- return units;
- }
-
- @override
- bool exists(Source source) {
- if (source == null) {
- return false;
- }
- if (_contentCache.getContents(source) != null) {
- return true;
- }
- return source.exists();
- }
-
- @override
- cache.CacheEntry getCacheEntry(AnalysisTarget target) {
- return null;
- }
-
- @override
- CompilationUnitElement getCompilationUnitElement(
- Source unitSource, Source librarySource) {
- LibraryElement libraryElement = getLibraryElement(librarySource);
- if (libraryElement != null) {
- // try defining unit
- CompilationUnitElement definingUnit =
- libraryElement.definingCompilationUnit;
- if (definingUnit.source == unitSource) {
- return definingUnit;
- }
- // try parts
- for (CompilationUnitElement partUnit in libraryElement.parts) {
- if (partUnit.source == unitSource) {
- return partUnit;
- }
- }
- }
- return null;
- }
-
- @override
- Object getConfigurationData(ResultDescriptor key) => _configurationData[key];
-
- @override
- TimestampedData<String> getContents(Source source) {
- String contents = _contentCache.getContents(source);
- if (contents != null) {
- return new TimestampedData<String>(
- _contentCache.getModificationStamp(source), contents);
- }
- return source.contents;
- }
-
- @override
- InternalAnalysisContext getContextFor(Source source) {
- InternalAnalysisContext context = _cache.getContextFor(source);
- return context == null ? this : context;
- }
-
- @override
- Element getElement(ElementLocation location) {
- // TODO(brianwilkerson) This should not be a "get" method.
- try {
- List<String> components = location.components;
- Source source = _computeSourceFromEncoding(components[0]);
- String sourceName = source.shortName;
- if (AnalysisEngine.isDartFileName(sourceName)) {
- ElementImpl element = computeLibraryElement(source) as ElementImpl;
- for (int i = 1; i < components.length; i++) {
- if (element == null) {
- return null;
- }
- element = element.getChild(components[i]);
- }
- return element;
- }
- if (AnalysisEngine.isHtmlFileName(sourceName)) {
- return computeHtmlElement(source);
- }
- } catch (exception) {
- // If the location cannot be decoded for some reason then the underlying
- // cause should have been logged already and we can fall though to return
- // null.
- }
- return null;
- }
-
- @override
- AnalysisErrorInfo getErrors(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry;
- return new AnalysisErrorInfoImpl(
- dartEntry.allErrors, dartEntry.getValue(SourceEntry.LINE_INFO));
- } else if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry;
- return new AnalysisErrorInfoImpl(
- htmlEntry.allErrors, htmlEntry.getValue(SourceEntry.LINE_INFO));
- }
- return new AnalysisErrorInfoImpl(AnalysisError.NO_ERRORS, null);
- }
-
- @override
- @deprecated
- HtmlElement getHtmlElement(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
- if (sourceEntry is HtmlEntry) {
- return sourceEntry.getValue(HtmlEntry.ELEMENT);
- }
- return null;
- }
-
- @override
- List<Source> getHtmlFilesReferencing(Source source) {
- SourceKind sourceKind = getKindOf(source);
- if (sourceKind == null) {
- return Source.EMPTY_LIST;
- }
- List<Source> htmlSources = new List<Source>();
- while (true) {
- if (sourceKind == SourceKind.PART) {
- List<Source> librarySources = getLibrariesContaining(source);
- MapIterator<Source, SourceEntry> partIterator = _cache.iterator();
- while (partIterator.moveNext()) {
- SourceEntry sourceEntry = partIterator.value;
- if (sourceEntry.kind == SourceKind.HTML) {
- List<Source> referencedLibraries = (sourceEntry as HtmlEntry)
- .getValue(HtmlEntry.REFERENCED_LIBRARIES);
- if (_containsAny(referencedLibraries, librarySources)) {
- htmlSources.add(partIterator.key);
- }
- }
- }
- } else {
- MapIterator<Source, SourceEntry> iterator = _cache.iterator();
- while (iterator.moveNext()) {
- SourceEntry sourceEntry = iterator.value;
- if (sourceEntry.kind == SourceKind.HTML) {
- List<Source> referencedLibraries = (sourceEntry as HtmlEntry)
- .getValue(HtmlEntry.REFERENCED_LIBRARIES);
- if (_contains(referencedLibraries, source)) {
- htmlSources.add(iterator.key);
- }
- }
- }
- }
- break;
- }
- if (htmlSources.isEmpty) {
- return Source.EMPTY_LIST;
- }
- return htmlSources;
- }
-
- @override
- SourceKind getKindOf(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
- if (sourceEntry == null) {
- return SourceKind.UNKNOWN;
- }
- return sourceEntry.kind;
- }
-
- @override
- List<Source> getLibrariesContaining(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
- if (sourceEntry is DartEntry) {
- return sourceEntry.containingLibraries;
- }
- return Source.EMPTY_LIST;
- }
-
- @override
- List<Source> getLibrariesDependingOn(Source librarySource) {
- List<Source> dependentLibraries = new List<Source>();
- MapIterator<Source, SourceEntry> iterator = _cache.iterator();
- while (iterator.moveNext()) {
- SourceEntry sourceEntry = iterator.value;
- if (sourceEntry.kind == SourceKind.LIBRARY) {
- if (_contains(
- (sourceEntry as DartEntry).getValue(DartEntry.EXPORTED_LIBRARIES),
- librarySource)) {
- dependentLibraries.add(iterator.key);
- }
- if (_contains(
- (sourceEntry as DartEntry).getValue(DartEntry.IMPORTED_LIBRARIES),
- librarySource)) {
- dependentLibraries.add(iterator.key);
- }
- }
- }
- if (dependentLibraries.isEmpty) {
- return Source.EMPTY_LIST;
- }
- return dependentLibraries;
- }
-
- @override
- List<Source> getLibrariesReferencedFromHtml(Source htmlSource) {
- SourceEntry sourceEntry = getReadableSourceEntryOrNull(htmlSource);
- if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry;
- return htmlEntry.getValue(HtmlEntry.REFERENCED_LIBRARIES);
- }
- return Source.EMPTY_LIST;
- }
-
- @override
- LibraryElement getLibraryElement(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
- if (sourceEntry is DartEntry) {
- return sourceEntry.getValue(DartEntry.ELEMENT);
- }
- return null;
- }
-
- @override
- LineInfo getLineInfo(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
- if (sourceEntry != null) {
- return sourceEntry.getValue(SourceEntry.LINE_INFO);
- }
- return null;
- }
-
- @override
- int getModificationStamp(Source source) {
- int stamp = _contentCache.getModificationStamp(source);
- if (stamp != null) {
- return stamp;
- }
- return source.modificationStamp;
- }
-
- @override
- ChangeNoticeImpl getNotice(Source source) {
- ChangeNoticeImpl notice = _pendingNotices[source];
- if (notice == null) {
- notice = new ChangeNoticeImpl(source);
- _pendingNotices[source] = notice;
- }
- return notice;
- }
-
- @override
- Namespace getPublicNamespace(LibraryElement library) {
- // TODO(brianwilkerson) Rename this to not start with 'get'.
- // Note that this is not part of the API of the interface.
- Source source = library.definingCompilationUnit.source;
- DartEntry dartEntry = _getReadableDartEntry(source);
- if (dartEntry == null) {
- return null;
- }
- Namespace namespace = null;
- if (identical(dartEntry.getValue(DartEntry.ELEMENT), library)) {
- namespace = dartEntry.getValue(DartEntry.PUBLIC_NAMESPACE);
- }
- if (namespace == null) {
- NamespaceBuilder builder = new NamespaceBuilder();
- namespace = builder.createPublicNamespaceForLibrary(library);
- if (dartEntry == null) {
- AnalysisEngine.instance.logger.logError(
- "Could not compute the public namespace for ${library.source.fullName}",
- new CaughtException(
- new AnalysisException(
- "A Dart file became a non-Dart file: ${source.fullName}"),
- null));
- return null;
- }
- if (identical(dartEntry.getValue(DartEntry.ELEMENT), library)) {
- dartEntry.setValue(DartEntry.PUBLIC_NAMESPACE, namespace);
- }
- }
- return namespace;
- }
-
- /**
- * Return the cache entry associated with the given [source], or `null` if
- * there is no entry associated with the source.
- */
- SourceEntry getReadableSourceEntryOrNull(Source source) => _cache.get(source);
-
- @override
- CompilationUnit getResolvedCompilationUnit(
- Source unitSource, LibraryElement library) {
- if (library == null) {
- return null;
- }
- return getResolvedCompilationUnit2(unitSource, library.source);
- }
-
- @override
- CompilationUnit getResolvedCompilationUnit2(
- Source unitSource, Source librarySource) {
- SourceEntry sourceEntry = getReadableSourceEntryOrNull(unitSource);
- if (sourceEntry is DartEntry) {
- return sourceEntry.getValueInLibrary(
- DartEntry.RESOLVED_UNIT, librarySource);
- }
- return null;
- }
-
- @override
- @deprecated
- ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
- SourceEntry sourceEntry = getReadableSourceEntryOrNull(htmlSource);
- if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry;
- return htmlEntry.getValue(HtmlEntry.RESOLVED_UNIT);
- }
- return null;
- }
-
- @override
- Object getResult(AnalysisTarget target, ResultDescriptor result) {
- return result.defaultValue;
- }
-
- @override
- List<Source> getSourcesWithFullName(String path) {
- List<Source> sources = <Source>[];
- MapIterator<Source, SourceEntry> iterator = _cache.iterator();
- while (iterator.moveNext()) {
- if (iterator.key.fullName == path) {
- sources.add(iterator.key);
- }
- }
- return sources;
- }
-
- @override
- bool handleContentsChanged(
- Source source, String originalContents, String newContents, bool notify) {
- SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry == null) {
- return false;
- }
- bool changed = newContents != originalContents;
- if (newContents != null) {
- if (changed) {
- _incrementalAnalysisCache =
- IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
- if (!analysisOptions.incremental ||
- !_tryPoorMansIncrementalResolution(source, newContents)) {
- _sourceChanged(source);
- }
- sourceEntry.modificationTime =
- _contentCache.getModificationStamp(source);
- sourceEntry.setValue(SourceEntry.CONTENT, newContents);
- } else {
- sourceEntry.modificationTime =
- _contentCache.getModificationStamp(source);
- }
- } else if (originalContents != null) {
- _incrementalAnalysisCache =
- IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
- // We are removing the overlay for the file, check if the file's
- // contents is the same as it was in the overlay.
- try {
- TimestampedData<String> fileContents = getContents(source);
- newContents = fileContents.data;
- sourceEntry.modificationTime = fileContents.modificationTime;
- if (newContents == originalContents) {
- sourceEntry.setValue(SourceEntry.CONTENT, newContents);
- changed = false;
- }
- } catch (e) {}
- // If not the same content (e.g. the file is being closed without save),
- // then force analysis.
- if (changed) {
- if (!analysisOptions.incremental ||
- !_tryPoorMansIncrementalResolution(source, newContents)) {
- _sourceChanged(source);
- }
- }
- }
- if (notify && changed) {
- _onSourcesChangedController
- .add(new SourcesChangedEvent.changedContent(source, newContents));
- }
- return changed;
- }
-
- @override
- void invalidateLibraryHints(Source librarySource) {
- SourceEntry sourceEntry = _cache.get(librarySource);
- if (sourceEntry is! DartEntry) {
- return;
- }
- DartEntry dartEntry = sourceEntry;
- // Prepare sources to invalidate hints in.
- List<Source> sources = <Source>[librarySource];
- sources.addAll(dartEntry.getValue(DartEntry.INCLUDED_PARTS));
- // Invalidate hints and lints.
- for (Source source in sources) {
- DartEntry dartEntry = _cache.get(source);
- if (dartEntry.getStateInLibrary(DartEntry.HINTS, librarySource) ==
- CacheState.VALID) {
- dartEntry.setStateInLibrary(
- DartEntry.HINTS, librarySource, CacheState.INVALID);
- }
- if (dartEntry.getStateInLibrary(DartEntry.LINTS, librarySource) ==
- CacheState.VALID) {
- dartEntry.setStateInLibrary(
- DartEntry.LINTS, librarySource, CacheState.INVALID);
- }
- }
- }
-
- @override
- bool isClientLibrary(Source librarySource) {
- SourceEntry sourceEntry = _getReadableSourceEntry(librarySource);
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry;
- return dartEntry.getValue(DartEntry.IS_CLIENT) &&
- dartEntry.getValue(DartEntry.IS_LAUNCHABLE);
- }
- return false;
- }
-
- @override
- bool isServerLibrary(Source librarySource) {
- SourceEntry sourceEntry = _getReadableSourceEntry(librarySource);
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry;
- return !dartEntry.getValue(DartEntry.IS_CLIENT) &&
- dartEntry.getValue(DartEntry.IS_LAUNCHABLE);
- }
- return false;
- }
-
- @override
- Stream<ComputedResult> onResultComputed(ResultDescriptor descriptor) {
- throw new NotImplementedException('In not task-based AnalysisContext.');
- }
-
- @override
- CompilationUnit parseCompilationUnit(Source source) =>
- _getDartParseData2(source, DartEntry.PARSED_UNIT, null);
-
- @override
- Document parseHtmlDocument(Source source) {
- return null;
- }
-
- @override
- @deprecated
- ht.HtmlUnit parseHtmlUnit(Source source) =>
- _getHtmlParseData(source, HtmlEntry.PARSED_UNIT, null);
-
- @override
- AnalysisResult performAnalysisTask() {
- if (_TRACE_PERFORM_TASK) {
- print("----------------------------------------");
- }
- return PerformanceStatistics.performAnaysis.makeCurrentWhile(() {
- int getStart = JavaSystem.currentTimeMillis();
- AnalysisTask task = PerformanceStatistics.nextTask
- .makeCurrentWhile(() => nextAnalysisTask);
- int getEnd = JavaSystem.currentTimeMillis();
- if (task == null) {
- _validateLastIncrementalResolutionResult();
- if (_performAnalysisTaskStopwatch != null) {
- AnalysisEngine.instance.instrumentationService.logPerformance(
- AnalysisPerformanceKind.FULL,
- _performAnalysisTaskStopwatch,
- 'context_id=$_id');
- _performAnalysisTaskStopwatch = null;
- }
- return new AnalysisResult(
- _getChangeNotices(true), getEnd - getStart, null, -1);
- }
- if (_performAnalysisTaskStopwatch == null) {
- _performAnalysisTaskStopwatch = new Stopwatch()..start();
- }
- String taskDescription = task.toString();
- _notifyAboutToPerformTask(taskDescription);
- if (_TRACE_PERFORM_TASK) {
- print(taskDescription);
- }
- int performStart = JavaSystem.currentTimeMillis();
- try {
- task.perform(_resultRecorder);
- } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
- AnalysisEngine.instance.logger.logInformation(
- "Could not perform analysis task: $taskDescription",
- new CaughtException(exception, stackTrace));
- } on AnalysisException catch (exception, stackTrace) {
- if (exception.cause is! JavaIOException) {
- AnalysisEngine.instance.logger.logError(
- "Internal error while performing the task: $task",
- new CaughtException(exception, stackTrace));
- }
- }
- int performEnd = JavaSystem.currentTimeMillis();
- List<ChangeNotice> notices = _getChangeNotices(false);
- int noticeCount = notices.length;
- for (int i = 0; i < noticeCount; i++) {
- ChangeNotice notice = notices[i];
- Source source = notice.source;
- // TODO(brianwilkerson) Figure out whether the compilation unit is
- // always resolved, or whether we need to decide whether to invoke the
- // "parsed" or "resolved" method. This might be better done when
- // recording task results in order to reduce the chance of errors.
-// if (notice.getCompilationUnit() != null) {
-// notifyResolvedDart(source, notice.getCompilationUnit());
-// } else if (notice.getHtmlUnit() != null) {
-// notifyResolvedHtml(source, notice.getHtmlUnit());
-// }
- _notifyErrors(source, notice.errors, notice.lineInfo);
- }
- return new AnalysisResult(notices, getEnd - getStart,
- task.runtimeType.toString(), performEnd - performStart);
- });
- }
-
- @override
- void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
- Source htmlSource = _sourceFactory.forUri(DartSdk.DART_HTML);
- elementMap.forEach((Source librarySource, LibraryElement library) {
- //
- // Cache the element in the library's info.
- //
- DartEntry dartEntry = _getReadableDartEntry(librarySource);
- if (dartEntry != null) {
- _recordElementData(dartEntry, library, library.source, htmlSource);
- dartEntry.setState(SourceEntry.CONTENT, CacheState.FLUSHED);
- dartEntry.setValue(SourceEntry.LINE_INFO, new LineInfo(<int>[0]));
- // DartEntry.ELEMENT - set in recordElementData
- dartEntry.setValue(DartEntry.EXPORTED_LIBRARIES, Source.EMPTY_LIST);
- dartEntry.setValue(DartEntry.IMPORTED_LIBRARIES, Source.EMPTY_LIST);
- dartEntry.setValue(DartEntry.INCLUDED_PARTS, Source.EMPTY_LIST);
- // DartEntry.IS_CLIENT - set in recordElementData
- // DartEntry.IS_LAUNCHABLE - set in recordElementData
- dartEntry.setValue(DartEntry.PARSE_ERRORS, AnalysisError.NO_ERRORS);
- dartEntry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
- dartEntry.setState(DartEntry.PUBLIC_NAMESPACE, CacheState.FLUSHED);
- dartEntry.setValue(DartEntry.SCAN_ERRORS, AnalysisError.NO_ERRORS);
- dartEntry.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
- dartEntry.setState(DartEntry.TOKEN_STREAM, CacheState.FLUSHED);
- dartEntry.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource,
- AnalysisError.NO_ERRORS);
- dartEntry.setStateInLibrary(
- DartEntry.RESOLVED_UNIT, librarySource, CacheState.FLUSHED);
- dartEntry.setValueInLibrary(DartEntry.VERIFICATION_ERRORS,
- librarySource, AnalysisError.NO_ERRORS);
- dartEntry.setValueInLibrary(
- DartEntry.HINTS, librarySource, AnalysisError.NO_ERRORS);
- dartEntry.setValueInLibrary(
- DartEntry.LINTS, librarySource, AnalysisError.NO_ERRORS);
- }
- });
- }
-
- /**
- * Record the results produced by performing a [task] and return the cache
- * entry associated with the results.
- */
- DartEntry recordResolveDartLibraryCycleTaskResults(
- ResolveDartLibraryCycleTask task) {
- LibraryResolver2 resolver = task.libraryResolver;
- CaughtException thrownException = task.exception;
- Source unitSource = task.unitSource;
- DartEntry unitEntry = _getReadableDartEntry(unitSource);
- if (resolver != null) {
- //
- // The resolver should only be null if an exception was thrown before (or
- // while) it was being created.
- //
- List<ResolvableLibrary> resolvedLibraries = resolver.resolvedLibraries;
- if (resolvedLibraries == null) {
- //
- // The resolved libraries should only be null if an exception was thrown
- // during resolution.
- //
- if (thrownException == null) {
- var message = "In recordResolveDartLibraryCycleTaskResults, "
- "resolvedLibraries was null and there was no thrown exception";
- unitEntry.recordResolutionError(
- new CaughtException(new AnalysisException(message), null));
- } else {
- unitEntry.recordResolutionError(thrownException);
- }
- _removeFromCache(unitSource);
- if (thrownException != null) {
- throw new AnalysisException('<rethrow>', thrownException);
- }
- return unitEntry;
- }
- Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
- RecordingErrorListener errorListener = resolver.errorListener;
- for (ResolvableLibrary library in resolvedLibraries) {
- Source librarySource = library.librarySource;
- for (Source source in library.compilationUnitSources) {
- CompilationUnit unit = library.getAST(source);
- List<AnalysisError> errors = errorListener.getErrorsForSource(source);
- LineInfo lineInfo = getLineInfo(source);
- DartEntry dartEntry = _cache.get(source);
- if (thrownException == null) {
- dartEntry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
- dartEntry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, librarySource, unit);
- dartEntry.setValueInLibrary(
- DartEntry.RESOLUTION_ERRORS, librarySource, errors);
- if (source == librarySource) {
- _recordElementData(
- dartEntry, library.libraryElement, librarySource, htmlSource);
- }
- _cache.storedAst(source);
- } else {
- dartEntry.recordResolutionErrorInLibrary(
- librarySource, thrownException);
- }
- if (source != librarySource) {
- _workManager.add(source, SourcePriority.PRIORITY_PART);
- }
- ChangeNoticeImpl notice = getNotice(source);
- notice.resolvedDartUnit = unit;
- notice.setErrors(dartEntry.allErrors, lineInfo);
- }
- }
- }
- if (thrownException != null) {
- throw new AnalysisException('<rethrow>', thrownException);
- }
- return unitEntry;
- }
-
- /**
- * Record the results produced by performing a [task] and return the cache
- * entry associated with the results.
- */
- DartEntry recordResolveDartLibraryTaskResults(ResolveDartLibraryTask task) {
- LibraryResolver resolver = task.libraryResolver;
- CaughtException thrownException = task.exception;
- Source unitSource = task.unitSource;
- DartEntry unitEntry = _getReadableDartEntry(unitSource);
- if (resolver != null) {
- //
- // The resolver should only be null if an exception was thrown before (or
- // while) it was being created.
- //
- Set<Library> resolvedLibraries = resolver.resolvedLibraries;
- if (resolvedLibraries == null) {
- //
- // The resolved libraries should only be null if an exception was thrown
- // during resolution.
- //
- if (thrownException == null) {
- String message = "In recordResolveDartLibraryTaskResults, "
- "resolvedLibraries was null and there was no thrown exception";
- unitEntry.recordResolutionError(
- new CaughtException(new AnalysisException(message), null));
- } else {
- unitEntry.recordResolutionError(thrownException);
- }
- _removeFromCache(unitSource);
- if (thrownException != null) {
- throw new AnalysisException('<rethrow>', thrownException);
- }
- return unitEntry;
- }
- Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
- RecordingErrorListener errorListener = resolver.errorListener;
- for (Library library in resolvedLibraries) {
- Source librarySource = library.librarySource;
- for (Source source in library.compilationUnitSources) {
- CompilationUnit unit = library.getAST(source);
- List<AnalysisError> errors = errorListener.getErrorsForSource(source);
- LineInfo lineInfo = getLineInfo(source);
- DartEntry dartEntry = _cache.get(source);
- if (thrownException == null) {
- dartEntry.setValue(SourceEntry.LINE_INFO, lineInfo);
- dartEntry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
- dartEntry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, librarySource, unit);
- dartEntry.setValueInLibrary(
- DartEntry.RESOLUTION_ERRORS, librarySource, errors);
- if (source == librarySource) {
- _recordElementData(
- dartEntry, library.libraryElement, librarySource, htmlSource);
- }
- _cache.storedAst(source);
- } else {
- dartEntry.recordResolutionErrorInLibrary(
- librarySource, thrownException);
- _removeFromCache(source);
- }
- if (source != librarySource) {
- _workManager.add(source, SourcePriority.PRIORITY_PART);
- }
- ChangeNoticeImpl notice = getNotice(source);
- notice.resolvedDartUnit = unit;
- notice.setErrors(dartEntry.allErrors, lineInfo);
- }
- }
- }
- if (thrownException != null) {
- throw new AnalysisException('<rethrow>', thrownException);
- }
- return unitEntry;
- }
-
- @override
- void removeListener(AnalysisListener listener) {
- _listeners.remove(listener);
- }
-
- @override
- CompilationUnit resolveCompilationUnit(
- Source unitSource, LibraryElement library) {
- if (library == null) {
- return null;
- }
- return resolveCompilationUnit2(unitSource, library.source);
- }
-
- @override
- CompilationUnit resolveCompilationUnit2(
- Source unitSource, Source librarySource) =>
- _getDartResolutionData2(
- unitSource, librarySource, DartEntry.RESOLVED_UNIT, null);
-
- @override
- @deprecated
- ht.HtmlUnit resolveHtmlUnit(Source htmlSource) {
- computeHtmlElement(htmlSource);
- return parseHtmlUnit(htmlSource);
- }
-
- @override
- void setChangedContents(Source source, String contents, int offset,
- int oldLength, int newLength) {
- if (_contentRangeChanged(source, contents, offset, oldLength, newLength)) {
- _onSourcesChangedController.add(new SourcesChangedEvent.changedRange(
- source, contents, offset, oldLength, newLength));
- }
- }
-
- @override
- void setConfigurationData(ResultDescriptor key, Object data) {
- _configurationData[key] = data;
- }
-
- @override
- void setContents(Source source, String contents) {
- _contentsChanged(source, contents, true);
- }
-
- @override
- bool shouldErrorsBeAnalyzed(Source source, Object entry) {
- DartEntry dartEntry = entry;
- if (source.isInSystemLibrary) {
- return _generateSdkErrors;
- } else if (!dartEntry.explicitlyAdded) {
- return _generateImplicitErrors;
- } else {
- return true;
- }
- }
-
- @override
- void test_flushAstStructures(Source source) {
- DartEntry dartEntry = getReadableSourceEntryOrNull(source);
- dartEntry.flushAstStructures();
- }
-
- @override
- bool validateCacheConsistency() {
- int consistencyCheckStart = JavaSystem.nanoTime();
- List<Source> changedSources = new List<Source>();
- List<Source> missingSources = new List<Source>();
- MapIterator<Source, SourceEntry> iterator = _cache.iterator();
- while (iterator.moveNext()) {
- Source source = iterator.key;
- SourceEntry sourceEntry = iterator.value;
- int sourceTime = getModificationStamp(source);
- if (sourceTime != sourceEntry.modificationTime) {
- changedSources.add(source);
- }
- if (sourceEntry.exception != null) {
- if (!exists(source)) {
- missingSources.add(source);
- }
- }
- }
- int count = changedSources.length;
- for (int i = 0; i < count; i++) {
- _sourceChanged(changedSources[i]);
- }
- int removalCount = 0;
- for (Source source in missingSources) {
- if (getLibrariesContaining(source).isEmpty &&
- getLibrariesDependingOn(source).isEmpty) {
- _removeFromCache(source);
- removalCount++;
- }
- }
- int consistencyCheckEnd = JavaSystem.nanoTime();
- if (changedSources.length > 0 || missingSources.length > 0) {
- StringBuffer buffer = new StringBuffer();
- buffer.write("Consistency check took ");
- buffer.write((consistencyCheckEnd - consistencyCheckStart) / 1000000.0);
- buffer.writeln(" ms and found");
- buffer.write(" ");
- buffer.write(changedSources.length);
- buffer.writeln(" inconsistent entries");
- buffer.write(" ");
- buffer.write(missingSources.length);
- buffer.write(" missing sources (");
- buffer.write(removalCount);
- buffer.writeln(" removed");
- for (Source source in missingSources) {
- buffer.write(" ");
- buffer.writeln(source.fullName);
- }
- _logInformation(buffer.toString());
- }
- return changedSources.length > 0;
- }
-
- @deprecated
- @override
- void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
- DataDescriptor rowDesc, CacheState state)) {
- bool hintsEnabled = _options.hint;
- bool lintsEnabled = _options.lint;
- MapIterator<Source, SourceEntry> iterator = _cache.iterator();
- while (iterator.moveNext()) {
- Source source = iterator.key;
- SourceEntry sourceEntry = iterator.value;
- for (DataDescriptor descriptor in sourceEntry.descriptors) {
- if (descriptor == DartEntry.SOURCE_KIND) {
- // The source kind is always valid, so the state isn't interesting.
- continue;
- } else if (descriptor == DartEntry.CONTAINING_LIBRARIES) {
- // The list of containing libraries is always valid, so the state
- // isn't interesting.
- continue;
- } else if (descriptor == DartEntry.PUBLIC_NAMESPACE) {
- // The public namespace isn't computed by performAnalysisTask()
- // and therefore isn't interesting.
- continue;
- } else if (descriptor == HtmlEntry.HINTS) {
- // We are not currently recording any hints related to HTML.
- continue;
- }
- callback(
- source, sourceEntry, descriptor, sourceEntry.getState(descriptor));
- }
- if (sourceEntry is DartEntry) {
- // get library-specific values
- List<Source> librarySources = getLibrariesContaining(source);
- for (Source librarySource in librarySources) {
- for (DataDescriptor descriptor in sourceEntry.libraryDescriptors) {
- if (descriptor == DartEntry.BUILT_ELEMENT ||
- descriptor == DartEntry.BUILT_UNIT) {
- // These values are not currently being computed, so their state
- // is not interesting.
- continue;
- } else if (!sourceEntry.explicitlyAdded &&
- !_generateImplicitErrors &&
- (descriptor == DartEntry.VERIFICATION_ERRORS ||
- descriptor == DartEntry.HINTS ||
- descriptor == DartEntry.LINTS)) {
- continue;
- } else if (source.isInSystemLibrary &&
- !_generateSdkErrors &&
- (descriptor == DartEntry.VERIFICATION_ERRORS ||
- descriptor == DartEntry.HINTS ||
- descriptor == DartEntry.LINTS)) {
- continue;
- } else if (!hintsEnabled && descriptor == DartEntry.HINTS) {
- continue;
- } else if (!lintsEnabled && descriptor == DartEntry.LINTS) {
- continue;
- }
- callback(librarySource, sourceEntry, descriptor,
- sourceEntry.getStateInLibrary(descriptor, librarySource));
- }
- }
- }
- }
- }
-
- @override
- void visitContentCache(ContentCacheVisitor visitor) {
- _contentCache.accept(visitor);
- }
-
- /**
- * Record that we have accessed the AST structure associated with the given
- * [source]. At the moment, there is no differentiation between the parsed and
- * resolved forms of the AST.
- */
- void _accessedAst(Source source) {
- _cache.accessedAst(source);
- }
-
- /**
- * Add all of the sources contained in the given source [container] to the
- * given list of [sources].
- */
- void _addSourcesInContainer(List<Source> sources, SourceContainer container) {
- MapIterator<Source, SourceEntry> iterator = _cache.iterator();
- while (iterator.moveNext()) {
- Source source = iterator.key;
- if (container.contains(source)) {
- sources.add(source);
- }
- }
- }
-
- /**
- * Given the [unitSource] of a Dart file and the [librarySource] of the
- * library that contains it, return a cache entry in which the state of the
- * data represented by the given [descriptor] is either [CacheState.VALID] or
- * [CacheState.ERROR]. This method assumes that the data can be produced by
- * generating hints for the library if the data is not already cached. The
- * [dartEntry] is the cache entry associated with the Dart file.
- *
- * Throws an [AnalysisException] if data could not be returned because the
- * source could not be parsed.
- */
- DartEntry _cacheDartHintData(Source unitSource, Source librarySource,
- DartEntry dartEntry, DataDescriptor descriptor) {
- //
- // Check to see whether we already have the information being requested.
- //
- CacheState state = dartEntry.getStateInLibrary(descriptor, librarySource);
- while (state != CacheState.ERROR && state != CacheState.VALID) {
- //
- // If not, compute the information.
- // Unless the modification date of the source continues to change,
- // this loop will eventually terminate.
- //
- DartEntry libraryEntry = _getReadableDartEntry(librarySource);
- libraryEntry = _cacheDartResolutionData(
- librarySource, librarySource, libraryEntry, DartEntry.ELEMENT);
- LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
- CompilationUnitElement definingUnit =
- libraryElement.definingCompilationUnit;
- List<CompilationUnitElement> parts = libraryElement.parts;
- List<TimestampedData<CompilationUnit>> units =
- new List<TimestampedData<CompilationUnit>>(parts.length + 1);
- units[0] = _getResolvedUnit(definingUnit, librarySource);
- if (units[0] == null) {
- Source source = definingUnit.source;
- units[0] = new TimestampedData<CompilationUnit>(
- getModificationStamp(source),
- resolveCompilationUnit(source, libraryElement));
- }
- for (int i = 0; i < parts.length; i++) {
- units[i + 1] = _getResolvedUnit(parts[i], librarySource);
- if (units[i + 1] == null) {
- Source source = parts[i].source;
- units[i + 1] = new TimestampedData<CompilationUnit>(
- getModificationStamp(source),
- resolveCompilationUnit(source, libraryElement));
- }
- }
- dartEntry = new GenerateDartHintsTask(
- this, units, getLibraryElement(librarySource))
- .perform(_resultRecorder) as DartEntry;
- state = dartEntry.getStateInLibrary(descriptor, librarySource);
- }
- return dartEntry;
- }
-
- /**
- * Given a source for a Dart file and the library that contains it, return a
- * cache entry in which the state of the data represented by the given
- * descriptor is either [CacheState.VALID] or [CacheState.ERROR]. This method
- * assumes that the data can be produced by generating lints for the library
- * if the data is not already cached.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- DartEntry _cacheDartLintData(Source unitSource, Source librarySource,
- DartEntry dartEntry, DataDescriptor descriptor) {
- //
- // Check to see whether we already have the information being requested.
- //
- CacheState state = dartEntry.getStateInLibrary(descriptor, librarySource);
- while (state != CacheState.ERROR && state != CacheState.VALID) {
- //
- // If not, compute the information.
- // Unless the modification date of the source continues to change,
- // this loop will eventually terminate.
- //
- DartEntry libraryEntry = _getReadableDartEntry(librarySource);
- libraryEntry = _cacheDartResolutionData(
- librarySource, librarySource, libraryEntry, DartEntry.ELEMENT);
- LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
- CompilationUnitElement definingUnit =
- libraryElement.definingCompilationUnit;
- List<CompilationUnitElement> parts = libraryElement.parts;
- List<TimestampedData<CompilationUnit>> units =
- new List<TimestampedData<CompilationUnit>>(parts.length + 1);
- units[0] = _getResolvedUnit(definingUnit, librarySource);
- if (units[0] == null) {
- Source source = definingUnit.source;
- units[0] = new TimestampedData<CompilationUnit>(
- getModificationStamp(source),
- resolveCompilationUnit(source, libraryElement));
- }
- for (int i = 0; i < parts.length; i++) {
- units[i + 1] = _getResolvedUnit(parts[i], librarySource);
- if (units[i + 1] == null) {
- Source source = parts[i].source;
- units[i + 1] = new TimestampedData<CompilationUnit>(
- getModificationStamp(source),
- resolveCompilationUnit(source, libraryElement));
- }
- }
- //TODO(pquitslund): revisit if we need all units or whether one will do
- dartEntry = new GenerateDartLintsTask(
- this, units, getLibraryElement(librarySource))
- .perform(_resultRecorder) as DartEntry;
- state = dartEntry.getStateInLibrary(descriptor, librarySource);
- }
- return dartEntry;
- }
-
- /**
- * Given a source for a Dart file, return a cache entry in which the state of
- * the data represented by the given descriptor is either [CacheState.VALID]
- * or [CacheState.ERROR]. This method assumes that the data can be produced by
- * parsing the source if it is not already cached.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- DartEntry _cacheDartParseData(
- Source source, DartEntry dartEntry, DataDescriptor descriptor) {
- if (identical(descriptor, DartEntry.PARSED_UNIT)) {
- if (dartEntry.hasResolvableCompilationUnit) {
- return dartEntry;
- }
- }
- //
- // Check to see whether we already have the information being requested.
- //
- CacheState state = dartEntry.getState(descriptor);
- while (state != CacheState.ERROR && state != CacheState.VALID) {
- //
- // If not, compute the information. Unless the modification date of the
- // source continues to change, this loop will eventually terminate.
- //
- dartEntry = _cacheDartScanData(source, dartEntry, DartEntry.TOKEN_STREAM);
- dartEntry = new ParseDartTask(
- this,
- source,
- dartEntry.getValue(DartEntry.TOKEN_STREAM),
- dartEntry.getValue(SourceEntry.LINE_INFO))
- .perform(_resultRecorder) as DartEntry;
- state = dartEntry.getState(descriptor);
- }
- return dartEntry;
- }
-
- /**
- * Given a source for a Dart file and the library that contains it, return a
- * cache entry in which the state of the data represented by the given
- * descriptor is either [CacheState.VALID] or [CacheState.ERROR]. This method
- * assumes that the data can be produced by resolving the source in the
- * context of the library if it is not already cached.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- DartEntry _cacheDartResolutionData(Source unitSource, Source librarySource,
- DartEntry dartEntry, DataDescriptor descriptor) {
- //
- // Check to see whether we already have the information being requested.
- //
- CacheState state = (identical(descriptor, DartEntry.ELEMENT))
- ? dartEntry.getState(descriptor)
- : dartEntry.getStateInLibrary(descriptor, librarySource);
- while (state != CacheState.ERROR && state != CacheState.VALID) {
- //
- // If not, compute the information. Unless the modification date of the
- // source continues to change, this loop will eventually terminate.
- //
- // TODO(brianwilkerson) As an optimization, if we already have the
- // element model for the library we can use ResolveDartUnitTask to produce
- // the resolved AST structure much faster.
- dartEntry = new ResolveDartLibraryTask(this, unitSource, librarySource)
- .perform(_resultRecorder) as DartEntry;
- state = (identical(descriptor, DartEntry.ELEMENT))
- ? dartEntry.getState(descriptor)
- : dartEntry.getStateInLibrary(descriptor, librarySource);
- }
- return dartEntry;
- }
-
- /**
- * Given a source for a Dart file, return a cache entry in which the state of
- * the data represented by the given descriptor is either [CacheState.VALID]
- * or [CacheState.ERROR]. This method assumes that the data can be produced by
- * scanning the source if it is not already cached.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- DartEntry _cacheDartScanData(
- Source source, DartEntry dartEntry, DataDescriptor descriptor) {
- //
- // Check to see whether we already have the information being requested.
- //
- CacheState state = dartEntry.getState(descriptor);
- while (state != CacheState.ERROR && state != CacheState.VALID) {
- //
- // If not, compute the information. Unless the modification date of the
- // source continues to change, this loop will eventually terminate.
- //
- try {
- if (dartEntry.getState(SourceEntry.CONTENT) != CacheState.VALID) {
- dartEntry = new GetContentTask(this, source).perform(_resultRecorder)
- as DartEntry;
- }
- dartEntry = new ScanDartTask(
- this, source, dartEntry.getValue(SourceEntry.CONTENT))
- .perform(_resultRecorder) as DartEntry;
- } on AnalysisException catch (exception) {
- throw exception;
- } catch (exception, stackTrace) {
- throw new AnalysisException(
- "Exception", new CaughtException(exception, stackTrace));
- }
- state = dartEntry.getState(descriptor);
- }
- return dartEntry;
- }
-
- /**
- * Given a source for a Dart file and the library that contains it, return a
- * cache entry in which the state of the data represented by the given
- * descriptor is either [CacheState.VALID] or [CacheState.ERROR]. This method
- * assumes that the data can be produced by verifying the source in the given
- * library if the data is not already cached.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- DartEntry _cacheDartVerificationData(Source unitSource, Source librarySource,
- DartEntry dartEntry, DataDescriptor descriptor) {
- //
- // Check to see whether we already have the information being requested.
- //
- CacheState state = dartEntry.getStateInLibrary(descriptor, librarySource);
- while (state != CacheState.ERROR && state != CacheState.VALID) {
- //
- // If not, compute the information. Unless the modification date of the
- // source continues to change, this loop will eventually terminate.
- //
- LibraryElement library = computeLibraryElement(librarySource);
- CompilationUnit unit = resolveCompilationUnit(unitSource, library);
- if (unit == null) {
- throw new AnalysisException(
- "Could not resolve compilation unit ${unitSource.fullName} in ${librarySource.fullName}");
- }
- dartEntry = new GenerateDartErrorsTask(this, unitSource, unit, library)
- .perform(_resultRecorder) as DartEntry;
- state = dartEntry.getStateInLibrary(descriptor, librarySource);
- }
- return dartEntry;
- }
-
- /**
- * Given a source for an HTML file, return a cache entry in which all of the
- * data represented by the state of the given descriptors is either
- * [CacheState.VALID] or [CacheState.ERROR]. This method assumes that the data
- * can be produced by parsing the source if it is not already cached.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- HtmlEntry _cacheHtmlParseData(
- Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
- if (identical(descriptor, HtmlEntry.PARSED_UNIT)) {
- ht.HtmlUnit unit = htmlEntry.anyParsedUnit;
- if (unit != null) {
- return htmlEntry;
- }
- }
- //
- // Check to see whether we already have the information being requested.
- //
- CacheState state = htmlEntry.getState(descriptor);
- while (state != CacheState.ERROR && state != CacheState.VALID) {
- //
- // If not, compute the information. Unless the modification date of the
- // source continues to change, this loop will eventually terminate.
- //
- try {
- if (htmlEntry.getState(SourceEntry.CONTENT) != CacheState.VALID) {
- htmlEntry = new GetContentTask(this, source).perform(_resultRecorder)
- as HtmlEntry;
- }
- htmlEntry = new ParseHtmlTask(
- this, source, htmlEntry.getValue(SourceEntry.CONTENT))
- .perform(_resultRecorder) as HtmlEntry;
- } on AnalysisException catch (exception) {
- throw exception;
- } catch (exception, stackTrace) {
- throw new AnalysisException(
- "Exception", new CaughtException(exception, stackTrace));
- }
- state = htmlEntry.getState(descriptor);
- }
- return htmlEntry;
- }
-
- /**
- * Given a source for an HTML file, return a cache entry in which the state of
- * the data represented by the given descriptor is either [CacheState.VALID]
- * or [CacheState.ERROR]. This method assumes that the data can be produced by
- * resolving the source if it is not already cached.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- HtmlEntry _cacheHtmlResolutionData(
- Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
- //
- // Check to see whether we already have the information being requested.
- //
- CacheState state = htmlEntry.getState(descriptor);
- while (state != CacheState.ERROR && state != CacheState.VALID) {
- //
- // If not, compute the information. Unless the modification date of the
- // source continues to change, this loop will eventually terminate.
- //
- htmlEntry = _cacheHtmlParseData(source, htmlEntry, HtmlEntry.PARSED_UNIT);
- htmlEntry = new ResolveHtmlTask(this, source, htmlEntry.modificationTime,
- htmlEntry.getValue(HtmlEntry.PARSED_UNIT))
- .perform(_resultRecorder) as HtmlEntry;
- state = htmlEntry.getState(descriptor);
- }
- return htmlEntry;
- }
-
- /**
- * Remove the given [pendingFuture] from [_pendingFutureSources], since the
- * client has indicated its computation is not needed anymore.
- */
- void _cancelFuture(PendingFuture pendingFuture) {
- List<PendingFuture> pendingFutures =
- _pendingFutureSources[pendingFuture.source];
- if (pendingFutures != null) {
- pendingFutures.remove(pendingFuture);
- if (pendingFutures.isEmpty) {
- _pendingFutureSources.remove(pendingFuture.source);
- }
- }
- }
-
- /**
- * Compute the transitive closure of all libraries that depend on the given
- * [library] by adding such libraries to the given collection of
- * [librariesToInvalidate].
- */
- void _computeAllLibrariesDependingOn(
- Source library, HashSet<Source> librariesToInvalidate) {
- if (librariesToInvalidate.add(library)) {
- for (Source dependentLibrary in getLibrariesDependingOn(library)) {
- _computeAllLibrariesDependingOn(
- dependentLibrary, librariesToInvalidate);
- }
- }
- }
-
- /**
- * Return the priority that should be used when the source associated with
- * the given [dartEntry] is added to the work manager.
- */
- SourcePriority _computePriority(DartEntry dartEntry) {
- SourceKind kind = dartEntry.kind;
- if (kind == SourceKind.LIBRARY) {
- return SourcePriority.LIBRARY;
- } else if (kind == SourceKind.PART) {
- return SourcePriority.NORMAL_PART;
- }
- return SourcePriority.UNKNOWN;
- }
-
- /**
- * Given the encoded form of a source ([encoding]), use the source factory to
- * reconstitute the original source.
- */
- Source _computeSourceFromEncoding(String encoding) =>
- _sourceFactory.fromEncoding(encoding);
-
- /**
- * Return `true` if the given list of [sources] contains the given
- * [targetSource].
- */
- bool _contains(List<Source> sources, Source targetSource) {
- for (Source source in sources) {
- if (source == targetSource) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Return `true` if the given list of [sources] contains any of the given
- * [targetSources].
- */
- bool _containsAny(List<Source> sources, List<Source> targetSources) {
- for (Source targetSource in targetSources) {
- if (_contains(sources, targetSource)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Set the contents of the given [source] to the given [contents] and mark the
- * source as having changed. The additional [offset], [oldLength] and
- * [newLength] information is used by the context to determine what reanalysis
- * is necessary. The method [setChangedContents] triggers a source changed
- * event where as this method does not.
- */
- bool _contentRangeChanged(Source source, String contents, int offset,
- int oldLength, int newLength) {
- bool changed = false;
- String originalContents = _contentCache.setContents(source, contents);
- if (contents != null) {
- if (contents != originalContents) {
- if (_options.incremental) {
- _incrementalAnalysisCache = IncrementalAnalysisCache.update(
- _incrementalAnalysisCache,
- source,
- originalContents,
- contents,
- offset,
- oldLength,
- newLength,
- _getReadableSourceEntry(source));
- }
- _sourceChanged(source);
- changed = true;
- SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry != null) {
- sourceEntry.modificationTime =
- _contentCache.getModificationStamp(source);
- sourceEntry.setValue(SourceEntry.CONTENT, contents);
- }
- }
- } else if (originalContents != null) {
- _incrementalAnalysisCache =
- IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
- _sourceChanged(source);
- changed = true;
- }
- return changed;
- }
-
- /**
- * Set the contents of the given [source] to the given [contents] and mark the
- * source as having changed. This has the effect of overriding the default
- * contents of the source. If the contents are `null` the override is removed
- * so that the default contents will be returned. If [notify] is true, a
- * source changed event is triggered.
- */
- void _contentsChanged(Source source, String contents, bool notify) {
- String originalContents = _contentCache.setContents(source, contents);
- handleContentsChanged(source, originalContents, contents, notify);
- }
-
- /**
- * Create a [GenerateDartErrorsTask] for the given [unitSource], marking the
- * verification errors as being in-process. The compilation unit and the
- * library can be the same if the compilation unit is the defining compilation
- * unit of the library.
- */
- AnalysisContextImpl_TaskData _createGenerateDartErrorsTask(Source unitSource,
- DartEntry unitEntry, Source librarySource, DartEntry libraryEntry) {
- if (unitEntry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource) !=
- CacheState.VALID ||
- libraryEntry.getState(DartEntry.ELEMENT) != CacheState.VALID) {
- return _createResolveDartLibraryTask(librarySource, libraryEntry);
- }
- CompilationUnit unit =
- unitEntry.getValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource);
- if (unit == null) {
- CaughtException exception = new CaughtException(
- new AnalysisException(
- "Entry has VALID state for RESOLVED_UNIT but null value for ${unitSource.fullName} in ${librarySource.fullName}"),
- null);
- AnalysisEngine.instance.logger
- .logInformation(exception.toString(), exception);
- unitEntry.recordResolutionError(exception);
- return new AnalysisContextImpl_TaskData(null, false);
- }
- LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
- return new AnalysisContextImpl_TaskData(
- new GenerateDartErrorsTask(this, unitSource, unit, libraryElement),
- false);
- }
-
- /**
- * Create a [GenerateDartHintsTask] for the given [source], marking the hints
- * as being in-process.
- */
- AnalysisContextImpl_TaskData _createGenerateDartHintsTask(Source source,
- DartEntry dartEntry, Source librarySource, DartEntry libraryEntry) {
- if (libraryEntry.getState(DartEntry.ELEMENT) != CacheState.VALID) {
- return _createResolveDartLibraryTask(librarySource, libraryEntry);
- }
- LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
- CompilationUnitElement definingUnit =
- libraryElement.definingCompilationUnit;
- List<CompilationUnitElement> parts = libraryElement.parts;
- List<TimestampedData<CompilationUnit>> units =
- new List<TimestampedData<CompilationUnit>>(parts.length + 1);
- units[0] = _getResolvedUnit(definingUnit, librarySource);
- if (units[0] == null) {
- // TODO(brianwilkerson) We should return a ResolveDartUnitTask
- // (unless there are multiple ASTs that need to be resolved).
- return _createResolveDartLibraryTask(librarySource, libraryEntry);
- }
- for (int i = 0; i < parts.length; i++) {
- units[i + 1] = _getResolvedUnit(parts[i], librarySource);
- if (units[i + 1] == null) {
- // TODO(brianwilkerson) We should return a ResolveDartUnitTask
- // (unless there are multiple ASTs that need to be resolved).
- return _createResolveDartLibraryTask(librarySource, libraryEntry);
- }
- }
- return new AnalysisContextImpl_TaskData(
- new GenerateDartHintsTask(this, units, libraryElement), false);
- }
-
- /**
- * Create a [GenerateDartLintsTask] for the given [source], marking the lints
- * as being in-process.
- */
- AnalysisContextImpl_TaskData _createGenerateDartLintsTask(Source source,
- DartEntry dartEntry, Source librarySource, DartEntry libraryEntry) {
- if (libraryEntry.getState(DartEntry.ELEMENT) != CacheState.VALID) {
- return _createResolveDartLibraryTask(librarySource, libraryEntry);
- }
- LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
- CompilationUnitElement definingUnit =
- libraryElement.definingCompilationUnit;
- List<CompilationUnitElement> parts = libraryElement.parts;
- List<TimestampedData<CompilationUnit>> units =
- new List<TimestampedData<CompilationUnit>>(parts.length + 1);
- units[0] = _getResolvedUnit(definingUnit, librarySource);
- if (units[0] == null) {
- // TODO(brianwilkerson) We should return a ResolveDartUnitTask
- // (unless there are multiple ASTs that need to be resolved).
- return _createResolveDartLibraryTask(librarySource, libraryEntry);
- }
- for (int i = 0; i < parts.length; i++) {
- units[i + 1] = _getResolvedUnit(parts[i], librarySource);
- if (units[i + 1] == null) {
- // TODO(brianwilkerson) We should return a ResolveDartUnitTask
- // (unless there are multiple ASTs that need to be resolved).
- return _createResolveDartLibraryTask(librarySource, libraryEntry);
- }
- }
- //TODO(pquitslund): revisit if we need all units or whether one will do
- return new AnalysisContextImpl_TaskData(
- new GenerateDartLintsTask(this, units, libraryElement), false);
- }
-
- /**
- * Create a [GetContentTask] for the given [source], marking the content as
- * being in-process.
- */
- AnalysisContextImpl_TaskData _createGetContentTask(
- Source source, SourceEntry sourceEntry) {
- return new AnalysisContextImpl_TaskData(
- new GetContentTask(this, source), false);
- }
-
- /**
- * Create a [ParseDartTask] for the given [source].
- */
- AnalysisContextImpl_TaskData _createParseDartTask(
- Source source, DartEntry dartEntry) {
- if (dartEntry.getState(DartEntry.TOKEN_STREAM) != CacheState.VALID ||
- dartEntry.getState(SourceEntry.LINE_INFO) != CacheState.VALID) {
- return _createScanDartTask(source, dartEntry);
- }
- Token tokenStream = dartEntry.getValue(DartEntry.TOKEN_STREAM);
- dartEntry.setState(DartEntry.TOKEN_STREAM, CacheState.FLUSHED);
- return new AnalysisContextImpl_TaskData(
- new ParseDartTask(this, source, tokenStream,
- dartEntry.getValue(SourceEntry.LINE_INFO)),
- false);
- }
-
- /**
- * Create a [ParseHtmlTask] for the given [source].
- */
- AnalysisContextImpl_TaskData _createParseHtmlTask(
- Source source, HtmlEntry htmlEntry) {
- if (htmlEntry.getState(SourceEntry.CONTENT) != CacheState.VALID) {
- return _createGetContentTask(source, htmlEntry);
- }
- String content = htmlEntry.getValue(SourceEntry.CONTENT);
- htmlEntry.setState(SourceEntry.CONTENT, CacheState.FLUSHED);
- return new AnalysisContextImpl_TaskData(
- new ParseHtmlTask(this, source, content), false);
- }
-
- /**
- * Create a [ResolveDartLibraryTask] for the given [source], marking ? as
- * being in-process.
- */
- AnalysisContextImpl_TaskData _createResolveDartLibraryTask(
- Source source, DartEntry dartEntry) {
- try {
- AnalysisContextImpl_CycleBuilder builder =
- new AnalysisContextImpl_CycleBuilder(this);
- PerformanceStatistics.cycles.makeCurrentWhile(() {
- builder.computeCycleContaining(source);
- });
- AnalysisContextImpl_TaskData taskData = builder.taskData;
- if (taskData != null) {
- return taskData;
- }
- return new AnalysisContextImpl_TaskData(
- new ResolveDartLibraryCycleTask(
- this, source, source, builder.librariesInCycle),
- false);
- } on AnalysisException catch (exception, stackTrace) {
- dartEntry
- .recordResolutionError(new CaughtException(exception, stackTrace));
- AnalysisEngine.instance.logger.logError(
- "Internal error trying to create a ResolveDartLibraryTask",
- new CaughtException(exception, stackTrace));
- }
- return new AnalysisContextImpl_TaskData(null, false);
- }
-
- /**
- * Create a [ResolveHtmlTask] for the given [source], marking the resolved
- * unit as being in-process.
- */
- AnalysisContextImpl_TaskData _createResolveHtmlTask(
- Source source, HtmlEntry htmlEntry) {
- if (htmlEntry.getState(HtmlEntry.PARSED_UNIT) != CacheState.VALID) {
- return _createParseHtmlTask(source, htmlEntry);
- }
- return new AnalysisContextImpl_TaskData(
- new ResolveHtmlTask(this, source, htmlEntry.modificationTime,
- htmlEntry.getValue(HtmlEntry.PARSED_UNIT)),
- false);
- }
-
- /**
- * Create a [ScanDartTask] for the given [source], marking the scan errors as
- * being in-process.
- */
- AnalysisContextImpl_TaskData _createScanDartTask(
- Source source, DartEntry dartEntry) {
- if (dartEntry.getState(SourceEntry.CONTENT) != CacheState.VALID) {
- return _createGetContentTask(source, dartEntry);
- }
- String content = dartEntry.getValue(SourceEntry.CONTENT);
- dartEntry.setState(SourceEntry.CONTENT, CacheState.FLUSHED);
- return new AnalysisContextImpl_TaskData(
- new ScanDartTask(this, source, content), false);
- }
-
- /**
- * Create a source entry for the given [source]. Return the source entry that
- * was created, or `null` if the source should not be tracked by this context.
- */
- SourceEntry _createSourceEntry(Source source, bool explicitlyAdded) {
- String name = source.shortName;
- if (AnalysisEngine.isHtmlFileName(name)) {
- HtmlEntry htmlEntry = new HtmlEntry();
- htmlEntry.modificationTime = getModificationStamp(source);
- htmlEntry.explicitlyAdded = explicitlyAdded;
- _cache.put(source, htmlEntry);
- if (!explicitlyAdded) {
- _implicitAnalysisEventsController
- .add(new ImplicitAnalysisEvent(source, true));
- }
- return htmlEntry;
- } else {
- DartEntry dartEntry = new DartEntry();
- dartEntry.modificationTime = getModificationStamp(source);
- dartEntry.explicitlyAdded = explicitlyAdded;
- _cache.put(source, dartEntry);
- if (!explicitlyAdded) {
- _implicitAnalysisEventsController
- .add(new ImplicitAnalysisEvent(source, true));
- }
- return dartEntry;
- }
- }
-
- /**
- * Return a list containing all of the change notices that are waiting to be
- * returned. If there are no notices, then return either `null` or an empty
- * list, depending on the value of [nullIfEmpty].
- */
- List<ChangeNotice> _getChangeNotices(bool nullIfEmpty) {
- if (_pendingNotices.isEmpty) {
- if (nullIfEmpty) {
- return null;
- }
- return ChangeNoticeImpl.EMPTY_LIST;
- }
- List<ChangeNotice> notices = new List.from(_pendingNotices.values);
- _pendingNotices.clear();
- return notices;
- }
-
- /**
- * Given a source for a Dart file and the library that contains it, return the
- * data represented by the given descriptor that is associated with that
- * source. This method assumes that the data can be produced by generating
- * hints for the library if it is not already cached.
- *
- * Throws an [AnalysisException] if data could not be returned because the
- * source could not be resolved.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- Object _getDartHintData(Source unitSource, Source librarySource,
- DartEntry dartEntry, DataDescriptor descriptor) {
- dartEntry =
- _cacheDartHintData(unitSource, librarySource, dartEntry, descriptor);
- if (identical(descriptor, DartEntry.ELEMENT)) {
- return dartEntry.getValue(descriptor);
- }
- return dartEntry.getValueInLibrary(descriptor, librarySource);
- }
-
- /**
- * Given a source for a Dart file and the library that contains it, return the
- * data represented by the given descriptor that is associated with that
- * source. This method assumes that the data can be produced by generating
- * lints for the library if it is not already cached.
- *
- * Throws an [AnalysisException] if data could not be returned because the
- * source could not be resolved.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- Object _getDartLintData(Source unitSource, Source librarySource,
- DartEntry dartEntry, DataDescriptor descriptor) {
- dartEntry =
- _cacheDartLintData(unitSource, librarySource, dartEntry, descriptor);
- if (identical(descriptor, DartEntry.ELEMENT)) {
- return dartEntry.getValue(descriptor);
- }
- return dartEntry.getValueInLibrary(descriptor, librarySource);
- }
-
- /**
- * Given a source for a Dart file, return the data represented by the given
- * descriptor that is associated with that source. This method assumes that
- * the data can be produced by parsing the source if it is not already cached.
- *
- * Throws an [AnalysisException] if data could not be returned because the
- * source could not be parsed.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- Object _getDartParseData(
- Source source, DartEntry dartEntry, DataDescriptor descriptor) {
- dartEntry = _cacheDartParseData(source, dartEntry, descriptor);
- if (identical(descriptor, DartEntry.PARSED_UNIT)) {
- _accessedAst(source);
- return dartEntry.anyParsedCompilationUnit;
- }
- return dartEntry.getValue(descriptor);
- }
-
- /**
- * Given a source for a Dart file, return the data represented by the given
- * descriptor that is associated with that source, or the given default value
- * if the source is not a Dart file. This method assumes that the data can be
- * produced by parsing the source if it is not already cached.
- *
- * Throws an [AnalysisException] if data could not be returned because the
- * source could not be parsed.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- Object _getDartParseData2(
- Source source, DataDescriptor descriptor, Object defaultValue) {
- DartEntry dartEntry = _getReadableDartEntry(source);
- if (dartEntry == null) {
- return defaultValue;
- }
- try {
- return _getDartParseData(source, dartEntry, descriptor);
- } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
- AnalysisEngine.instance.logger.logInformation(
- "Could not compute $descriptor",
- new CaughtException(exception, stackTrace));
- return defaultValue;
- }
- }
-
- /**
- * Given a source for a Dart file and the library that contains it, return the
- * data represented by the given descriptor that is associated with that
- * source. This method assumes that the data can be produced by resolving the
- * source in the context of the library if it is not already cached.
- *
- * Throws an [AnalysisException] if data could not be returned because the
- * source could not be resolved.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- Object _getDartResolutionData(Source unitSource, Source librarySource,
- DartEntry dartEntry, DataDescriptor descriptor) {
- dartEntry = _cacheDartResolutionData(
- unitSource, librarySource, dartEntry, descriptor);
- if (identical(descriptor, DartEntry.ELEMENT)) {
- return dartEntry.getValue(descriptor);
- } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
- _accessedAst(unitSource);
- }
- return dartEntry.getValueInLibrary(descriptor, librarySource);
- }
-
- /**
- * Given a source for a Dart file and the library that contains it, return the
- * data represented by the given descriptor that is associated with that
- * source, or the given default value if the source is not a Dart file. This
- * method assumes that the data can be produced by resolving the source in the
- * context of the library if it is not already cached.
- *
- * Throws an [AnalysisException] if data could not be returned because the
- * source could not be resolved.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- Object _getDartResolutionData2(Source unitSource, Source librarySource,
- DataDescriptor descriptor, Object defaultValue) {
- DartEntry dartEntry = _getReadableDartEntry(unitSource);
- if (dartEntry == null) {
- return defaultValue;
- }
- try {
- return _getDartResolutionData(
- unitSource, librarySource, dartEntry, descriptor);
- } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
- AnalysisEngine.instance.logger.logInformation(
- "Could not compute $descriptor",
- new CaughtException(exception, stackTrace));
- return defaultValue;
- }
- }
-
- /**
- * Given a source for a Dart file, return the data represented by the given
- * descriptor that is associated with that source. This method assumes that
- * the data can be produced by scanning the source if it is not already
- * cached.
- *
- * Throws an [AnalysisException] if data could not be returned because the
- * source could not be scanned.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- Object _getDartScanData(
- Source source, DartEntry dartEntry, DataDescriptor descriptor) {
- dartEntry = _cacheDartScanData(source, dartEntry, descriptor);
- return dartEntry.getValue(descriptor);
- }
-
- /**
- * Given a source for a Dart file, return the data represented by the given
- * descriptor that is associated with that source, or the given default value
- * if the source is not a Dart file. This method assumes that the data can be
- * produced by scanning the source if it is not already cached.
- *
- * Throws an [AnalysisException] if data could not be returned because the
- * source could not be scanned.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- Object _getDartScanData2(
- Source source, DataDescriptor descriptor, Object defaultValue) {
- DartEntry dartEntry = _getReadableDartEntry(source);
- if (dartEntry == null) {
- return defaultValue;
- }
- try {
- return _getDartScanData(source, dartEntry, descriptor);
- } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
- AnalysisEngine.instance.logger.logInformation(
- "Could not compute $descriptor",
- new CaughtException(exception, stackTrace));
- return defaultValue;
- }
- }
-
- /**
- * Given a source for a Dart file and the library that contains it, return the
- * data represented by the given descriptor that is associated with that
- * source. This method assumes that the data can be produced by verifying the
- * source within the given library if it is not already cached.
- *
- * Throws an [AnalysisException] if data could not be returned because the
- * source could not be resolved.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- Object _getDartVerificationData(Source unitSource, Source librarySource,
- DartEntry dartEntry, DataDescriptor descriptor) {
- dartEntry = _cacheDartVerificationData(
- unitSource, librarySource, dartEntry, descriptor);
- return dartEntry.getValueInLibrary(descriptor, librarySource);
- }
-
- /**
- * Given a source for an HTML file, return the data represented by the given
- * descriptor that is associated with that source, or the given default value
- * if the source is not an HTML file. This method assumes that the data can be
- * produced by parsing the source if it is not already cached.
- *
- * Throws an [AnalysisException] if data could not be returned because the
- * source could not be parsed.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- Object _getHtmlParseData(
- Source source, DataDescriptor descriptor, Object defaultValue) {
- HtmlEntry htmlEntry = _getReadableHtmlEntry(source);
- if (htmlEntry == null) {
- return defaultValue;
- }
- htmlEntry = _cacheHtmlParseData(source, htmlEntry, descriptor);
- if (identical(descriptor, HtmlEntry.PARSED_UNIT)) {
- _accessedAst(source);
- return htmlEntry.anyParsedUnit;
- }
- return htmlEntry.getValue(descriptor);
- }
-
- /**
- * Given a source for an HTML file, return the data represented by the given
- * descriptor that is associated with that source, or the given default value
- * if the source is not an HTML file. This method assumes that the data can be
- * produced by resolving the source if it is not already cached.
- *
- * Throws an [AnalysisException] if data could not be returned because the
- * source could not be resolved.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- Object _getHtmlResolutionData(
- Source source, DataDescriptor descriptor, Object defaultValue) {
- HtmlEntry htmlEntry = _getReadableHtmlEntry(source);
- if (htmlEntry == null) {
- return defaultValue;
- }
- try {
- return _getHtmlResolutionData2(source, htmlEntry, descriptor);
- } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
- AnalysisEngine.instance.logger.logInformation(
- "Could not compute $descriptor",
- new CaughtException(exception, stackTrace));
- return defaultValue;
- }
- }
-
- /**
- * Given a source for an HTML file, return the data represented by the given
- * descriptor that is associated with that source. This method assumes that
- * the data can be produced by resolving the source if it is not already
- * cached.
- *
- * Throws an [AnalysisException] if data could not be returned because the
- * source could not be resolved.
- *
- * <b>Note:</b> This method cannot be used in an async environment.
- */
- Object _getHtmlResolutionData2(
- Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
- htmlEntry = _cacheHtmlResolutionData(source, htmlEntry, descriptor);
- if (identical(descriptor, HtmlEntry.RESOLVED_UNIT)) {
- _accessedAst(source);
- }
- return htmlEntry.getValue(descriptor);
- }
-
- /**
- * Look at the given [source] to see whether a task needs to be performed
- * related to it. Return the task that should be performed, or `null` if there
- * is no more work to be done for the source.
- */
- AnalysisContextImpl_TaskData _getNextAnalysisTaskForSource(
- Source source,
- SourceEntry sourceEntry,
- bool isPriority,
- bool hintsEnabled,
- bool lintsEnabled) {
- // Refuse to generate tasks for html based files that are above 1500 KB
- if (_isTooBigHtmlSourceEntry(source, sourceEntry)) {
- // TODO (jwren) we still need to report an error of some kind back to the
- // client.
- return new AnalysisContextImpl_TaskData(null, false);
- }
- if (sourceEntry == null) {
- return new AnalysisContextImpl_TaskData(null, false);
- }
- CacheState contentState = sourceEntry.getState(SourceEntry.CONTENT);
- if (contentState == CacheState.INVALID) {
- return _createGetContentTask(source, sourceEntry);
- } else if (contentState == CacheState.IN_PROCESS) {
- // We are already in the process of getting the content.
- // There's nothing else we can do with this source until that's complete.
- return new AnalysisContextImpl_TaskData(null, true);
- } else if (contentState == CacheState.ERROR) {
- // We have done all of the analysis we can for this source because we
- // cannot get its content.
- return new AnalysisContextImpl_TaskData(null, false);
- }
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry;
- CacheState scanErrorsState = dartEntry.getState(DartEntry.SCAN_ERRORS);
- if (scanErrorsState == CacheState.INVALID ||
- (isPriority && scanErrorsState == CacheState.FLUSHED)) {
- return _createScanDartTask(source, dartEntry);
- }
- CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS);
- if (parseErrorsState == CacheState.INVALID ||
- (isPriority && parseErrorsState == CacheState.FLUSHED)) {
- return _createParseDartTask(source, dartEntry);
- }
- if (isPriority && parseErrorsState != CacheState.ERROR) {
- if (!dartEntry.hasResolvableCompilationUnit) {
- return _createParseDartTask(source, dartEntry);
- }
- }
- SourceKind kind = dartEntry.getValue(DartEntry.SOURCE_KIND);
- if (kind == SourceKind.UNKNOWN) {
- return _createParseDartTask(source, dartEntry);
- } else if (kind == SourceKind.LIBRARY) {
- CacheState elementState = dartEntry.getState(DartEntry.ELEMENT);
- if (elementState == CacheState.INVALID) {
- return _createResolveDartLibraryTask(source, dartEntry);
- }
- }
- List<Source> librariesContaining = dartEntry.containingLibraries;
- for (Source librarySource in librariesContaining) {
- SourceEntry librarySourceEntry = _cache.get(librarySource);
- if (librarySourceEntry is DartEntry) {
- DartEntry libraryEntry = librarySourceEntry;
- CacheState elementState = libraryEntry.getState(DartEntry.ELEMENT);
- if (elementState == CacheState.INVALID ||
- (isPriority && elementState == CacheState.FLUSHED)) {
-// return createResolveDartLibraryTask(librarySource, (DartEntry) libraryEntry);
- return new AnalysisContextImpl_TaskData(
- new ResolveDartLibraryTask(this, source, librarySource), false);
- }
- CacheState resolvedUnitState = dartEntry.getStateInLibrary(
- DartEntry.RESOLVED_UNIT, librarySource);
- if (resolvedUnitState == CacheState.INVALID ||
- (isPriority && resolvedUnitState == CacheState.FLUSHED)) {
- //
- // The commented out lines below are an optimization that doesn't
- // quite work yet. The problem is that if the source was not
- // resolved because it wasn't part of any library, then there won't
- // be any elements in the element model that we can use to resolve
- // it.
- //
-// LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
-// if (libraryElement != null) {
-// return new ResolveDartUnitTask(this, source, libraryElement);
-// }
- // Possibly replace with:
-// return createResolveDartLibraryTask(librarySource, (DartEntry) libraryEntry);
- return new AnalysisContextImpl_TaskData(
- new ResolveDartLibraryTask(this, source, librarySource), false);
- }
- if (shouldErrorsBeAnalyzed(source, dartEntry)) {
- CacheState verificationErrorsState = dartEntry.getStateInLibrary(
- DartEntry.VERIFICATION_ERRORS, librarySource);
- if (verificationErrorsState == CacheState.INVALID ||
- (isPriority && verificationErrorsState == CacheState.FLUSHED)) {
- return _createGenerateDartErrorsTask(
- source, dartEntry, librarySource, libraryEntry);
- }
- if (hintsEnabled) {
- CacheState hintsState =
- dartEntry.getStateInLibrary(DartEntry.HINTS, librarySource);
- if (hintsState == CacheState.INVALID ||
- (isPriority && hintsState == CacheState.FLUSHED)) {
- return _createGenerateDartHintsTask(
- source, dartEntry, librarySource, libraryEntry);
- }
- }
- if (lintsEnabled) {
- CacheState lintsState =
- dartEntry.getStateInLibrary(DartEntry.LINTS, librarySource);
- if (lintsState == CacheState.INVALID ||
- (isPriority && lintsState == CacheState.FLUSHED)) {
- return _createGenerateDartLintsTask(
- source, dartEntry, librarySource, libraryEntry);
- }
- }
- }
- }
- }
- } else if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry;
- CacheState parseErrorsState = htmlEntry.getState(HtmlEntry.PARSE_ERRORS);
- if (parseErrorsState == CacheState.INVALID ||
- (isPriority && parseErrorsState == CacheState.FLUSHED)) {
- return _createParseHtmlTask(source, htmlEntry);
- }
- if (isPriority && parseErrorsState != CacheState.ERROR) {
- ht.HtmlUnit parsedUnit = htmlEntry.anyParsedUnit;
- if (parsedUnit == null) {
- return _createParseHtmlTask(source, htmlEntry);
- }
- }
- CacheState resolvedUnitState =
- htmlEntry.getState(HtmlEntry.RESOLVED_UNIT);
- if (resolvedUnitState == CacheState.INVALID ||
- (isPriority && resolvedUnitState == CacheState.FLUSHED)) {
- return _createResolveHtmlTask(source, htmlEntry);
- }
- }
- return new AnalysisContextImpl_TaskData(null, false);
- }
-
- /**
- * Return the cache entry associated with the given [source], or `null` if the
- * source is not a Dart file.
- *
- * @param source the source for which a cache entry is being sought
- * @return the source cache entry associated with the given source
- */
- DartEntry _getReadableDartEntry(Source source) {
- SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry == null) {
- sourceEntry = _createSourceEntry(source, false);
- }
- if (sourceEntry is DartEntry) {
- return sourceEntry;
- }
- return null;
- }
-
- /**
- * Return the cache entry associated with the given [source], or `null` if the
- * source is not an HTML file.
- */
- HtmlEntry _getReadableHtmlEntry(Source source) {
- SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry == null) {
- sourceEntry = _createSourceEntry(source, false);
- }
- if (sourceEntry is HtmlEntry) {
- return sourceEntry;
- }
- return null;
- }
-
- /**
- * Return the cache entry associated with the given [source], creating it if
- * necessary.
- */
- SourceEntry _getReadableSourceEntry(Source source) {
- SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry == null) {
- sourceEntry = _createSourceEntry(source, false);
- }
- return sourceEntry;
- }
-
- /**
- * Return a resolved compilation unit corresponding to the given [element] in
- * the library defined by the given [librarySource], or `null` if the
- * information is not cached.
- */
- TimestampedData<CompilationUnit> _getResolvedUnit(
- CompilationUnitElement element, Source librarySource) {
- SourceEntry sourceEntry = _cache.get(element.source);
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry;
- if (dartEntry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource) ==
- CacheState.VALID) {
- return new TimestampedData<CompilationUnit>(
- dartEntry.modificationTime,
- dartEntry.getValueInLibrary(
- DartEntry.RESOLVED_UNIT, librarySource));
- }
- }
- return null;
- }
-
- /**
- * Return a list containing all of the sources known to this context that have
- * the given [kind].
- */
- List<Source> _getSources(SourceKind kind) {
- List<Source> sources = new List<Source>();
- MapIterator<Source, SourceEntry> iterator = _cache.iterator();
- while (iterator.moveNext()) {
- if (iterator.value.kind == kind) {
- sources.add(iterator.key);
- }
- }
- return sources;
- }
-
- /**
- * Look at the given [source] to see whether a task needs to be performed
- * related to it. If so, add the source to the set of sources that need to be
- * processed. This method duplicates, and must therefore be kept in sync with,
- * [_getNextAnalysisTaskForSource]. This method is intended to be used for
- * testing purposes only.
- */
- void _getSourcesNeedingProcessing(
- Source source,
- SourceEntry sourceEntry,
- bool isPriority,
- bool hintsEnabled,
- bool lintsEnabled,
- HashSet<Source> sources) {
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry;
- CacheState scanErrorsState = dartEntry.getState(DartEntry.SCAN_ERRORS);
- if (scanErrorsState == CacheState.INVALID ||
- (isPriority && scanErrorsState == CacheState.FLUSHED)) {
- sources.add(source);
- return;
- }
- CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS);
- if (parseErrorsState == CacheState.INVALID ||
- (isPriority && parseErrorsState == CacheState.FLUSHED)) {
- sources.add(source);
- return;
- }
- if (isPriority) {
- if (!dartEntry.hasResolvableCompilationUnit) {
- sources.add(source);
- return;
- }
- }
- for (Source librarySource in getLibrariesContaining(source)) {
- SourceEntry libraryEntry = _cache.get(librarySource);
- if (libraryEntry is DartEntry) {
- CacheState elementState = libraryEntry.getState(DartEntry.ELEMENT);
- if (elementState == CacheState.INVALID ||
- (isPriority && elementState == CacheState.FLUSHED)) {
- sources.add(source);
- return;
- }
- CacheState resolvedUnitState = dartEntry.getStateInLibrary(
- DartEntry.RESOLVED_UNIT, librarySource);
- if (resolvedUnitState == CacheState.INVALID ||
- (isPriority && resolvedUnitState == CacheState.FLUSHED)) {
- LibraryElement libraryElement =
- libraryEntry.getValue(DartEntry.ELEMENT);
- if (libraryElement != null) {
- sources.add(source);
- return;
- }
- }
- if (shouldErrorsBeAnalyzed(source, dartEntry)) {
- CacheState verificationErrorsState = dartEntry.getStateInLibrary(
- DartEntry.VERIFICATION_ERRORS, librarySource);
- if (verificationErrorsState == CacheState.INVALID ||
- (isPriority && verificationErrorsState == CacheState.FLUSHED)) {
- LibraryElement libraryElement =
- libraryEntry.getValue(DartEntry.ELEMENT);
- if (libraryElement != null) {
- sources.add(source);
- return;
- }
- }
- if (hintsEnabled) {
- CacheState hintsState =
- dartEntry.getStateInLibrary(DartEntry.HINTS, librarySource);
- if (hintsState == CacheState.INVALID ||
- (isPriority && hintsState == CacheState.FLUSHED)) {
- LibraryElement libraryElement =
- libraryEntry.getValue(DartEntry.ELEMENT);
- if (libraryElement != null) {
- sources.add(source);
- return;
- }
- }
- }
- if (lintsEnabled) {
- CacheState lintsState =
- dartEntry.getStateInLibrary(DartEntry.LINTS, librarySource);
- if (lintsState == CacheState.INVALID ||
- (isPriority && lintsState == CacheState.FLUSHED)) {
- LibraryElement libraryElement =
- libraryEntry.getValue(DartEntry.ELEMENT);
- if (libraryElement != null) {
- sources.add(source);
- return;
- }
- }
- }
- }
- }
- }
- } else if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry;
- CacheState parsedUnitState = htmlEntry.getState(HtmlEntry.PARSED_UNIT);
- if (parsedUnitState == CacheState.INVALID ||
- (isPriority && parsedUnitState == CacheState.FLUSHED)) {
- sources.add(source);
- return;
- }
- CacheState resolvedUnitState =
- htmlEntry.getState(HtmlEntry.RESOLVED_UNIT);
- if (resolvedUnitState == CacheState.INVALID ||
- (isPriority && resolvedUnitState == CacheState.FLUSHED)) {
- sources.add(source);
- return;
- }
- }
- }
-
- /**
- * Invalidate all of the resolution results computed by this context. The flag
- * [invalidateUris] should be `true` if the cached results of converting URIs
- * to source files should also be invalidated.
- */
- void _invalidateAllLocalResolutionInformation(bool invalidateUris) {
- HashMap<Source, List<Source>> oldPartMap =
- new HashMap<Source, List<Source>>();
- MapIterator<Source, SourceEntry> iterator = _privatePartition.iterator();
- while (iterator.moveNext()) {
- Source source = iterator.key;
- SourceEntry sourceEntry = iterator.value;
- if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry;
- htmlEntry.invalidateAllResolutionInformation(invalidateUris);
- iterator.value = htmlEntry;
- _workManager.add(source, SourcePriority.HTML);
- } else if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry;
- oldPartMap[source] = dartEntry.getValue(DartEntry.INCLUDED_PARTS);
- dartEntry.invalidateAllResolutionInformation(invalidateUris);
- iterator.value = dartEntry;
- _workManager.add(source, _computePriority(dartEntry));
- }
- }
- _removeFromPartsUsingMap(oldPartMap);
- }
-
- /**
- * In response to a change to at least one of the compilation units in the
- * library defined by the given [librarySource], invalidate any results that
- * are dependent on the result of resolving that library.
- *
- * <b>Note:</b> Any cache entries that were accessed before this method was
- * invoked must be re-accessed after this method returns.
- */
- void _invalidateLibraryResolution(Source librarySource) {
- // TODO(brianwilkerson) This could be optimized. There's no need to flush
- // all of these entries if the public namespace hasn't changed, which will
- // be a fairly common case. The question is whether we can afford the time
- // to compute the namespace to look for differences.
- DartEntry libraryEntry = _getReadableDartEntry(librarySource);
- if (libraryEntry != null) {
- List<Source> includedParts =
- libraryEntry.getValue(DartEntry.INCLUDED_PARTS);
- libraryEntry.invalidateAllResolutionInformation(false);
- _workManager.add(librarySource, SourcePriority.LIBRARY);
- for (Source partSource in includedParts) {
- SourceEntry partEntry = _cache.get(partSource);
- if (partEntry is DartEntry) {
- partEntry.invalidateAllResolutionInformation(false);
- }
- }
- }
- }
-
- /**
- * Return `true` if the given [library] is, or depends on, 'dart:html'. The
- * [visitedLibraries] is a collection of the libraries that have been visited,
- * used to prevent infinite recursion.
- */
- bool _isClient(LibraryElement library, Source htmlSource,
- HashSet<LibraryElement> visitedLibraries) {
- if (visitedLibraries.contains(library)) {
- return false;
- }
- if (library.source == htmlSource) {
- return true;
- }
- visitedLibraries.add(library);
- for (LibraryElement imported in library.importedLibraries) {
- if (_isClient(imported, htmlSource, visitedLibraries)) {
- return true;
- }
- }
- for (LibraryElement exported in library.exportedLibraries) {
- if (_isClient(exported, htmlSource, visitedLibraries)) {
- return true;
- }
- }
- return false;
- }
-
- bool _isTooBigHtmlSourceEntry(Source source, SourceEntry sourceEntry) =>
- false;
-
-// /**
-// * Notify all of the analysis listeners that the given source is no longer included in the set of
-// * sources that are being analyzed.
-// *
-// * @param source the source that is no longer being analyzed
-// */
-// void _notifyExcludedSource(Source source) {
-// int count = _listeners.length;
-// for (int i = 0; i < count; i++) {
-// _listeners[i].excludedSource(this, source);
-// }
-// }
-
-// /**
-// * Notify all of the analysis listeners that the given source is now included in the set of
-// * sources that are being analyzed.
-// *
-// * @param source the source that is now being analyzed
-// */
-// void _notifyIncludedSource(Source source) {
-// int count = _listeners.length;
-// for (int i = 0; i < count; i++) {
-// _listeners[i].includedSource(this, source);
-// }
-// }
-
-// /**
-// * Notify all of the analysis listeners that the given Dart source was parsed.
-// *
-// * @param source the source that was parsed
-// * @param unit the result of parsing the source
-// */
-// void _notifyParsedDart(Source source, CompilationUnit unit) {
-// int count = _listeners.length;
-// for (int i = 0; i < count; i++) {
-// _listeners[i].parsedDart(this, source, unit);
-// }
-// }
-
-// /**
-// * Notify all of the analysis listeners that the given HTML source was parsed.
-// *
-// * @param source the source that was parsed
-// * @param unit the result of parsing the source
-// */
-// void _notifyParsedHtml(Source source, ht.HtmlUnit unit) {
-// int count = _listeners.length;
-// for (int i = 0; i < count; i++) {
-// _listeners[i].parsedHtml(this, source, unit);
-// }
-// }
-
-// /**
-// * Notify all of the analysis listeners that the given Dart source was resolved.
-// *
-// * @param source the source that was resolved
-// * @param unit the result of resolving the source
-// */
-// void _notifyResolvedDart(Source source, CompilationUnit unit) {
-// int count = _listeners.length;
-// for (int i = 0; i < count; i++) {
-// _listeners[i].resolvedDart(this, source, unit);
-// }
-// }
-
-// /**
-// * Notify all of the analysis listeners that the given HTML source was resolved.
-// *
-// * @param source the source that was resolved
-// * @param unit the result of resolving the source
-// */
-// void _notifyResolvedHtml(Source source, ht.HtmlUnit unit) {
-// int count = _listeners.length;
-// for (int i = 0; i < count; i++) {
-// _listeners[i].resolvedHtml(this, source, unit);
-// }
-// }
-
- /**
- * Log the given debugging [message].
- */
- void _logInformation(String message) {
- AnalysisEngine.instance.logger.logInformation(message);
- }
-
- /**
- * Notify all of the analysis listeners that a task is about to be performed.
- */
- void _notifyAboutToPerformTask(String taskDescription) {
- int count = _listeners.length;
- for (int i = 0; i < count; i++) {
- _listeners[i].aboutToPerformTask(this, taskDescription);
- }
- }
-
- /**
- * Notify all of the analysis listeners that the errors associated with the
- * given [source] has been updated to the given [errors].
- */
- void _notifyErrors(
- Source source, List<AnalysisError> errors, LineInfo lineInfo) {
- int count = _listeners.length;
- for (int i = 0; i < count; i++) {
- _listeners[i].computedErrors(this, source, errors, lineInfo);
- }
- }
-
- /**
- * Given that the given [source] (with the corresponding [sourceEntry]) has
- * been invalidated, invalidate all of the libraries that depend on it.
- */
- void _propagateInvalidation(Source source, SourceEntry sourceEntry) {
- if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry;
- htmlEntry.modificationTime = getModificationStamp(source);
- htmlEntry.invalidateAllInformation();
- _cache.removedAst(source);
- _workManager.add(source, SourcePriority.HTML);
- } else if (sourceEntry is DartEntry) {
- List<Source> containingLibraries = getLibrariesContaining(source);
- List<Source> dependentLibraries = getLibrariesDependingOn(source);
- HashSet<Source> librariesToInvalidate = new HashSet<Source>();
- for (Source containingLibrary in containingLibraries) {
- _computeAllLibrariesDependingOn(
- containingLibrary, librariesToInvalidate);
- }
- for (Source dependentLibrary in dependentLibraries) {
- _computeAllLibrariesDependingOn(
- dependentLibrary, librariesToInvalidate);
- }
- for (Source library in librariesToInvalidate) {
- _invalidateLibraryResolution(library);
- }
- DartEntry dartEntry = _cache.get(source);
- _removeFromParts(source, dartEntry);
- dartEntry.modificationTime = getModificationStamp(source);
- dartEntry.invalidateAllInformation();
- _cache.removedAst(source);
- _workManager.add(source, SourcePriority.UNKNOWN);
- }
- // reset unit in the notification, it is out of date now
- ChangeNoticeImpl notice = _pendingNotices[source];
- if (notice != null) {
- notice.resolvedDartUnit = null;
- notice.resolvedHtmlUnit = null;
- }
- }
-
- /**
- * Given a [dartEntry] and a [library] element, record the library element and
- * other information gleaned from the element in the cache entry.
- */
- void _recordElementData(DartEntry dartEntry, LibraryElement library,
- Source librarySource, Source htmlSource) {
- dartEntry.setValue(DartEntry.ELEMENT, library);
- dartEntry.setValue(DartEntry.IS_LAUNCHABLE, library.entryPoint != null);
- dartEntry.setValue(DartEntry.IS_CLIENT,
- _isClient(library, htmlSource, new HashSet<LibraryElement>()));
- }
-
- /**
- * Record the results produced by performing a [task] and return the cache
- * entry associated with the results.
- */
- DartEntry _recordGenerateDartErrorsTask(GenerateDartErrorsTask task) {
- Source source = task.source;
- DartEntry dartEntry = _cache.get(source);
- Source librarySource = task.libraryElement.source;
- CaughtException thrownException = task.exception;
- if (thrownException != null) {
- dartEntry.recordVerificationErrorInLibrary(
- librarySource, thrownException);
- throw new AnalysisException('<rethrow>', thrownException);
- }
- dartEntry.setValueInLibrary(
- DartEntry.VERIFICATION_ERRORS, librarySource, task.errors);
- ChangeNoticeImpl notice = getNotice(source);
- LineInfo lineInfo = dartEntry.getValue(SourceEntry.LINE_INFO);
- notice.setErrors(dartEntry.allErrors, lineInfo);
- return dartEntry;
- }
-
- /**
- * Record the results produced by performing a [task] and return the cache
- * entry associated with the results.
- */
- DartEntry _recordGenerateDartHintsTask(GenerateDartHintsTask task) {
- Source librarySource = task.libraryElement.source;
- CaughtException thrownException = task.exception;
- DartEntry libraryEntry = null;
- HashMap<Source, List<AnalysisError>> hintMap = task.hintMap;
- if (hintMap == null) {
- // We don't have any information about which sources to mark as invalid
- // other than the library source.
- DartEntry libraryEntry = _cache.get(librarySource);
- if (thrownException == null) {
- String message = "GenerateDartHintsTask returned a null hint map "
- "without throwing an exception: ${librarySource.fullName}";
- thrownException =
- new CaughtException(new AnalysisException(message), null);
- }
- libraryEntry.recordHintErrorInLibrary(librarySource, thrownException);
- throw new AnalysisException('<rethrow>', thrownException);
- }
- hintMap.forEach((Source unitSource, List<AnalysisError> hints) {
- DartEntry dartEntry = _cache.get(unitSource);
- if (unitSource == librarySource) {
- libraryEntry = dartEntry;
- }
- if (thrownException == null) {
- dartEntry.setValueInLibrary(DartEntry.HINTS, librarySource, hints);
- ChangeNoticeImpl notice = getNotice(unitSource);
- LineInfo lineInfo = dartEntry.getValue(SourceEntry.LINE_INFO);
- notice.setErrors(dartEntry.allErrors, lineInfo);
- } else {
- dartEntry.recordHintErrorInLibrary(librarySource, thrownException);
- }
- });
- if (thrownException != null) {
- throw new AnalysisException('<rethrow>', thrownException);
- }
- return libraryEntry;
- }
-
- /**
- * Record the results produced by performing a [task] and return the cache
- * entry associated with the results.
- */
- DartEntry _recordGenerateDartLintsTask(GenerateDartLintsTask task) {
- Source librarySource = task.libraryElement.source;
- CaughtException thrownException = task.exception;
- DartEntry libraryEntry = null;
- HashMap<Source, List<AnalysisError>> lintMap = task.lintMap;
- if (lintMap == null) {
- // We don't have any information about which sources to mark as invalid
- // other than the library source.
- DartEntry libraryEntry = _cache.get(librarySource);
- if (thrownException == null) {
- String message = "GenerateDartLintsTask returned a null lint map "
- "without throwing an exception: ${librarySource.fullName}";
- thrownException =
- new CaughtException(new AnalysisException(message), null);
- }
- libraryEntry.recordLintErrorInLibrary(librarySource, thrownException);
- throw new AnalysisException('<rethrow>', thrownException);
- }
- lintMap.forEach((Source unitSource, List<AnalysisError> lints) {
- DartEntry dartEntry = _cache.get(unitSource);
- if (unitSource == librarySource) {
- libraryEntry = dartEntry;
- }
- if (thrownException == null) {
- dartEntry.setValueInLibrary(DartEntry.LINTS, librarySource, lints);
- ChangeNoticeImpl notice = getNotice(unitSource);
- LineInfo lineInfo = dartEntry.getValue(SourceEntry.LINE_INFO);
- notice.setErrors(dartEntry.allErrors, lineInfo);
- } else {
- dartEntry.recordLintErrorInLibrary(librarySource, thrownException);
- }
- });
- if (thrownException != null) {
- throw new AnalysisException('<rethrow>', thrownException);
- }
- return libraryEntry;
- }
-
- /**
- * Record the results produced by performing a [task] and return the cache
- * entry associated with the results.
- */
- SourceEntry _recordGetContentsTask(GetContentTask task) {
- if (!task.isComplete) {
- return null;
- }
- Source source = task.source;
- SourceEntry sourceEntry = _cache.get(source);
- CaughtException thrownException = task.exception;
- if (thrownException != null) {
- sourceEntry.recordContentError(thrownException);
- {
- sourceEntry.setValue(SourceEntry.CONTENT_ERRORS, task.errors);
- ChangeNoticeImpl notice = getNotice(source);
- notice.setErrors(sourceEntry.allErrors, null);
- }
- _workManager.remove(source);
- throw new AnalysisException('<rethrow>', thrownException);
- }
- sourceEntry.modificationTime = task.modificationTime;
- sourceEntry.setValue(SourceEntry.CONTENT, task.content);
- return sourceEntry;
- }
-
- /**
- * Record the results produced by performing a [task] and return the cache
- * entry associated with the results.
- */
- DartEntry _recordIncrementalAnalysisTaskResults(
- IncrementalAnalysisTask task) {
- CompilationUnit unit = task.compilationUnit;
- if (unit != null) {
- ChangeNoticeImpl notice = getNotice(task.source);
- notice.resolvedDartUnit = unit;
- _incrementalAnalysisCache =
- IncrementalAnalysisCache.cacheResult(task.cache, unit);
- }
- return null;
- }
-
- /**
- * Record the results produced by performing a [task] and return the cache
- * entry associated with the results.
- */
- DartEntry _recordParseDartTaskResults(ParseDartTask task) {
- Source source = task.source;
- DartEntry dartEntry = _cache.get(source);
- _removeFromParts(source, dartEntry);
- CaughtException thrownException = task.exception;
- if (thrownException != null) {
- _removeFromParts(source, dartEntry);
- dartEntry.recordParseError(thrownException);
- _cache.removedAst(source);
- throw new AnalysisException('<rethrow>', thrownException);
- }
- if (task.hasNonPartOfDirective) {
- dartEntry.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
- dartEntry.containingLibrary = source;
- _workManager.add(source, SourcePriority.LIBRARY);
- } else if (task.hasPartOfDirective) {
- dartEntry.setValue(DartEntry.SOURCE_KIND, SourceKind.PART);
- dartEntry.removeContainingLibrary(source);
- _workManager.add(source, SourcePriority.NORMAL_PART);
- } else {
- // The file contains no directives.
- List<Source> containingLibraries = dartEntry.containingLibraries;
- if (containingLibraries.length > 1 ||
- (containingLibraries.length == 1 &&
- containingLibraries[0] != source)) {
- dartEntry.setValue(DartEntry.SOURCE_KIND, SourceKind.PART);
- dartEntry.removeContainingLibrary(source);
- _workManager.add(source, SourcePriority.NORMAL_PART);
- } else {
- dartEntry.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
- dartEntry.containingLibrary = source;
- _workManager.add(source, SourcePriority.LIBRARY);
- }
- }
- List<Source> newParts = task.includedSources;
- for (int i = 0; i < newParts.length; i++) {
- Source partSource = newParts[i];
- DartEntry partEntry = _getReadableDartEntry(partSource);
- if (partEntry != null && !identical(partEntry, dartEntry)) {
- // TODO(brianwilkerson) Change the kind of the "part" if it was marked
- // as a library and it has no directives.
- partEntry.addContainingLibrary(source);
- }
- }
- dartEntry.setValue(DartEntry.PARSED_UNIT, task.compilationUnit);
- dartEntry.setValue(DartEntry.PARSE_ERRORS, task.errors);
- dartEntry.setValue(DartEntry.EXPORTED_LIBRARIES, task.exportedSources);
- dartEntry.setValue(DartEntry.IMPORTED_LIBRARIES, task.importedSources);
- dartEntry.setValue(DartEntry.INCLUDED_PARTS, newParts);
- _cache.storedAst(source);
- ChangeNoticeImpl notice = getNotice(source);
- if (notice.resolvedDartUnit == null) {
- notice.parsedDartUnit = task.compilationUnit;
- }
- notice.setErrors(dartEntry.allErrors, task.lineInfo);
- // Verify that the incrementally parsed and resolved unit in the incremental
- // cache is structurally equivalent to the fully parsed unit
- _incrementalAnalysisCache = IncrementalAnalysisCache.verifyStructure(
- _incrementalAnalysisCache, source, task.compilationUnit);
- return dartEntry;
- }
-
- /**
- * Record the results produced by performing a [task] and return the cache
- * entry associated with the results.
- */
- HtmlEntry _recordParseHtmlTaskResults(ParseHtmlTask task) {
- Source source = task.source;
- HtmlEntry htmlEntry = _cache.get(source);
- CaughtException thrownException = task.exception;
- if (thrownException != null) {
- htmlEntry.recordParseError(thrownException);
- _cache.removedAst(source);
- throw new AnalysisException('<rethrow>', thrownException);
- }
- LineInfo lineInfo = task.lineInfo;
- htmlEntry.setValue(SourceEntry.LINE_INFO, lineInfo);
- htmlEntry.setValue(HtmlEntry.PARSED_UNIT, task.htmlUnit);
- htmlEntry.setValue(HtmlEntry.PARSE_ERRORS, task.errors);
- htmlEntry.setValue(
- HtmlEntry.REFERENCED_LIBRARIES, task.referencedLibraries);
- _cache.storedAst(source);
- ChangeNoticeImpl notice = getNotice(source);
- notice.setErrors(htmlEntry.allErrors, lineInfo);
- return htmlEntry;
- }
-
- /**
- * Record the results produced by performing a [task] and return the cache
- * entry associated with the results.
- */
- DartEntry _recordResolveDartUnitTaskResults(ResolveDartUnitTask task) {
- Source unitSource = task.source;
- DartEntry dartEntry = _cache.get(unitSource);
- Source librarySource = task.librarySource;
- CaughtException thrownException = task.exception;
- if (thrownException != null) {
- dartEntry.recordResolutionErrorInLibrary(librarySource, thrownException);
- _cache.removedAst(unitSource);
- throw new AnalysisException('<rethrow>', thrownException);
- }
- dartEntry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, librarySource, task.resolvedUnit);
- _cache.storedAst(unitSource);
- return dartEntry;
- }
-
- /**
- * Record the results produced by performing a [task] and return the cache
- * entry associated with the results.
- */
- HtmlEntry _recordResolveHtmlTaskResults(ResolveHtmlTask task) {
- Source source = task.source;
- HtmlEntry htmlEntry = _cache.get(source);
- CaughtException thrownException = task.exception;
- if (thrownException != null) {
- htmlEntry.recordResolutionError(thrownException);
- _cache.removedAst(source);
- throw new AnalysisException('<rethrow>', thrownException);
- }
- htmlEntry.setState(HtmlEntry.PARSED_UNIT, CacheState.FLUSHED);
- htmlEntry.setValue(HtmlEntry.RESOLVED_UNIT, task.resolvedUnit);
- htmlEntry.setValue(HtmlEntry.ELEMENT, task.element);
- htmlEntry.setValue(HtmlEntry.RESOLUTION_ERRORS, task.resolutionErrors);
- _cache.storedAst(source);
- ChangeNoticeImpl notice = getNotice(source);
- notice.resolvedHtmlUnit = task.resolvedUnit;
- LineInfo lineInfo = htmlEntry.getValue(SourceEntry.LINE_INFO);
- notice.setErrors(htmlEntry.allErrors, lineInfo);
- return htmlEntry;
- }
-
- /**
- * Record the results produced by performing a [task] and return the cache
- * entry associated with the results.
- */
- DartEntry _recordScanDartTaskResults(ScanDartTask task) {
- Source source = task.source;
- DartEntry dartEntry = _cache.get(source);
- CaughtException thrownException = task.exception;
- if (thrownException != null) {
- _removeFromParts(source, dartEntry);
- dartEntry.recordScanError(thrownException);
- _cache.removedAst(source);
- throw new AnalysisException('<rethrow>', thrownException);
- }
- LineInfo lineInfo = task.lineInfo;
- dartEntry.setValue(SourceEntry.LINE_INFO, lineInfo);
- dartEntry.setValue(DartEntry.TOKEN_STREAM, task.tokenStream);
- dartEntry.setValue(DartEntry.SCAN_ERRORS, task.errors);
- _cache.storedAst(source);
- ChangeNoticeImpl notice = getNotice(source);
- notice.setErrors(dartEntry.allErrors, lineInfo);
- return dartEntry;
- }
-
- void _removeFromCache(Source source) {
- SourceEntry entry = _cache.remove(source);
- if (entry != null && !entry.explicitlyAdded) {
- _implicitAnalysisEventsController
- .add(new ImplicitAnalysisEvent(source, false));
- }
- }
-
- /**
- * Remove the given [librarySource] from the list of containing libraries for
- * all of the parts referenced by the given [dartEntry].
- */
- void _removeFromParts(Source librarySource, DartEntry dartEntry) {
- List<Source> oldParts = dartEntry.getValue(DartEntry.INCLUDED_PARTS);
- for (int i = 0; i < oldParts.length; i++) {
- Source partSource = oldParts[i];
- DartEntry partEntry = _getReadableDartEntry(partSource);
- if (partEntry != null && !identical(partEntry, dartEntry)) {
- partEntry.removeContainingLibrary(librarySource);
- if (partEntry.containingLibraries.length == 0 && !exists(partSource)) {
- _removeFromCache(partSource);
- }
- }
- }
- }
-
- /**
- * Remove the given libraries that are keys in the given map from the list of
- * containing libraries for each of the parts in the corresponding value.
- */
- void _removeFromPartsUsingMap(HashMap<Source, List<Source>> oldPartMap) {
- oldPartMap.forEach((Source librarySource, List<Source> oldParts) {
- for (int i = 0; i < oldParts.length; i++) {
- Source partSource = oldParts[i];
- if (partSource != librarySource) {
- DartEntry partEntry = _getReadableDartEntry(partSource);
- if (partEntry != null) {
- partEntry.removeContainingLibrary(librarySource);
- if (partEntry.containingLibraries.length == 0 &&
- !exists(partSource)) {
- _removeFromCache(partSource);
- }
- }
- }
- }
- });
- }
-
- /**
- * Remove the given [source] from the priority order if it is in the list.
- */
- void _removeFromPriorityOrder(Source source) {
- int count = _priorityOrder.length;
- List<Source> newOrder = new List<Source>();
- for (int i = 0; i < count; i++) {
- if (_priorityOrder[i] != source) {
- newOrder.add(_priorityOrder[i]);
- }
- }
- if (newOrder.length < count) {
- analysisPriorityOrder = newOrder;
- }
- }
-
- /**
- * Create an entry for the newly added [source] and invalidate any sources
- * that referenced the source before it existed.
- */
- void _sourceAvailable(Source source) {
- // TODO(brianwilkerson) This method needs to check whether the source was
- // previously being implicitly analyzed. If so, the cache entry needs to be
- // update to reflect the new status and an event needs to be generated to
- // inform clients that it is no longer being implicitly analyzed.
- SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry == null) {
- sourceEntry = _createSourceEntry(source, true);
- } else {
- _propagateInvalidation(source, sourceEntry);
- sourceEntry = _cache.get(source);
- }
- if (sourceEntry is HtmlEntry) {
- _workManager.add(source, SourcePriority.HTML);
- } else if (sourceEntry is DartEntry) {
- _workManager.add(source, _computePriority(sourceEntry));
- }
- }
-
- /**
- * Invalidate the [source] that was changed and any sources that referenced
- * the source before it existed.
- */
- void _sourceChanged(Source source) {
- SourceEntry sourceEntry = _cache.get(source);
- // If the source is removed, we don't care about it.
- if (sourceEntry == null) {
- return;
- }
- // Check if the content of the source is the same as it was the last time.
- String sourceContent = sourceEntry.getValue(SourceEntry.CONTENT);
- if (sourceContent != null) {
- sourceEntry.setState(SourceEntry.CONTENT, CacheState.FLUSHED);
- try {
- TimestampedData<String> fileContents = getContents(source);
- if (fileContents.data == sourceContent) {
- return;
- }
- } catch (e) {}
- }
- // We have to invalidate the cache.
- _propagateInvalidation(source, sourceEntry);
- }
-
- /**
- * Record that the give [source] has been deleted.
- */
- void _sourceDeleted(Source source) {
- SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry;
- htmlEntry.recordContentError(new CaughtException(
- new AnalysisException("This source was marked as being deleted"),
- null));
- } else if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry;
- HashSet<Source> libraries = new HashSet<Source>();
- for (Source librarySource in getLibrariesContaining(source)) {
- libraries.add(librarySource);
- for (Source dependentLibrary
- in getLibrariesDependingOn(librarySource)) {
- libraries.add(dependentLibrary);
- }
- }
- for (Source librarySource in libraries) {
- _invalidateLibraryResolution(librarySource);
- }
- dartEntry.recordContentError(new CaughtException(
- new AnalysisException("This source was marked as being deleted"),
- null));
- }
- _workManager.remove(source);
- _removeFromPriorityOrder(source);
- }
-
- /**
- * Record that the given [source] has been removed.
- */
- void _sourceRemoved(Source source) {
- SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry is HtmlEntry) {} else if (sourceEntry is DartEntry) {
- HashSet<Source> libraries = new HashSet<Source>();
- for (Source librarySource in getLibrariesContaining(source)) {
- libraries.add(librarySource);
- for (Source dependentLibrary
- in getLibrariesDependingOn(librarySource)) {
- libraries.add(dependentLibrary);
- }
- }
- for (Source librarySource in libraries) {
- _invalidateLibraryResolution(librarySource);
- }
- }
- _removeFromCache(source);
- _workManager.remove(source);
- _removeFromPriorityOrder(source);
- }
-
- /**
- * TODO(scheglov) A hackish, limited incremental resolution implementation.
- */
- bool _tryPoorMansIncrementalResolution(Source unitSource, String newCode) {
- return PerformanceStatistics.incrementalAnalysis.makeCurrentWhile(() {
- incrementalResolutionValidation_lastUnitSource = null;
- incrementalResolutionValidation_lastLibrarySource = null;
- incrementalResolutionValidation_lastUnit = null;
- // prepare the entry
- DartEntry dartEntry = _cache.get(unitSource);
- if (dartEntry == null) {
- return false;
- }
- // prepare the (only) library source
- List<Source> librarySources = getLibrariesContaining(unitSource);
- if (librarySources.length != 1) {
- return false;
- }
- Source librarySource = librarySources[0];
- // prepare the library element
- LibraryElement libraryElement = getLibraryElement(librarySource);
- if (libraryElement == null) {
- return false;
- }
- // prepare the existing unit
- CompilationUnit oldUnit =
- getResolvedCompilationUnit2(unitSource, librarySource);
- if (oldUnit == null) {
- return false;
- }
- // do resolution
- Stopwatch perfCounter = new Stopwatch()..start();
- PoorMansIncrementalResolver resolver = new PoorMansIncrementalResolver(
- typeProvider,
- unitSource,
- getReadableSourceEntryOrNull(unitSource),
- null,
- null,
- oldUnit,
- analysisOptions.incrementalApi);
- bool success = resolver.resolve(newCode);
- AnalysisEngine.instance.instrumentationService.logPerformance(
- AnalysisPerformanceKind.INCREMENTAL,
- perfCounter,
- 'success=$success,context_id=$_id,code_length=${newCode.length}');
- if (!success) {
- return false;
- }
- // if validation, remember the result, but throw it away
- if (analysisOptions.incrementalValidation) {
- incrementalResolutionValidation_lastUnitSource = oldUnit.element.source;
- incrementalResolutionValidation_lastLibrarySource =
- oldUnit.element.library.source;
- incrementalResolutionValidation_lastUnit = oldUnit;
- return false;
- }
- // prepare notice
- {
- LineInfo lineInfo = getLineInfo(unitSource);
- ChangeNoticeImpl notice = getNotice(unitSource);
- notice.resolvedDartUnit = oldUnit;
- notice.setErrors(dartEntry.allErrors, lineInfo);
- }
- // OK
- return true;
- });
- }
-
- void _validateLastIncrementalResolutionResult() {
- if (incrementalResolutionValidation_lastUnitSource == null ||
- incrementalResolutionValidation_lastLibrarySource == null ||
- incrementalResolutionValidation_lastUnit == null) {
- return;
- }
- CompilationUnit fullUnit = getResolvedCompilationUnit2(
- incrementalResolutionValidation_lastUnitSource,
- incrementalResolutionValidation_lastLibrarySource);
- if (fullUnit != null) {
- try {
- assertSameResolution(
- incrementalResolutionValidation_lastUnit, fullUnit);
- } on IncrementalResolutionMismatch catch (mismatch, stack) {
- String failure = mismatch.message;
- String message =
- 'Incremental resolution mismatch:\n$failure\nat\n$stack';
- AnalysisEngine.instance.logger.logError(message);
- }
- }
- incrementalResolutionValidation_lastUnitSource = null;
- incrementalResolutionValidation_lastLibrarySource = null;
- incrementalResolutionValidation_lastUnit = null;
- }
-}
-
-/**
- * An object used by an analysis context to record the results of a task.
- */
-class AnalysisContextImpl_AnalysisTaskResultRecorder
- implements AnalysisTaskVisitor<SourceEntry> {
- final AnalysisContextImpl AnalysisContextImpl_this;
-
- AnalysisContextImpl_AnalysisTaskResultRecorder(this.AnalysisContextImpl_this);
-
- @override
- DartEntry visitGenerateDartErrorsTask(GenerateDartErrorsTask task) =>
- AnalysisContextImpl_this._recordGenerateDartErrorsTask(task);
-
- @override
- DartEntry visitGenerateDartHintsTask(GenerateDartHintsTask task) =>
- AnalysisContextImpl_this._recordGenerateDartHintsTask(task);
-
- @override
- DartEntry visitGenerateDartLintsTask(GenerateDartLintsTask task) =>
- AnalysisContextImpl_this._recordGenerateDartLintsTask(task);
-
- @override
- SourceEntry visitGetContentTask(GetContentTask task) =>
- AnalysisContextImpl_this._recordGetContentsTask(task);
-
- @override
- DartEntry visitIncrementalAnalysisTask(IncrementalAnalysisTask task) =>
- AnalysisContextImpl_this._recordIncrementalAnalysisTaskResults(task);
-
- @override
- DartEntry visitParseDartTask(ParseDartTask task) =>
- AnalysisContextImpl_this._recordParseDartTaskResults(task);
-
- @override
- HtmlEntry visitParseHtmlTask(ParseHtmlTask task) =>
- AnalysisContextImpl_this._recordParseHtmlTaskResults(task);
-
- @override
- DartEntry visitResolveDartLibraryCycleTask(
- ResolveDartLibraryCycleTask task) =>
- AnalysisContextImpl_this.recordResolveDartLibraryCycleTaskResults(task);
-
- @override
- DartEntry visitResolveDartLibraryTask(ResolveDartLibraryTask task) =>
- AnalysisContextImpl_this.recordResolveDartLibraryTaskResults(task);
-
- @override
- DartEntry visitResolveDartUnitTask(ResolveDartUnitTask task) =>
- AnalysisContextImpl_this._recordResolveDartUnitTaskResults(task);
-
- @override
- HtmlEntry visitResolveHtmlTask(ResolveHtmlTask task) =>
- AnalysisContextImpl_this._recordResolveHtmlTaskResults(task);
-
- @override
- DartEntry visitScanDartTask(ScanDartTask task) =>
- AnalysisContextImpl_this._recordScanDartTaskResults(task);
-}
-
-class AnalysisContextImpl_ContextRetentionPolicy
- implements CacheRetentionPolicy {
- final AnalysisContextImpl AnalysisContextImpl_this;
-
- AnalysisContextImpl_ContextRetentionPolicy(this.AnalysisContextImpl_this);
-
- @override
- RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry) {
- int priorityCount = AnalysisContextImpl_this._priorityOrder.length;
- for (int i = 0; i < priorityCount; i++) {
- if (source == AnalysisContextImpl_this._priorityOrder[i]) {
- return RetentionPriority.HIGH;
- }
- }
- if (AnalysisContextImpl_this._neededForResolution != null &&
- AnalysisContextImpl_this._neededForResolution.contains(source)) {
- return RetentionPriority.HIGH;
- }
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry;
- if (_astIsNeeded(dartEntry)) {
- return RetentionPriority.MEDIUM;
- }
- }
- return RetentionPriority.LOW;
- }
-
- bool _astIsNeeded(DartEntry dartEntry) =>
- dartEntry.hasInvalidData(DartEntry.HINTS) ||
- dartEntry.hasInvalidData(DartEntry.LINTS) ||
- dartEntry.hasInvalidData(DartEntry.VERIFICATION_ERRORS) ||
- dartEntry.hasInvalidData(DartEntry.RESOLUTION_ERRORS);
-}
-
-/**
- * An object used to construct a list of the libraries that must be resolved
- * together in order to resolve any one of the libraries.
- */
-class AnalysisContextImpl_CycleBuilder {
- final AnalysisContextImpl AnalysisContextImpl_this;
-
- /**
- * A table mapping the sources of the defining compilation units of libraries
- * to the representation of the library that has the information needed to
- * resolve the library.
- */
- HashMap<Source, ResolvableLibrary> _libraryMap =
- new HashMap<Source, ResolvableLibrary>();
-
- /**
- * The dependency graph used to compute the libraries in the cycle.
- */
- DirectedGraph<ResolvableLibrary> _dependencyGraph;
-
- /**
- * A list containing the libraries that are ready to be resolved.
- */
- List<ResolvableLibrary> _librariesInCycle;
-
- /**
- * The analysis task that needs to be performed before the cycle of libraries
- * can be resolved, or `null` if the libraries are ready to be resolved.
- */
- AnalysisContextImpl_TaskData _taskData;
-
- /**
- * Initialize a newly created cycle builder.
- */
- AnalysisContextImpl_CycleBuilder(this.AnalysisContextImpl_this) : super();
-
- /**
- * Return a list containing the libraries that are ready to be resolved
- * (assuming that [getTaskData] returns `null`).
- */
- List<ResolvableLibrary> get librariesInCycle => _librariesInCycle;
-
- /**
- * Return a representation of an analysis task that needs to be performed
- * before the cycle of libraries can be resolved, or `null` if the libraries
- * are ready to be resolved.
- */
- AnalysisContextImpl_TaskData get taskData => _taskData;
-
- /**
- * Compute a list of the libraries that need to be resolved together in orde
- * to resolve the given [librarySource].
- */
- void computeCycleContaining(Source librarySource) {
- //
- // Create the object representing the library being resolved.
- //
- ResolvableLibrary targetLibrary = _createLibrary(librarySource);
- //
- // Compute the set of libraries that need to be resolved together.
- //
- _dependencyGraph = new DirectedGraph<ResolvableLibrary>();
- _computeLibraryDependencies(targetLibrary);
- if (_taskData != null) {
- return;
- }
- _librariesInCycle = _dependencyGraph.findCycleContaining(targetLibrary);
- //
- // Ensure that all of the data needed to resolve them has been computed.
- //
- _ensureImportsAndExports();
- if (_taskData != null) {
- // At least one imported library needs to be resolved before the target
- // library.
- AnalysisTask task = _taskData.task;
- if (task is ResolveDartLibraryTask) {
- AnalysisContextImpl_this._workManager
- .addFirst(task.librarySource, SourcePriority.LIBRARY);
- }
- return;
- }
- _computePartsInCycle(librarySource);
- if (_taskData != null) {
- // At least one part needs to be parsed.
- return;
- }
- // All of the AST's necessary to perform a resolution of the library cycle
- // have been gathered, so it is no longer necessary to retain them in the
- // cache.
- AnalysisContextImpl_this._neededForResolution = null;
- }
-
- bool _addDependency(ResolvableLibrary dependant, Source dependency,
- List<ResolvableLibrary> dependencyList) {
- if (dependant.librarySource == dependency) {
- // Don't add a dependency of a library on itself; there's no point.
- return true;
- }
- ResolvableLibrary importedLibrary = _libraryMap[dependency];
- if (importedLibrary == null) {
- importedLibrary = _createLibraryOrNull(dependency);
- if (importedLibrary != null) {
- _computeLibraryDependencies(importedLibrary);
- if (_taskData != null) {
- return false;
- }
- }
- }
- if (importedLibrary != null) {
- if (dependencyList != null) {
- dependencyList.add(importedLibrary);
- }
- _dependencyGraph.addEdge(dependant, importedLibrary);
- }
- return true;
- }
-
- /**
- * Recursively traverse the libraries reachable from the given [library],
- * creating instances of the class [Library] to represent them, and record the
- * references in the library objects.
- *
- * Throws an [AnalysisException] if some portion of the library graph could
- * not be traversed.
- */
- void _computeLibraryDependencies(ResolvableLibrary library) {
- Source librarySource = library.librarySource;
- DartEntry dartEntry =
- AnalysisContextImpl_this._getReadableDartEntry(librarySource);
- List<Source> importedSources =
- _getSources(librarySource, dartEntry, DartEntry.IMPORTED_LIBRARIES);
- if (_taskData != null) {
- return;
- }
- List<Source> exportedSources =
- _getSources(librarySource, dartEntry, DartEntry.EXPORTED_LIBRARIES);
- if (_taskData != null) {
- return;
- }
- _computeLibraryDependenciesFromDirectives(
- library, importedSources, exportedSources);
- }
-
- /**
- * Recursively traverse the libraries reachable from the given [library],
- * creating instances of the class [Library] to represent them, and record the
- * references in the library objects. The [importedSources] is a list
- * containing the sources that are imported into the given library. The
- * [exportedSources] is a list containing the sources that are exported from
- * the given library.
- */
- void _computeLibraryDependenciesFromDirectives(ResolvableLibrary library,
- List<Source> importedSources, List<Source> exportedSources) {
- int importCount = importedSources.length;
- List<ResolvableLibrary> importedLibraries = new List<ResolvableLibrary>();
- bool explicitlyImportsCore = false;
- bool importsAsync = false;
- for (int i = 0; i < importCount; i++) {
- Source importedSource = importedSources[i];
- if (importedSource == AnalysisContextImpl_this._coreLibrarySource) {
- explicitlyImportsCore = true;
- } else if (importedSource ==
- AnalysisContextImpl_this._asyncLibrarySource) {
- importsAsync = true;
- }
- if (!_addDependency(library, importedSource, importedLibraries)) {
- return;
- }
- }
- library.explicitlyImportsCore = explicitlyImportsCore;
- if (!explicitlyImportsCore) {
- if (!_addDependency(library, AnalysisContextImpl_this._coreLibrarySource,
- importedLibraries)) {
- return;
- }
- }
- if (!importsAsync) {
- // Add a dependency on async to ensure that the Future element will be
- // built before we generate errors and warnings for async methods. Also
- // include it in importedLibraries, so that it will be picked up by
- // LibraryResolver2._buildLibraryMap().
- // TODO(paulberry): this is a bit of a hack, since the async library
- // isn't actually being imported. Also, it's not clear whether it should
- // be necessary: in theory, dart:core already (indirectly) imports
- // dart:async, so if core has been built, async should have been built
- // too. However, removing this code causes unit test failures.
- if (!_addDependency(library, AnalysisContextImpl_this._asyncLibrarySource,
- importedLibraries)) {
- return;
- }
- }
- library.importedLibraries = importedLibraries;
- int exportCount = exportedSources.length;
- if (exportCount > 0) {
- List<ResolvableLibrary> exportedLibraries = new List<ResolvableLibrary>();
- for (int i = 0; i < exportCount; i++) {
- Source exportedSource = exportedSources[i];
- if (!_addDependency(library, exportedSource, exportedLibraries)) {
- return;
- }
- }
- library.exportedLibraries = exportedLibraries;
- }
- }
-
- /**
- * Gather the resolvable AST structures for each of the compilation units in
- * each of the libraries in the cycle. This is done in two phases: first we
- * ensure that we have cached an AST structure for each compilation unit, then
- * we gather them. We split the work this way because getting the AST
- * structures can change the state of the cache in such a way that we would
- * have more work to do if any compilation unit didn't have a resolvable AST
- * structure.
- */
- void _computePartsInCycle(Source librarySource) {
- int count = _librariesInCycle.length;
- List<CycleBuilder_LibraryPair> libraryData =
- new List<CycleBuilder_LibraryPair>();
- for (int i = 0; i < count; i++) {
- ResolvableLibrary library = _librariesInCycle[i];
- libraryData.add(new CycleBuilder_LibraryPair(
- library, _ensurePartsInLibrary(library)));
- }
- AnalysisContextImpl_this._neededForResolution = _gatherSources(libraryData);
- if (AnalysisContextImpl._TRACE_PERFORM_TASK) {
- print(
- " preserve resolution data for ${AnalysisContextImpl_this._neededForResolution.length} sources while resolving ${librarySource.fullName}");
- }
- if (_taskData != null) {
- return;
- }
- for (int i = 0; i < count; i++) {
- _computePartsInLibrary(libraryData[i]);
- }
- }
-
- /**
- * Gather the resolvable compilation units for each of the compilation units
- * in the library represented by the [libraryPair].
- */
- void _computePartsInLibrary(CycleBuilder_LibraryPair libraryPair) {
- ResolvableLibrary library = libraryPair.library;
- List<CycleBuilder_SourceEntryPair> entryPairs = libraryPair.entryPairs;
- int count = entryPairs.length;
- List<ResolvableCompilationUnit> units =
- new List<ResolvableCompilationUnit>(count);
- for (int i = 0; i < count; i++) {
- CycleBuilder_SourceEntryPair entryPair = entryPairs[i];
- Source source = entryPair.source;
- DartEntry dartEntry = entryPair.entry;
- units[i] = new ResolvableCompilationUnit(
- source, dartEntry.resolvableCompilationUnit);
- }
- library.resolvableCompilationUnits = units;
- }
-
- /**
- * Create an object to represent the information about the library defined by
- * the compilation unit with the given [librarySource].
- */
- ResolvableLibrary _createLibrary(Source librarySource) {
- ResolvableLibrary library = new ResolvableLibrary(librarySource);
- SourceEntry sourceEntry =
- AnalysisContextImpl_this._cache.get(librarySource);
- if (sourceEntry is DartEntry) {
- LibraryElementImpl libraryElement =
- sourceEntry.getValue(DartEntry.ELEMENT) as LibraryElementImpl;
- if (libraryElement != null) {
- library.libraryElement = libraryElement;
- }
- }
- _libraryMap[librarySource] = library;
- return library;
- }
-
- /**
- * Create an object to represent the information about the library defined by
- * the compilation unit with the given [librarySource].
- */
- ResolvableLibrary _createLibraryOrNull(Source librarySource) {
- ResolvableLibrary library = new ResolvableLibrary(librarySource);
- SourceEntry sourceEntry =
- AnalysisContextImpl_this._cache.get(librarySource);
- if (sourceEntry is DartEntry) {
- LibraryElementImpl libraryElement =
- sourceEntry.getValue(DartEntry.ELEMENT) as LibraryElementImpl;
- if (libraryElement != null) {
- library.libraryElement = libraryElement;
- }
- }
- _libraryMap[librarySource] = library;
- return library;
- }
-
- /**
- * Ensure that the given [library] has an element model built for it. If
- * another task needs to be executed first in order to build the element
- * model, that task is placed in [taskData].
- */
- void _ensureElementModel(ResolvableLibrary library) {
- Source librarySource = library.librarySource;
- DartEntry libraryEntry =
- AnalysisContextImpl_this._getReadableDartEntry(librarySource);
- if (libraryEntry != null &&
- libraryEntry.getState(DartEntry.PARSED_UNIT) != CacheState.ERROR) {
- AnalysisContextImpl_this._workManager
- .addFirst(librarySource, SourcePriority.LIBRARY);
- if (_taskData == null) {
- _taskData = AnalysisContextImpl_this._createResolveDartLibraryTask(
- librarySource, libraryEntry);
- }
- }
- }
-
- /**
- * Ensure that all of the libraries that are exported by the given [library]
- * (but are not themselves in the cycle) have element models built for them.
- * If another task needs to be executed first in order to build the element
- * model, that task is placed in [taskData].
- */
- void _ensureExports(
- ResolvableLibrary library, HashSet<Source> visitedLibraries) {
- List<ResolvableLibrary> dependencies = library.exports;
- int dependencyCount = dependencies.length;
- for (int i = 0; i < dependencyCount; i++) {
- ResolvableLibrary dependency = dependencies[i];
- if (!_librariesInCycle.contains(dependency) &&
- visitedLibraries.add(dependency.librarySource)) {
- if (dependency.libraryElement == null) {
- _ensureElementModel(dependency);
- } else {
- _ensureExports(dependency, visitedLibraries);
- }
- if (_taskData != null) {
- return;
- }
- }
- }
- }
-
- /**
- * Ensure that all of the libraries that are exported by the given [library]
- * (but are not themselves in the cycle) have element models built for them.
- * If another task needs to be executed first in order to build the element
- * model, that task is placed in [taskData].
- */
- void _ensureImports(ResolvableLibrary library) {
- List<ResolvableLibrary> dependencies = library.imports;
- int dependencyCount = dependencies.length;
- for (int i = 0; i < dependencyCount; i++) {
- ResolvableLibrary dependency = dependencies[i];
- if (!_librariesInCycle.contains(dependency) &&
- dependency.libraryElement == null) {
- _ensureElementModel(dependency);
- if (_taskData != null) {
- return;
- }
- }
- }
- }
-
- /**
- * Ensure that all of the libraries that are either imported or exported by
- * libraries in the cycle (but are not themselves in the cycle) have element
- * models built for them.
- */
- void _ensureImportsAndExports() {
- HashSet<Source> visitedLibraries = new HashSet<Source>();
- int libraryCount = _librariesInCycle.length;
- for (int i = 0; i < libraryCount; i++) {
- ResolvableLibrary library = _librariesInCycle[i];
- _ensureImports(library);
- if (_taskData != null) {
- return;
- }
- _ensureExports(library, visitedLibraries);
- if (_taskData != null) {
- return;
- }
- }
- }
-
- /**
- * Ensure that there is a resolvable compilation unit available for all of the
- * compilation units in the given [library].
- */
- List<CycleBuilder_SourceEntryPair> _ensurePartsInLibrary(
- ResolvableLibrary library) {
- List<CycleBuilder_SourceEntryPair> pairs =
- new List<CycleBuilder_SourceEntryPair>();
- Source librarySource = library.librarySource;
- DartEntry libraryEntry =
- AnalysisContextImpl_this._getReadableDartEntry(librarySource);
- if (libraryEntry == null) {
- throw new AnalysisException(
- "Cannot find entry for ${librarySource.fullName}");
- } else if (libraryEntry.getState(DartEntry.PARSED_UNIT) ==
- CacheState.ERROR) {
- String message =
- "Cannot compute parsed unit for ${librarySource.fullName}";
- CaughtException exception = libraryEntry.exception;
- if (exception == null) {
- throw new AnalysisException(message);
- }
- throw new AnalysisException(
- message, new CaughtException(exception, null));
- }
- _ensureResolvableCompilationUnit(librarySource, libraryEntry);
- pairs.add(new CycleBuilder_SourceEntryPair(librarySource, libraryEntry));
- List<Source> partSources =
- _getSources(librarySource, libraryEntry, DartEntry.INCLUDED_PARTS);
- int count = partSources.length;
- for (int i = 0; i < count; i++) {
- Source partSource = partSources[i];
- DartEntry partEntry =
- AnalysisContextImpl_this._getReadableDartEntry(partSource);
- if (partEntry != null &&
- partEntry.getState(DartEntry.PARSED_UNIT) != CacheState.ERROR) {
- _ensureResolvableCompilationUnit(partSource, partEntry);
- pairs.add(new CycleBuilder_SourceEntryPair(partSource, partEntry));
- }
- }
- return pairs;
- }
-
- /**
- * Ensure that there is a resolvable compilation unit available for the given
- * [source].
- */
- void _ensureResolvableCompilationUnit(Source source, DartEntry dartEntry) {
- // The entry will be null if the source represents a non-Dart file.
- if (dartEntry != null && !dartEntry.hasResolvableCompilationUnit) {
- if (_taskData == null) {
- _taskData =
- AnalysisContextImpl_this._createParseDartTask(source, dartEntry);
- }
- }
- }
-
- HashSet<Source> _gatherSources(List<CycleBuilder_LibraryPair> libraryData) {
- int libraryCount = libraryData.length;
- HashSet<Source> sources = new HashSet<Source>();
- for (int i = 0; i < libraryCount; i++) {
- List<CycleBuilder_SourceEntryPair> entryPairs = libraryData[i].entryPairs;
- int entryCount = entryPairs.length;
- for (int j = 0; j < entryCount; j++) {
- sources.add(entryPairs[j].source);
- }
- }
- return sources;
- }
-
- /**
- * Return the sources described by the given [descriptor].
- */
- List<Source> _getSources(Source source, DartEntry dartEntry,
- DataDescriptor<List<Source>> descriptor) {
- if (dartEntry == null) {
- return Source.EMPTY_LIST;
- }
- CacheState exportState = dartEntry.getState(descriptor);
- if (exportState == CacheState.ERROR) {
- return Source.EMPTY_LIST;
- } else if (exportState != CacheState.VALID) {
- if (_taskData == null) {
- _taskData =
- AnalysisContextImpl_this._createParseDartTask(source, dartEntry);
- }
- return Source.EMPTY_LIST;
- }
- return dartEntry.getValue(descriptor);
- }
-}
-
-/**
- * Information about the next task to be performed. Each data has an implicit
- * associated source: the source that might need to be analyzed. There are
- * essentially three states that can be represented:
- *
- * * If [getTask] returns a non-`null` value, then that is the task that should
- * be executed to further analyze the associated source.
- * * Otherwise, if [isBlocked] returns `true`, then there is no work that can be
- * done, but analysis for the associated source is not complete.
- * * Otherwise, [getDependentSource] should return a source that needs to be
- * analyzed before the analysis of the associated source can be completed.
- */
-class AnalysisContextImpl_TaskData {
- /**
- * The task that is to be performed.
- */
- final AnalysisTask task;
-
- /**
- * A flag indicating whether the associated source is blocked waiting for its
- * contents to be loaded.
- */
- final bool _blocked;
-
- /**
- * Initialize a newly created data holder.
- */
- AnalysisContextImpl_TaskData(this.task, this._blocked);
-
- /**
- * Return `true` if the associated source is blocked waiting for its contents
- * to be loaded.
- */
- bool get isBlocked => _blocked;
-
- @override
- String toString() {
- if (task == null) {
- return "blocked: $_blocked";
- }
- return task.toString();
- }
-}
-
-/**
- * Statistics and information about a single [AnalysisContext].
- */
-abstract class AnalysisContextStatistics {
- /**
- * Return the statistics for each kind of cached data.
- */
- List<AnalysisContextStatistics_CacheRow> get cacheRows;
-
- /**
- * Return the exceptions that caused some entries to have a state of
- * [CacheState.ERROR].
- */
- List<CaughtException> get exceptions;
-
- /**
- * Return information about each of the partitions in the cache.
- */
- List<AnalysisContextStatistics_PartitionData> get partitionData;
-
- /**
- * Return a list containing all of the sources in the cache.
- */
- List<Source> get sources;
-}
-
-/**
- * Information about single piece of data in the cache.
- */
-abstract class AnalysisContextStatistics_CacheRow {
- /**
- * List of possible states which can be queried.
- */
- static const List<CacheState> STATES = const <CacheState>[
- CacheState.ERROR,
- CacheState.FLUSHED,
- CacheState.IN_PROCESS,
- CacheState.INVALID,
- CacheState.VALID
- ];
-
- /**
- * Return the number of entries whose state is [CacheState.ERROR].
- */
- int get errorCount;
-
- /**
- * Return the number of entries whose state is [CacheState.FLUSHED].
- */
- int get flushedCount;
-
- /**
- * Return the number of entries whose state is [CacheState.IN_PROCESS].
- */
- int get inProcessCount;
-
- /**
- * Return the number of entries whose state is [CacheState.INVALID].
- */
- int get invalidCount;
-
- /**
- * Return the name of the data represented by this object.
- */
- String get name;
-
- /**
- * Return the number of entries whose state is [CacheState.VALID].
- */
- int get validCount;
-
- /**
- * Return the number of entries whose state is [state].
- */
- int getCount(CacheState state);
-}
-
-/**
- * Information about a single partition in the cache.
- */
-abstract class AnalysisContextStatistics_PartitionData {
- /**
- * Return the number of entries in the partition that have an AST structure in
- * one state or another.
- */
- int get astCount;
-
- /**
- * Return the total number of entries in the partition.
- */
- int get totalCount;
-}
-
-/**
- * Implementation of the [AnalysisContextStatistics].
- */
-class AnalysisContextStatisticsImpl implements AnalysisContextStatistics {
- Map<String, AnalysisContextStatistics_CacheRow> _dataMap =
- new HashMap<String, AnalysisContextStatistics_CacheRow>();
-
- List<Source> _sources = new List<Source>();
-
- HashSet<CaughtException> _exceptions = new HashSet<CaughtException>();
-
- List<AnalysisContextStatistics_PartitionData> _partitionData;
-
- @override
- List<AnalysisContextStatistics_CacheRow> get cacheRows =>
- _dataMap.values.toList();
-
- @override
- List<CaughtException> get exceptions => new List.from(_exceptions);
-
- @override
- List<AnalysisContextStatistics_PartitionData> get partitionData =>
- _partitionData;
-
- /**
- * Set the partition data returned by this object to the given data.
- */
- void set partitionData(List<AnalysisContextStatistics_PartitionData> data) {
- _partitionData = data;
- }
-
- @override
- List<Source> get sources => _sources;
-
- void addSource(Source source) {
- _sources.add(source);
- }
-
- void _internalPutCacheItem(Source source, SourceEntry dartEntry,
- DataDescriptor rowDesc, CacheState state) {
- String rowName = rowDesc.toString();
- AnalysisContextStatisticsImpl_CacheRowImpl row =
- _dataMap[rowName] as AnalysisContextStatisticsImpl_CacheRowImpl;
- if (row == null) {
- row = new AnalysisContextStatisticsImpl_CacheRowImpl(rowName);
- _dataMap[rowName] = row;
- }
- row._incState(state);
- if (state == CacheState.ERROR) {
- CaughtException exception = dartEntry.exception;
- if (exception != null) {
- _exceptions.add(exception);
- }
- }
- }
-}
-
-class AnalysisContextStatisticsImpl_CacheRowImpl
- implements AnalysisContextStatistics_CacheRow {
- final String name;
-
- Map<CacheState, int> _counts = <CacheState, int>{};
-
- AnalysisContextStatisticsImpl_CacheRowImpl(this.name);
-
- @override
- int get errorCount => getCount(CacheState.ERROR);
-
- @override
- int get flushedCount => getCount(CacheState.FLUSHED);
-
- @override
- int get hashCode => name.hashCode;
-
- @override
- int get inProcessCount => getCount(CacheState.IN_PROCESS);
-
- @override
- int get invalidCount => getCount(CacheState.INVALID);
-
- @override
- int get validCount => getCount(CacheState.VALID);
-
- @override
- bool operator ==(Object obj) =>
- obj is AnalysisContextStatisticsImpl_CacheRowImpl && obj.name == name;
-
- @override
- int getCount(CacheState state) {
- int count = _counts[state];
- if (count != null) {
- return count;
- } else {
- return 0;
- }
- }
-
- void _incState(CacheState state) {
- if (_counts[state] == null) {
- _counts[state] = 1;
- } else {
- _counts[state]++;
- }
- }
-}
-
-class AnalysisContextStatisticsImpl_PartitionDataImpl
- implements AnalysisContextStatistics_PartitionData {
- final int astCount;
-
- final int totalCount;
-
- AnalysisContextStatisticsImpl_PartitionDataImpl(
- this.astCount, this.totalCount);
-}
-
-/**
* A representation of changes to the types of analysis that should be
* performed.
*/
@@ -5931,39 +762,17 @@
InstrumentationService.NULL_SERVICE;
/**
- * The list of supported plugins for processing by clients.
- */
- List<Plugin> _supportedPlugins;
-
- /**
* The partition manager being used to manage the shared partitions.
*/
final PartitionManager partitionManager = new PartitionManager();
/**
- * The partition manager being used to manage the shared partitions.
- */
- final newContext.PartitionManager partitionManager_new =
- new newContext.PartitionManager();
-
- /**
- * A flag indicating whether the (new) task model should be used to perform
- * analysis.
- */
- bool useTaskModel = true;
-
- /**
* A flag indicating whether the task model should attempt to limit
* invalidation after a change.
*/
bool limitInvalidationInTaskModel = false;
/**
- * The plugins that are defined outside the `analyzer` package.
- */
- List<Plugin> _userDefinedPlugins = <Plugin>[];
-
- /**
* The task manager used to manage the tasks used to analyze code.
*/
TaskManager _taskManager;
@@ -6003,26 +812,21 @@
}
/**
- * Return the list of supported plugins for processing by clients.
+ * Return the list of plugins that clients are required to process, either by
+ * creating an [ExtensionManager] or by using the method
+ * [processRequiredPlugins].
*/
- List<Plugin> get supportedPlugins {
- if (_supportedPlugins == null) {
- _supportedPlugins = <Plugin>[
- enginePlugin,
- commandLinePlugin,
- optionsPlugin
- ];
- _supportedPlugins.addAll(_userDefinedPlugins);
- }
- return _supportedPlugins;
- }
+ List<Plugin> get requiredPlugins => <Plugin>[enginePlugin];
/**
* Return the task manager used to manage the tasks used to analyze code.
*/
TaskManager get taskManager {
if (_taskManager == null) {
- new ExtensionManager().processPlugins(supportedPlugins);
+ if (enginePlugin.taskExtensionPoint == null) {
+ throw new IllegalStateException(
+ 'The analysis engine plugin has not been registered');
+ }
_taskManager = new TaskManager();
_taskManager.addTaskDescriptors(enginePlugin.taskDescriptors);
// TODO(brianwilkerson) Create a way to associate different results with
@@ -6033,18 +837,6 @@
}
/**
- * Set plugins that are defined outside the `analyzer` package.
- */
- void set userDefinedPlugins(List<Plugin> plugins) {
- if (plugins == null) {
- plugins = <Plugin>[];
- }
- _userDefinedPlugins = plugins;
- _supportedPlugins = null;
- _taskManager = null;
- }
-
- /**
* Clear any caches holding on to analysis results so that a full re-analysis
* will be performed the next time an analysis context is created.
*/
@@ -6056,13 +848,20 @@
* Create and return a new context in which analysis can be performed.
*/
AnalysisContext createAnalysisContext() {
- if (useTaskModel) {
- return new newContext.AnalysisContextImpl();
- }
return new AnalysisContextImpl();
}
/**
+ * A utility method that clients can use to process all of the required
+ * plugins. This method can only be used by clients that do not need to
+ * process any other plugins.
+ */
+ void processRequiredPlugins() {
+ ExtensionManager manager = new ExtensionManager();
+ manager.processPlugins(AnalysisEngine.instance.requiredPlugins);
+ }
+
+ /**
* Return `true` if the given [fileName] is an analysis options file.
*/
static bool isAnalysisOptionsFileName(String fileName,
@@ -6206,22 +1005,10 @@
void parsedDart(AnalysisContext context, Source source, CompilationUnit unit);
/**
- * Reports that the given HTML [source] was parsed in the given [context].
- */
- @deprecated
- void parsedHtml(AnalysisContext context, Source source, ht.HtmlUnit unit);
-
- /**
* Reports that the given Dart [source] was resolved in the given [context].
*/
void resolvedDart(
AnalysisContext context, Source source, CompilationUnit unit);
-
- /**
- * Reports that the given HTML [source] was resolved in the given [context].
- */
- @deprecated
- void resolvedHtml(AnalysisContext context, Source source, ht.HtmlUnit unit);
}
/**
@@ -6239,18 +1026,6 @@
*/
abstract class AnalysisOptions {
/**
- * If analysis is to parse and analyze all function bodies, return `true`.
- * If analysis is to skip all function bodies, return `false`. If analysis
- * is to parse and analyze function bodies in some sources and not in others,
- * throw an exception.
- *
- * This getter is deprecated; consider using [analyzeFunctionBodiesPredicate]
- * instead.
- */
- @deprecated // Use this.analyzeFunctionBodiesPredicate
- bool get analyzeFunctionBodies;
-
- /**
* Function that returns `true` if analysis is to parse and analyze function
* bodies for a given source.
*/
@@ -6268,22 +1043,14 @@
bool get dart2jsHint;
/**
- * Return `true` if analysis is to include the new async support.
+ * Return `true` to enable custom assert messages (DEP 37).
*/
- @deprecated // Always true
- bool get enableAsync;
+ bool get enableAssertMessage;
/**
- * Return `true` if analysis is to include the new deferred loading support.
+ * Return `true` to enable interface libraries (DEP 40).
*/
- @deprecated // Always true
- bool get enableDeferredLoading;
-
- /**
- * Return `true` if analysis is to include the new enum support.
- */
- @deprecated // Always true
- bool get enableEnum;
+ bool get enableConditionalDirectives;
/**
* Return `true` to enable generic methods (DEP 22).
@@ -6291,12 +1058,6 @@
bool get enableGenericMethods => null;
/**
- * Return `true` to enable null-aware operators (DEP 9).
- */
- @deprecated // Always true
- bool get enableNullAwareOperators;
-
- /**
* Return `true` to strictly follow the specification when generating
* warnings on "call" methods (fixes dartbug.com/21938).
*/
@@ -6370,18 +1131,6 @@
static const int DEFAULT_CACHE_SIZE = 64;
/**
- * The default value for enabling deferred loading.
- */
- @deprecated
- static bool DEFAULT_ENABLE_DEFERRED_LOADING = true;
-
- /**
- * The default value for enabling enum support.
- */
- @deprecated
- static bool DEFAULT_ENABLE_ENUM = true;
-
- /**
* A predicate indicating whether analysis is to parse and analyze function
* bodies.
*/
@@ -6401,6 +1150,17 @@
bool dart2jsHint = false;
/**
+ * A flag indicating whether custom assert messages are to be supported (DEP
+ * 37).
+ */
+ bool enableAssertMessage = false;
+
+ /**
+ * A flag indicating whether interface libraries are to be supported (DEP 40).
+ */
+ bool enableConditionalDirectives = false;
+
+ /**
* A flag indicating whether generic methods are to be supported (DEP 22).
*/
bool enableGenericMethods = false;
@@ -6485,36 +1245,11 @@
* Initialize a newly created set of analysis options to have the same values
* as those in the given set of analysis [options].
*/
- @deprecated // Use new AnalysisOptionsImpl.from(options)
- AnalysisOptionsImpl.con1(AnalysisOptions options) {
- analyzeFunctionBodiesPredicate = options.analyzeFunctionBodiesPredicate;
- cacheSize = options.cacheSize;
- dart2jsHint = options.dart2jsHint;
- enableStrictCallChecks = options.enableStrictCallChecks;
- enableGenericMethods = options.enableGenericMethods;
- enableSuperMixins = options.enableSuperMixins;
- generateImplicitErrors = options.generateImplicitErrors;
- generateSdkErrors = options.generateSdkErrors;
- hint = options.hint;
- incremental = options.incremental;
- incrementalApi = options.incrementalApi;
- incrementalValidation = options.incrementalValidation;
- lint = options.lint;
- preserveComments = options.preserveComments;
- strongMode = options.strongMode;
- if (options is AnalysisOptionsImpl) {
- strongModeHints = options.strongModeHints;
- }
- }
-
- /**
- * Initialize a newly created set of analysis options to have the same values
- * as those in the given set of analysis [options].
- */
AnalysisOptionsImpl.from(AnalysisOptions options) {
analyzeFunctionBodiesPredicate = options.analyzeFunctionBodiesPredicate;
cacheSize = options.cacheSize;
dart2jsHint = options.dart2jsHint;
+ enableAssertMessage = options.enableAssertMessage;
enableStrictCallChecks = options.enableStrictCallChecks;
enableGenericMethods = options.enableGenericMethods;
enableSuperMixins = options.enableSuperMixins;
@@ -6562,42 +1297,6 @@
_analyzeFunctionBodiesPredicate = value;
}
- @deprecated
- @override
- bool get enableAsync => true;
-
- @deprecated
- void set enableAsync(bool enable) {
- // Async support cannot be disabled
- }
-
- @deprecated
- @override
- bool get enableDeferredLoading => true;
-
- @deprecated
- void set enableDeferredLoading(bool enable) {
- // Deferred loading support cannot be disabled
- }
-
- @deprecated
- @override
- bool get enableEnum => true;
-
- @deprecated
- void set enableEnum(bool enable) {
- // Enum support cannot be disabled
- }
-
- @deprecated
- @override
- bool get enableNullAwareOperators => true;
-
- @deprecated
- void set enableNullAwareOperators(bool enable) {
- // Null-aware operator support cannot be disabled
- }
-
/**
* Predicate used for [analyzeFunctionBodiesPredicate] when
* [analyzeFunctionBodies] is set to `true`.
@@ -6662,174 +1361,6 @@
}
/**
- * An analysis task.
- */
-abstract class AnalysisTask {
- /**
- * The context in which the task is to be performed.
- */
- final InternalAnalysisContext context;
-
- /**
- * The exception that was thrown while performing this task, or `null` if the
- * task completed successfully.
- */
- CaughtException _thrownException;
-
- /**
- * Initialize a newly created task to perform analysis within the given
- * [context].
- */
- AnalysisTask(this.context);
-
- /**
- * Return the exception that was thrown while performing this task, or `null`
- * if the task completed successfully.
- */
- CaughtException get exception => _thrownException;
-
- /**
- * Return a textual description of this task.
- */
- String get taskDescription;
-
- /**
- * Use the given [visitor] to visit this task. Throws an [AnalysisException]
- * if the visitor throws the exception.
- */
- accept(AnalysisTaskVisitor visitor);
-
- /**
- * Perform this analysis task, protected by an exception handler. Throws an
- * [AnalysisException] if an exception occurs while performing the task.
- */
- void internalPerform();
-
- /**
- * Perform this analysis task and use the given [visitor] to visit this task
- * after it has completed. Throws an [AnalysisException] if the visitor throws
- * the exception.
- */
- Object perform(AnalysisTaskVisitor visitor) {
- try {
- _safelyPerform();
- } on AnalysisException catch (exception, stackTrace) {
- _thrownException = new CaughtException(exception, stackTrace);
- AnalysisEngine.instance.logger.logInformation(
- "Task failed: $taskDescription",
- new CaughtException(exception, stackTrace));
- }
- return PerformanceStatistics.analysisTaskVisitor
- .makeCurrentWhile(() => accept(visitor));
- }
-
- @override
- String toString() => taskDescription;
-
- /**
- * Perform this analysis task, ensuring that all exceptions are wrapped in an
- * [AnalysisException]. Throws an [AnalysisException] if any exception occurs
- * while performing the task
- */
- void _safelyPerform() {
- try {
- String contextName = context.name;
- if (contextName == null) {
- contextName = 'unnamed';
- }
- AnalysisEngine.instance.instrumentationService
- .logAnalysisTask(contextName, taskDescription);
- internalPerform();
- } on AnalysisException {
- rethrow;
- } catch (exception, stackTrace) {
- throw new AnalysisException(
- exception.toString(), new CaughtException(exception, stackTrace));
- }
- }
-}
-
-/**
- * An object used to visit tasks. While tasks are not structured in any
- * interesting way, this class provides the ability to dispatch to an
- * appropriate method.
- */
-abstract class AnalysisTaskVisitor<E> {
- /**
- * Visit the given [task], returning the result of the visit. This method will
- * throw an AnalysisException if the visitor throws an exception.
- */
- E visitGenerateDartErrorsTask(GenerateDartErrorsTask task);
-
- /**
- * Visit the given [task], returning the result of the visit. This method will
- * throw an AnalysisException if the visitor throws an exception.
- */
- E visitGenerateDartHintsTask(GenerateDartHintsTask task);
-
- /**
- * Visit the given [task], returning the result of the visit. This method will
- * throw an AnalysisException if the visitor throws an exception.
- */
- E visitGenerateDartLintsTask(GenerateDartLintsTask task);
-
- /**
- * Visit the given [task], returning the result of the visit. This method will
- * throw an AnalysisException if the visitor throws an exception.
- */
- E visitGetContentTask(GetContentTask task);
-
- /**
- * Visit the given [task], returning the result of the visit. This method will
- * throw an AnalysisException if the visitor throws an exception.
- */
- E visitIncrementalAnalysisTask(
- IncrementalAnalysisTask incrementalAnalysisTask);
-
- /**
- * Visit the given [task], returning the result of the visit. This method will
- * throw an AnalysisException if the visitor throws an exception.
- */
- E visitParseDartTask(ParseDartTask task);
-
- /**
- * Visit the given [task], returning the result of the visit. This method will
- * throw an AnalysisException if the visitor throws an exception.
- */
- E visitParseHtmlTask(ParseHtmlTask task);
-
- /**
- * Visit the given [task], returning the result of the visit. This method will
- * throw an AnalysisException if the visitor throws an exception.
- */
- E visitResolveDartLibraryCycleTask(ResolveDartLibraryCycleTask task);
-
- /**
- * Visit the given [task], returning the result of the visit. This method will
- * throw an AnalysisException if the visitor throws an exception.
- */
- E visitResolveDartLibraryTask(ResolveDartLibraryTask task);
-
- /**
- * Visit the given [task], returning the result of the visit. This method will
- * throw an AnalysisException if the visitor throws an exception.
- */
- E visitResolveDartUnitTask(ResolveDartUnitTask task);
-
- /**
- * Visit the given [task], returning the result of the visit. This method will
- * throw an AnalysisException if the visitor throws an exception.
- */
- E visitResolveHtmlTask(ResolveHtmlTask task);
-
- /**
- * Visit the given [task], returning the result of the visit. This method will
- * throw an AnalysisException if the visitor throws an exception.
- */
- E visitScanDartTask(ScanDartTask task);
-}
-
-/**
* The result of applying a [ChangeSet] to a [AnalysisContext].
*/
class ApplyChangesStatus {
@@ -6842,262 +1373,6 @@
}
/**
- * A `CachedResult` is a single analysis result that is stored in a
- * [SourceEntry].
- */
-class CachedResult<E> {
- /**
- * The state of the cached value.
- */
- CacheState state;
-
- /**
- * The value being cached, or `null` if there is no value (for example, when
- * the [state] is [CacheState.INVALID].
- */
- E value;
-
- /**
- * Initialize a newly created result holder to represent the value of data
- * described by the given [descriptor].
- */
- CachedResult(DataDescriptor descriptor) {
- state = CacheState.INVALID;
- value = descriptor.defaultValue;
- }
-}
-
-/**
- * A single partition in an LRU cache of information related to analysis.
- */
-abstract class CachePartition {
- /**
- * The context that owns this partition. Multiple contexts can reference a
- * partition, but only one context can own it.
- */
- final InternalAnalysisContext context;
-
- /**
- * The maximum number of sources for which AST structures should be kept in
- * the cache.
- */
- int _maxCacheSize = 0;
-
- /**
- * The policy used to determine which pieces of data to remove from the cache.
- */
- final CacheRetentionPolicy _retentionPolicy;
-
- /**
- * A table mapping the sources belonging to this partition to the information
- * known about those sources.
- */
- HashMap<Source, SourceEntry> _sourceMap = new HashMap<Source, SourceEntry>();
-
- /**
- * A list containing the most recently accessed sources with the most recently
- * used at the end of the list. When more sources are added than the maximum
- * allowed then the least recently used source will be removed and will have
- * it's cached AST structure flushed.
- */
- List<Source> _recentlyUsed;
-
- /**
- * Initialize a newly created cache to maintain at most [maxCacheSize] AST
- * structures in the cache. The cache is owned by the give [context], and the
- * [retentionPolicy] will be used to determine which pieces of data to remove
- * from the cache.
- */
- CachePartition(this.context, this._maxCacheSize, this._retentionPolicy) {
- _recentlyUsed = new List<Source>();
- }
-
- /**
- * Return the number of entries in this partition that have an AST associated
- * with them.
- */
- int get astSize {
- int astSize = 0;
- int count = _recentlyUsed.length;
- for (int i = 0; i < count; i++) {
- Source source = _recentlyUsed[i];
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry is DartEntry) {
- if (sourceEntry.anyParsedCompilationUnit != null) {
- astSize++;
- }
- } else if (sourceEntry is HtmlEntry) {
- if (sourceEntry.anyParsedUnit != null) {
- astSize++;
- }
- }
- }
- return astSize;
- }
-
- /**
- * Return a table mapping the sources known to the context to the information
- * known about the source.
- *
- * <b>Note:</b> This method is only visible for use by [AnalysisCache] and
- * should not be used for any other purpose.
- */
- Map<Source, SourceEntry> get map => _sourceMap;
-
- /**
- * Set the maximum size of the cache to the given [size].
- */
- void set maxCacheSize(int size) {
- _maxCacheSize = size;
- while (_recentlyUsed.length > _maxCacheSize) {
- if (!_flushAstFromCache()) {
- break;
- }
- }
- }
-
- /**
- * Record that the AST associated with the given source was just read from the
- * cache.
- */
- void accessedAst(Source source) {
- if (_recentlyUsed.remove(source)) {
- _recentlyUsed.add(source);
- return;
- }
- while (_recentlyUsed.length >= _maxCacheSize) {
- if (!_flushAstFromCache()) {
- break;
- }
- }
- _recentlyUsed.add(source);
- }
-
- /**
- * Return `true` if the given [source] is contained in this partition.
- */
- bool contains(Source source);
-
- /**
- * Return the entry associated with the given [source].
- */
- SourceEntry get(Source source) => _sourceMap[source];
-
- /**
- * Return an iterator returning all of the map entries mapping sources to
- * cache entries.
- */
- MapIterator<Source, SourceEntry> iterator() =>
- new SingleMapIterator<Source, SourceEntry>(_sourceMap);
-
- /**
- * Associate the given [entry] with the given [source].
- */
- void put(Source source, SourceEntry entry) {
- entry.fixExceptionState();
- _sourceMap[source] = entry;
- }
-
- /**
- * Remove all information related to the given [source] from this partition.
- * Return the entry associated with the source, or `null` if there was cache
- * entry for the source.
- */
- SourceEntry remove(Source source) {
- _recentlyUsed.remove(source);
- return _sourceMap.remove(source);
- }
-
- /**
- * Record that the AST associated with the given [source] was just removed
- * from the cache.
- */
- void removedAst(Source source) {
- _recentlyUsed.remove(source);
- }
-
- /**
- * Return the number of sources that are mapped to cache entries.
- */
- int size() => _sourceMap.length;
-
- /**
- * Record that the AST associated with the given [source] was just stored to
- * the cache.
- */
- void storedAst(Source source) {
- if (_recentlyUsed.contains(source)) {
- return;
- }
- while (_recentlyUsed.length >= _maxCacheSize) {
- if (!_flushAstFromCache()) {
- break;
- }
- }
- _recentlyUsed.add(source);
- }
-
- /**
- * Attempt to flush one AST structure from the cache. Return `true` if a
- * structure was flushed.
- */
- bool _flushAstFromCache() {
- Source removedSource = _removeAstToFlush();
- if (removedSource == null) {
- return false;
- }
- SourceEntry sourceEntry = _sourceMap[removedSource];
- if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry;
- htmlEntry.flushAstStructures();
- } else if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry;
- dartEntry.flushAstStructures();
- }
- return true;
- }
-
- /**
- * Remove and return one source from the list of recently used sources whose
- * AST structure can be flushed from the cache. The source that will be
- * returned will be the source that has been unreferenced for the longest
- * period of time but that is not a priority for analysis.
- */
- Source _removeAstToFlush() {
- int sourceToRemove = -1;
- for (int i = 0; i < _recentlyUsed.length; i++) {
- Source source = _recentlyUsed[i];
- RetentionPriority priority =
- _retentionPolicy.getAstPriority(source, _sourceMap[source]);
- if (priority == RetentionPriority.LOW) {
- return _recentlyUsed.removeAt(i);
- } else if (priority == RetentionPriority.MEDIUM && sourceToRemove < 0) {
- sourceToRemove = i;
- }
- }
- if (sourceToRemove < 0) {
- // This happens if the retention policy returns a priority of HIGH for all
- // of the sources that have been recently used. This is the case, for
- // example, when the list of priority sources is bigger than the current
- // cache size.
- return null;
- }
- return _recentlyUsed.removeAt(sourceToRemove);
- }
-}
-
-/**
- * An object used to determine how important it is for data to be retained in
- * the analysis cache.
- */
-abstract class CacheRetentionPolicy {
- /**
- * Return the priority of retaining the AST structure for the given [source].
- */
- RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry);
-}
-
-/**
* The possible states of cached data.
*/
class CacheState extends Enum<CacheState> {
@@ -7182,13 +1457,6 @@
CompilationUnit get resolvedDartUnit;
/**
- * The fully resolved HTML AST that changed as a result of the analysis, or
- * `null` if the AST was not changed.
- */
- @deprecated
- ht.HtmlUnit get resolvedHtmlUnit;
-
- /**
* Return the source for which the result is being reported.
*/
Source get source;
@@ -7221,13 +1489,6 @@
CompilationUnit resolvedDartUnit;
/**
- * The fully resolved HTML AST that changed as a result of the analysis, or
- * `null` if the AST was not changed.
- */
- @deprecated
- ht.HtmlUnit resolvedHtmlUnit;
-
- /**
* The errors that changed as a result of the analysis, or `null` if errors
* were not changed.
*/
@@ -7329,7 +1590,8 @@
/**
* Return `true` if this change set does not contain any changes.
*/
- bool get isEmpty => addedSources.isEmpty &&
+ bool get isEmpty =>
+ addedSources.isEmpty &&
changedSources.isEmpty &&
_changedContent.isEmpty &&
changedRanges.isEmpty &&
@@ -7547,1564 +1809,6 @@
}
/**
- * A pair containing a library and a list of the (source, entry) pairs for
- * compilation units in the library.
- */
-class CycleBuilder_LibraryPair {
- /**
- * The library containing the compilation units.
- */
- ResolvableLibrary library;
-
- /**
- * The (source, entry) pairs representing the compilation units in the
- * library.
- */
- List<CycleBuilder_SourceEntryPair> entryPairs;
-
- /**
- * Initialize a newly created pair from the given [library] and [entryPairs].
- */
- CycleBuilder_LibraryPair(this.library, this.entryPairs);
-}
-
-/**
- * A pair containing a source and the cache entry associated with that source.
- * They are used to reduce the number of times an entry must be looked up in the
- * cache.
- */
-class CycleBuilder_SourceEntryPair {
- /**
- * The source associated with the entry.
- */
- Source source;
-
- /**
- * The entry associated with the source.
- */
- DartEntry entry;
-
- /**
- * Initialize a newly created pair from the given [source] and [entry].
- */
- CycleBuilder_SourceEntryPair(this.source, this.entry);
-}
-
-/**
- * The information cached by an analysis context about an individual Dart file.
- */
-class DartEntry extends SourceEntry {
- /**
- * The data descriptor representing the element model representing a single
- * compilation unit. This model is incomplete and should not be used except as
- * input to another task.
- */
- static final DataDescriptor<List<AnalysisError>> BUILT_ELEMENT =
- new DataDescriptor<List<AnalysisError>>("DartEntry.BUILT_ELEMENT");
-
- /**
- * The data descriptor representing the AST structure after the element model
- * has been built (and declarations are resolved) but before other resolution
- * has been performed.
- */
- static final DataDescriptor<CompilationUnit> BUILT_UNIT =
- new DataDescriptor<CompilationUnit>("DartEntry.BUILT_UNIT");
-
- /**
- * The data descriptor representing the list of libraries that contain this
- * compilation unit.
- */
- static final DataDescriptor<List<Source>> CONTAINING_LIBRARIES =
- new DataDescriptor<List<Source>>(
- "DartEntry.CONTAINING_LIBRARIES", Source.EMPTY_LIST);
-
- /**
- * The data descriptor representing the library element for the library. This
- * data is only available for Dart files that are the defining compilation
- * unit of a library.
- */
- static final DataDescriptor<LibraryElement> ELEMENT =
- new DataDescriptor<LibraryElement>("DartEntry.ELEMENT");
-
- /**
- * The data descriptor representing the list of exported libraries. This data
- * is only available for Dart files that are the defining compilation unit of
- * a library.
- */
- static final DataDescriptor<List<Source>> EXPORTED_LIBRARIES =
- new DataDescriptor<List<Source>>(
- "DartEntry.EXPORTED_LIBRARIES", Source.EMPTY_LIST);
-
- /**
- * The data descriptor representing the hints resulting from auditing the
- * source.
- */
- static final DataDescriptor<List<AnalysisError>> HINTS =
- new DataDescriptor<List<AnalysisError>>(
- "DartEntry.HINTS", AnalysisError.NO_ERRORS);
-
- /**
- * The data descriptor representing the list of imported libraries. This data
- * is only available for Dart files that are the defining compilation unit of
- * a library.
- */
- static final DataDescriptor<List<Source>> IMPORTED_LIBRARIES =
- new DataDescriptor<List<Source>>(
- "DartEntry.IMPORTED_LIBRARIES", Source.EMPTY_LIST);
-
- /**
- * The data descriptor representing the list of included parts. This data is
- * only available for Dart files that are the defining compilation unit of a
- * library.
- */
- static final DataDescriptor<List<Source>> INCLUDED_PARTS =
- new DataDescriptor<List<Source>>(
- "DartEntry.INCLUDED_PARTS", Source.EMPTY_LIST);
-
- /**
- * The data descriptor representing the client flag. This data is only
- * available for Dart files that are the defining compilation unit of a
- * library.
- */
- static final DataDescriptor<bool> IS_CLIENT =
- new DataDescriptor<bool>("DartEntry.IS_CLIENT", false);
-
- /**
- * The data descriptor representing the launchable flag. This data is only
- * available for Dart files that are the defining compilation unit of a
- * library.
- */
- static final DataDescriptor<bool> IS_LAUNCHABLE =
- new DataDescriptor<bool>("DartEntry.IS_LAUNCHABLE", false);
-
- /**
- * The data descriptor representing lint warnings resulting from auditing the
- * source.
- */
- static final DataDescriptor<List<AnalysisError>> LINTS =
- new DataDescriptor<List<AnalysisError>>(
- "DartEntry.LINTS", AnalysisError.NO_ERRORS);
-
- /**
- * The data descriptor representing the errors resulting from parsing the
- * source.
- */
- static final DataDescriptor<List<AnalysisError>> PARSE_ERRORS =
- new DataDescriptor<List<AnalysisError>>(
- "DartEntry.PARSE_ERRORS", AnalysisError.NO_ERRORS);
-
- /**
- * The data descriptor representing the parsed AST structure.
- */
- static final DataDescriptor<CompilationUnit> PARSED_UNIT =
- new DataDescriptor<CompilationUnit>("DartEntry.PARSED_UNIT");
-
- /**
- * The data descriptor representing the public namespace of the library. This
- * data is only available for Dart files that are the defining compilation
- * unit of a library.
- */
- static final DataDescriptor<Namespace> PUBLIC_NAMESPACE =
- new DataDescriptor<Namespace>("DartEntry.PUBLIC_NAMESPACE");
-
- /**
- * The data descriptor representing the errors resulting from resolving the
- * source.
- */
- static final DataDescriptor<List<AnalysisError>> RESOLUTION_ERRORS =
- new DataDescriptor<List<AnalysisError>>(
- "DartEntry.RESOLUTION_ERRORS", AnalysisError.NO_ERRORS);
-
- /**
- * The data descriptor representing the resolved AST structure.
- */
- static final DataDescriptor<CompilationUnit> RESOLVED_UNIT =
- new DataDescriptor<CompilationUnit>("DartEntry.RESOLVED_UNIT");
-
- /**
- * The data descriptor representing the errors resulting from scanning the
- * source.
- */
- static final DataDescriptor<List<AnalysisError>> SCAN_ERRORS =
- new DataDescriptor<List<AnalysisError>>(
- "DartEntry.SCAN_ERRORS", AnalysisError.NO_ERRORS);
-
- /**
- * The data descriptor representing the source kind.
- */
- static final DataDescriptor<SourceKind> SOURCE_KIND =
- new DataDescriptor<SourceKind>(
- "DartEntry.SOURCE_KIND", SourceKind.UNKNOWN);
-
- /**
- * The data descriptor representing the token stream.
- */
- static final DataDescriptor<Token> TOKEN_STREAM =
- new DataDescriptor<Token>("DartEntry.TOKEN_STREAM");
-
- /**
- * The data descriptor representing the errors resulting from verifying the
- * source.
- */
- static final DataDescriptor<List<AnalysisError>> VERIFICATION_ERRORS =
- new DataDescriptor<List<AnalysisError>>(
- "DartEntry.VERIFICATION_ERRORS", AnalysisError.NO_ERRORS);
-
- /**
- * The list of libraries that contain this compilation unit. The list will be
- * empty if there are no known libraries that contain this compilation unit.
- */
- List<Source> _containingLibraries = new List<Source>();
-
- /**
- * The information known as a result of resolving this compilation unit as
- * part of the library that contains this unit. This field will never be
- * `null`.
- */
- ResolutionState _resolutionState = new ResolutionState();
-
- /**
- * Return all of the errors associated with the compilation unit that are
- * currently cached.
- */
- List<AnalysisError> get allErrors {
- List<AnalysisError> errors = new List<AnalysisError>();
- errors.addAll(super.allErrors);
- errors.addAll(getValue(SCAN_ERRORS));
- errors.addAll(getValue(PARSE_ERRORS));
- ResolutionState state = _resolutionState;
- while (state != null) {
- errors.addAll(state.getValue(RESOLUTION_ERRORS));
- errors.addAll(state.getValue(VERIFICATION_ERRORS));
- errors.addAll(state.getValue(HINTS));
- errors.addAll(state.getValue(LINTS));
- state = state._nextState;
- }
- if (errors.length == 0) {
- return AnalysisError.NO_ERRORS;
- }
- return errors;
- }
-
- /**
- * Return a valid parsed compilation unit, either an unresolved AST structure
- * or the result of resolving the AST structure in the context of some
- * library, or `null` if there is no parsed compilation unit available.
- */
- CompilationUnit get anyParsedCompilationUnit {
- if (getState(PARSED_UNIT) == CacheState.VALID) {
- return getValue(PARSED_UNIT);
- }
- ResolutionState state = _resolutionState;
- while (state != null) {
- if (state.getState(BUILT_UNIT) == CacheState.VALID) {
- return state.getValue(BUILT_UNIT);
- }
- state = state._nextState;
- }
-
- return anyResolvedCompilationUnit;
- }
-
- /**
- * Return the result of resolving the compilation unit as part of any library,
- * or `null` if there is no cached resolved compilation unit.
- */
- CompilationUnit get anyResolvedCompilationUnit {
- ResolutionState state = _resolutionState;
- while (state != null) {
- if (state.getState(RESOLVED_UNIT) == CacheState.VALID) {
- return state.getValue(RESOLVED_UNIT);
- }
- state = state._nextState;
- }
- return null;
- }
-
- /**
- * The libraries that are known to contain this part.
- */
- List<Source> get containingLibraries => _containingLibraries;
-
- /**
- * Set the list of libraries that contain this compilation unit to contain
- * only the given [librarySource]. This method should only be invoked on
- * entries that represent a library.
- */
- void set containingLibrary(Source librarySource) {
- _containingLibraries.clear();
- _containingLibraries.add(librarySource);
- }
-
- @override
- List<DataDescriptor> get descriptors {
- List<DataDescriptor> result = super.descriptors;
- result.addAll(<DataDescriptor>[
- DartEntry.SOURCE_KIND,
- DartEntry.CONTAINING_LIBRARIES,
- DartEntry.PARSE_ERRORS,
- DartEntry.PARSED_UNIT,
- DartEntry.SCAN_ERRORS,
- DartEntry.SOURCE_KIND,
- DartEntry.TOKEN_STREAM
- ]);
- SourceKind kind = getValue(DartEntry.SOURCE_KIND);
- if (kind == SourceKind.LIBRARY) {
- result.addAll(<DataDescriptor>[
- DartEntry.ELEMENT,
- DartEntry.EXPORTED_LIBRARIES,
- DartEntry.IMPORTED_LIBRARIES,
- DartEntry.INCLUDED_PARTS,
- DartEntry.IS_CLIENT,
- DartEntry.IS_LAUNCHABLE,
- DartEntry.PUBLIC_NAMESPACE
- ]);
- }
- return result;
- }
-
- /**
- * Return `true` if this entry has an AST structure that can be resolved, even
- * if it needs to be copied. Returning `true` implies that the method
- * [resolvableCompilationUnit] will return a non-`null` result.
- */
- bool get hasResolvableCompilationUnit {
- if (getState(PARSED_UNIT) == CacheState.VALID) {
- return true;
- }
- ResolutionState state = _resolutionState;
- while (state != null) {
- if (state.getState(BUILT_UNIT) == CacheState.VALID ||
- state.getState(RESOLVED_UNIT) == CacheState.VALID) {
- return true;
- }
- state = state._nextState;
- }
-
- return false;
- }
-
- @override
- SourceKind get kind => getValue(SOURCE_KIND);
-
- /**
- * The library sources containing the receiver's source.
- */
- List<Source> get librariesContaining {
- ResolutionState state = _resolutionState;
- List<Source> result = new List<Source>();
- while (state != null) {
- if (state._librarySource != null) {
- result.add(state._librarySource);
- }
- state = state._nextState;
- }
- return result;
- }
-
- /**
- * Get a list of all the library-dependent descriptors for which values may
- * be stored in this SourceEntry.
- */
- List<DataDescriptor> get libraryDescriptors {
- return <DataDescriptor>[
- DartEntry.BUILT_ELEMENT,
- DartEntry.BUILT_UNIT,
- DartEntry.RESOLUTION_ERRORS,
- DartEntry.RESOLVED_UNIT,
- DartEntry.VERIFICATION_ERRORS,
- DartEntry.HINTS,
- DartEntry.LINTS
- ];
- }
-
- /**
- * A compilation unit that has not been accessed by any other client and can
- * therefore safely be modified by the reconciler, or `null` if the source has
- * not been parsed.
- */
- CompilationUnit get resolvableCompilationUnit {
- if (getState(PARSED_UNIT) == CacheState.VALID) {
- CompilationUnit unit = getValue(PARSED_UNIT);
- setState(PARSED_UNIT, CacheState.FLUSHED);
- return unit;
- }
- ResolutionState state = _resolutionState;
- while (state != null) {
- if (state.getState(BUILT_UNIT) == CacheState.VALID) {
- // TODO(brianwilkerson) We're cloning the structure to remove any
- // previous resolution data, but I'm not sure that's necessary.
- return state.getValue(BUILT_UNIT).accept(new AstCloner());
- }
- if (state.getState(RESOLVED_UNIT) == CacheState.VALID) {
- return state.getValue(RESOLVED_UNIT).accept(new AstCloner());
- }
- state = state._nextState;
- }
- return null;
- }
-
- /**
- * Add the given [librarySource] to the list of libraries that contain this
- * part. This method should only be invoked on entries that represent a part.
- */
- void addContainingLibrary(Source librarySource) {
- _containingLibraries.add(librarySource);
- }
-
- /**
- * Flush any AST structures being maintained by this entry.
- */
- void flushAstStructures() {
- _flush(TOKEN_STREAM);
- _flush(PARSED_UNIT);
- _resolutionState.flushAstStructures();
- }
-
- /**
- * Return the state of the data represented by the given [descriptor] in the
- * context of the given [librarySource].
- */
- CacheState getStateInLibrary(
- DataDescriptor descriptor, Source librarySource) {
- if (!_isValidLibraryDescriptor(descriptor)) {
- throw new ArgumentError("Invalid descriptor: $descriptor");
- }
- ResolutionState state = _resolutionState;
- while (state != null) {
- if (librarySource == state._librarySource) {
- return state.getState(descriptor);
- }
- state = state._nextState;
- }
- return CacheState.INVALID;
- }
-
- /**
- * Return the value of the data represented by the given [descriptor] in the
- * context of the given [librarySource], or `null` if the data represented by
- * the descriptor is not in the cache.
- */
- Object getValueInLibrary(DataDescriptor descriptor, Source librarySource) {
- if (!_isValidLibraryDescriptor(descriptor)) {
- throw new ArgumentError("Invalid descriptor: $descriptor");
- }
- ResolutionState state = _resolutionState;
- while (state != null) {
- if (librarySource == state._librarySource) {
- return state.getValue(descriptor);
- }
- state = state._nextState;
- }
- return descriptor.defaultValue;
- }
-
- /**
- * Return `true` if the data represented by the given [descriptor] is marked
- * as being invalid. If the descriptor represents library-specific data then
- * this method will return `true` if the data associated with any library it
- * marked as invalid.
- */
- bool hasInvalidData(DataDescriptor descriptor) {
- if (_isValidDescriptor(descriptor)) {
- return getState(descriptor) == CacheState.INVALID;
- } else if (_isValidLibraryDescriptor(descriptor)) {
- ResolutionState state = _resolutionState;
- while (state != null) {
- if (state.getState(descriptor) == CacheState.INVALID) {
- return true;
- }
- state = state._nextState;
- }
- }
- return false;
- }
-
- @override
- void invalidateAllInformation() {
- super.invalidateAllInformation();
- setState(SCAN_ERRORS, CacheState.INVALID);
- setState(TOKEN_STREAM, CacheState.INVALID);
- setState(SOURCE_KIND, CacheState.INVALID);
- setState(PARSE_ERRORS, CacheState.INVALID);
- setState(PARSED_UNIT, CacheState.INVALID);
- _discardCachedResolutionInformation(true);
- }
-
- /**
- * Invalidate all of the resolution information associated with the
- * compilation unit. The flag [invalidateUris] should be `true` if the cached
- * results of converting URIs to source files should also be invalidated.
- */
- void invalidateAllResolutionInformation(bool invalidateUris) {
- if (getState(PARSED_UNIT) == CacheState.FLUSHED) {
- ResolutionState state = _resolutionState;
- while (state != null) {
- if (state.getState(BUILT_UNIT) == CacheState.VALID) {
- CompilationUnit unit = state.getValue(BUILT_UNIT);
- setValue(PARSED_UNIT, unit.accept(new AstCloner()));
- break;
- } else if (state.getState(RESOLVED_UNIT) == CacheState.VALID) {
- CompilationUnit unit = state.getValue(RESOLVED_UNIT);
- setValue(PARSED_UNIT, unit.accept(new AstCloner()));
- break;
- }
- state = state._nextState;
- }
- }
- _discardCachedResolutionInformation(invalidateUris);
- }
-
- /**
- * Invalidate all of the parse and resolution information associated with
- * this source.
- */
- void invalidateParseInformation() {
- setState(SOURCE_KIND, CacheState.INVALID);
- setState(PARSE_ERRORS, CacheState.INVALID);
- setState(PARSED_UNIT, CacheState.INVALID);
- _containingLibraries.clear();
- _discardCachedResolutionInformation(true);
- }
-
- /**
- * Record that an [exception] occurred while attempting to build the element
- * model for the source represented by this entry in the context of the given
- * [library]. This will set the state of all resolution-based information as
- * being in error, but will not change the state of any parse results.
- */
- void recordBuildElementErrorInLibrary(
- Source librarySource, CaughtException exception) {
- setStateInLibrary(BUILT_ELEMENT, librarySource, CacheState.ERROR);
- setStateInLibrary(BUILT_UNIT, librarySource, CacheState.ERROR);
- recordResolutionErrorInLibrary(librarySource, exception);
- }
-
- @override
- void recordContentError(CaughtException exception) {
- super.recordContentError(exception);
- recordScanError(exception);
- }
-
- /**
- * Record that an error occurred while attempting to generate hints for the
- * source represented by this entry. This will set the state of all
- * verification information as being in error. The [librarySource] is the
- * source of the library in which hints were being generated. The [exception]
- * is the exception that shows where the error occurred.
- */
- void recordHintErrorInLibrary(
- Source librarySource, CaughtException exception) {
- this.exception = exception;
- ResolutionState state = _getOrCreateResolutionState(librarySource);
- state.recordHintError();
- }
-
- /**
- * Record that an error occurred while attempting to generate lints for the
- * source represented by this entry. This will set the state of all
- * verification information as being in error. The [librarySource] is the
- * source of the library in which lints were being generated. The [exception]
- * is the exception that shows where the error occurred.
- */
- void recordLintErrorInLibrary(
- Source librarySource, CaughtException exception) {
- this.exception = exception;
- ResolutionState state = _getOrCreateResolutionState(librarySource);
- state.recordLintError();
- }
-
- /**
- * Record that an [exception] occurred while attempting to scan or parse the
- * entry represented by this entry. This will set the state of all information,
- * including any resolution-based information, as being in error.
- */
- void recordParseError(CaughtException exception) {
- setState(SOURCE_KIND, CacheState.ERROR);
- setState(PARSE_ERRORS, CacheState.ERROR);
- setState(PARSED_UNIT, CacheState.ERROR);
- setState(EXPORTED_LIBRARIES, CacheState.ERROR);
- setState(IMPORTED_LIBRARIES, CacheState.ERROR);
- setState(INCLUDED_PARTS, CacheState.ERROR);
- recordResolutionError(exception);
- }
-
- /**
- * Record that an [exception] occurred while attempting to resolve the source
- * represented by this entry. This will set the state of all resolution-based
- * information as being in error, but will not change the state of any parse
- * results.
- */
- void recordResolutionError(CaughtException exception) {
- this.exception = exception;
- setState(ELEMENT, CacheState.ERROR);
- setState(IS_CLIENT, CacheState.ERROR);
- setState(IS_LAUNCHABLE, CacheState.ERROR);
- setState(PUBLIC_NAMESPACE, CacheState.ERROR);
- _resolutionState.recordResolutionErrorsInAllLibraries();
- }
-
- /**
- * Record that an error occurred while attempting to resolve the source
- * represented by this entry. This will set the state of all resolution-based
- * information as being in error, but will not change the state of any parse
- * results. The [librarySource] is the source of the library in which
- * resolution was being performed. The [exception] is the exception that shows
- * where the error occurred.
- */
- void recordResolutionErrorInLibrary(
- Source librarySource, CaughtException exception) {
- this.exception = exception;
- setState(ELEMENT, CacheState.ERROR);
- setState(IS_CLIENT, CacheState.ERROR);
- setState(IS_LAUNCHABLE, CacheState.ERROR);
- setState(PUBLIC_NAMESPACE, CacheState.ERROR);
- ResolutionState state = _getOrCreateResolutionState(librarySource);
- state.recordResolutionError();
- }
-
- /**
- * Record that an [exception] occurred while attempting to scan or parse the
- * entry represented by this entry. This will set the state of all
- * information, including any resolution-based information, as being in error.
- */
- @override
- void recordScanError(CaughtException exception) {
- super.recordScanError(exception);
- setState(SCAN_ERRORS, CacheState.ERROR);
- setState(TOKEN_STREAM, CacheState.ERROR);
- recordParseError(exception);
- }
-
- /**
- * Record that an [exception] occurred while attempting to generate errors and
- * warnings for the source represented by this entry. This will set the state
- * of all verification information as being in error. The [librarySource] is
- * the source of the library in which verification was being performed. The
- * [exception] is the exception that shows where the error occurred.
- */
- void recordVerificationErrorInLibrary(
- Source librarySource, CaughtException exception) {
- this.exception = exception;
- ResolutionState state = _getOrCreateResolutionState(librarySource);
- state.recordVerificationError();
- }
-
- /**
- * Remove the given [library] from the list of libraries that contain this
- * part. This method should only be invoked on entries that represent a part.
- */
- void removeContainingLibrary(Source library) {
- _containingLibraries.remove(library);
- }
-
- /**
- * Remove any resolution information associated with this compilation unit
- * being part of the given [library], presumably because it is no longer part
- * of the library.
- */
- void removeResolution(Source library) {
- if (library != null) {
- if (library == _resolutionState._librarySource) {
- if (_resolutionState._nextState == null) {
- _resolutionState.invalidateAllResolutionInformation();
- } else {
- _resolutionState = _resolutionState._nextState;
- }
- } else {
- ResolutionState priorState = _resolutionState;
- ResolutionState state = _resolutionState._nextState;
- while (state != null) {
- if (library == state._librarySource) {
- priorState._nextState = state._nextState;
- break;
- }
- priorState = state;
- state = state._nextState;
- }
- }
- }
- }
-
- /**
- * Set the state of the data represented by the given [descriptor] in the
- * context of the given [library] to the given [state].
- */
- void setStateInLibrary(
- DataDescriptor descriptor, Source library, CacheState state) {
- if (!_isValidLibraryDescriptor(descriptor)) {
- throw new ArgumentError("Invalid descriptor: $descriptor");
- }
- ResolutionState resolutionState = _getOrCreateResolutionState(library);
- resolutionState.setState(descriptor, state);
- }
-
- /**
- * Set the value of the data represented by the given [descriptor] in the
- * context of the given [library] to the given [value], and set the state of
- * that data to [CacheState.VALID].
- */
- void setValueInLibrary(
- DataDescriptor descriptor, Source library, Object value) {
- if (!_isValidLibraryDescriptor(descriptor)) {
- throw new ArgumentError("Invalid descriptor: $descriptor");
- }
- ResolutionState state = _getOrCreateResolutionState(library);
- state.setValue(descriptor, value);
- }
-
- /**
- * Invalidate all of the resolution information associated with the
- * compilation unit. The flag [invalidateUris] should be `true` if the cached
- * results of converting URIs to source files should also be invalidated.
- */
- void _discardCachedResolutionInformation(bool invalidateUris) {
- setState(ELEMENT, CacheState.INVALID);
- setState(IS_CLIENT, CacheState.INVALID);
- setState(IS_LAUNCHABLE, CacheState.INVALID);
- setState(PUBLIC_NAMESPACE, CacheState.INVALID);
- _resolutionState.invalidateAllResolutionInformation();
- if (invalidateUris) {
- setState(EXPORTED_LIBRARIES, CacheState.INVALID);
- setState(IMPORTED_LIBRARIES, CacheState.INVALID);
- setState(INCLUDED_PARTS, CacheState.INVALID);
- }
- }
-
- /**
- * Return a resolution state for the specified [library], creating one as
- * necessary.
- */
- ResolutionState _getOrCreateResolutionState(Source library) {
- ResolutionState state = _resolutionState;
- if (state._librarySource == null) {
- state._librarySource = library;
- return state;
- }
- while (state._librarySource != library) {
- if (state._nextState == null) {
- ResolutionState newState = new ResolutionState();
- newState._librarySource = library;
- state._nextState = newState;
- return newState;
- }
- state = state._nextState;
- }
- return state;
- }
-
- @override
- bool _isValidDescriptor(DataDescriptor descriptor) {
- return descriptor == CONTAINING_LIBRARIES ||
- descriptor == ELEMENT ||
- descriptor == EXPORTED_LIBRARIES ||
- descriptor == IMPORTED_LIBRARIES ||
- descriptor == INCLUDED_PARTS ||
- descriptor == IS_CLIENT ||
- descriptor == IS_LAUNCHABLE ||
- descriptor == PARSED_UNIT ||
- descriptor == PARSE_ERRORS ||
- descriptor == PUBLIC_NAMESPACE ||
- descriptor == SCAN_ERRORS ||
- descriptor == SOURCE_KIND ||
- descriptor == TOKEN_STREAM ||
- super._isValidDescriptor(descriptor);
- }
-
- /**
- * Return `true` if the [descriptor] is valid for this entry when the data is
- * relative to a library.
- */
- bool _isValidLibraryDescriptor(DataDescriptor descriptor) {
- return descriptor == BUILT_ELEMENT ||
- descriptor == BUILT_UNIT ||
- descriptor == HINTS ||
- descriptor == LINTS ||
- descriptor == RESOLUTION_ERRORS ||
- descriptor == RESOLVED_UNIT ||
- descriptor == VERIFICATION_ERRORS;
- }
-
- @override
- bool _writeDiffOn(StringBuffer buffer, SourceEntry oldEntry) {
- bool needsSeparator = super._writeDiffOn(buffer, oldEntry);
- if (oldEntry is! DartEntry) {
- if (needsSeparator) {
- buffer.write("; ");
- }
- buffer.write("entry type changed; was ");
- buffer.write(oldEntry.runtimeType.toString());
- return true;
- }
- needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "tokenStream",
- DartEntry.TOKEN_STREAM, oldEntry);
- needsSeparator = _writeStateDiffOn(
- buffer, needsSeparator, "scanErrors", DartEntry.SCAN_ERRORS, oldEntry);
- needsSeparator = _writeStateDiffOn(
- buffer, needsSeparator, "sourceKind", DartEntry.SOURCE_KIND, oldEntry);
- needsSeparator = _writeStateDiffOn(
- buffer, needsSeparator, "parsedUnit", DartEntry.PARSED_UNIT, oldEntry);
- needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "parseErrors",
- DartEntry.PARSE_ERRORS, oldEntry);
- needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
- "importedLibraries", DartEntry.IMPORTED_LIBRARIES, oldEntry);
- needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
- "exportedLibraries", DartEntry.EXPORTED_LIBRARIES, oldEntry);
- needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "includedParts",
- DartEntry.INCLUDED_PARTS, oldEntry);
- needsSeparator = _writeStateDiffOn(
- buffer, needsSeparator, "element", DartEntry.ELEMENT, oldEntry);
- needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
- "publicNamespace", DartEntry.PUBLIC_NAMESPACE, oldEntry);
- needsSeparator = _writeStateDiffOn(
- buffer, needsSeparator, "clientServer", DartEntry.IS_CLIENT, oldEntry);
- needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "launchable",
- DartEntry.IS_LAUNCHABLE, oldEntry);
- // TODO(brianwilkerson) Add better support for containingLibraries.
- // It would be nice to be able to report on size-preserving changes.
- int oldLibraryCount = (oldEntry as DartEntry)._containingLibraries.length;
- int libraryCount = _containingLibraries.length;
- if (oldLibraryCount != libraryCount) {
- if (needsSeparator) {
- buffer.write("; ");
- }
- buffer.write("containingLibraryCount = ");
- buffer.write(oldLibraryCount);
- buffer.write(" -> ");
- buffer.write(libraryCount);
- needsSeparator = true;
- }
- //
- // Report change to the per-library state.
- //
- HashMap<Source, ResolutionState> oldStateMap =
- new HashMap<Source, ResolutionState>();
- ResolutionState state = (oldEntry as DartEntry)._resolutionState;
- while (state != null) {
- Source librarySource = state._librarySource;
- if (librarySource != null) {
- oldStateMap[librarySource] = state;
- }
- state = state._nextState;
- }
- state = _resolutionState;
- while (state != null) {
- Source librarySource = state._librarySource;
- if (librarySource != null) {
- ResolutionState oldState = oldStateMap.remove(librarySource);
- if (oldState == null) {
- if (needsSeparator) {
- buffer.write("; ");
- }
- buffer.write("added resolution for ");
- buffer.write(librarySource.fullName);
- needsSeparator = true;
- } else {
- needsSeparator = oldState._writeDiffOn(
- buffer, needsSeparator, oldEntry as DartEntry);
- }
- }
- state = state._nextState;
- }
- for (Source librarySource in oldStateMap.keys.toSet()) {
- if (needsSeparator) {
- buffer.write("; ");
- }
- buffer.write("removed resolution for ");
- buffer.write(librarySource.fullName);
- needsSeparator = true;
- }
- return needsSeparator;
- }
-
- @override
- void _writeOn(StringBuffer buffer) {
- buffer.write("Dart: ");
- super._writeOn(buffer);
- _writeStateOn(buffer, "tokenStream", TOKEN_STREAM);
- _writeStateOn(buffer, "scanErrors", SCAN_ERRORS);
- _writeStateOn(buffer, "sourceKind", SOURCE_KIND);
- _writeStateOn(buffer, "parsedUnit", PARSED_UNIT);
- _writeStateOn(buffer, "parseErrors", PARSE_ERRORS);
- _writeStateOn(buffer, "exportedLibraries", EXPORTED_LIBRARIES);
- _writeStateOn(buffer, "importedLibraries", IMPORTED_LIBRARIES);
- _writeStateOn(buffer, "includedParts", INCLUDED_PARTS);
- _writeStateOn(buffer, "element", ELEMENT);
- _writeStateOn(buffer, "publicNamespace", PUBLIC_NAMESPACE);
- _writeStateOn(buffer, "clientServer", IS_CLIENT);
- _writeStateOn(buffer, "launchable", IS_LAUNCHABLE);
- _resolutionState._writeOn(buffer);
- }
-}
-
-/**
- * An immutable constant representing data that can be stored in the cache.
- */
-class DataDescriptor<E> {
- /**
- * The next artificial hash code.
- */
- static int _NEXT_HASH_CODE = 0;
-
- /**
- * The artifitial hash code for this object.
- */
- final int _hashCode = _NEXT_HASH_CODE++;
-
- /**
- * The name of the descriptor, used for debugging purposes.
- */
- final String _name;
-
- /**
- * The default value used when the data does not exist.
- */
- final E defaultValue;
-
- /**
- * Initialize a newly created descriptor to have the given [name] and
- * [defaultValue].
- */
- DataDescriptor(this._name, [this.defaultValue = null]);
-
- @override
- int get hashCode => _hashCode;
-
- @override
- String toString() => _name;
-}
-
-/**
- * A retention policy that will keep AST's in the cache if there is analysis
- * information that needs to be computed for a source, where the computation is
- * dependent on having the AST.
- */
-class DefaultRetentionPolicy implements CacheRetentionPolicy {
- /**
- * An instance of this class that can be shared.
- */
- static DefaultRetentionPolicy POLICY = new DefaultRetentionPolicy();
-
- /**
- * Return `true` if there is analysis information in the given [dartEntry]
- * that needs to be computed, where the computation is dependent on having the
- * AST.
- */
- bool astIsNeeded(DartEntry dartEntry) =>
- dartEntry.hasInvalidData(DartEntry.HINTS) ||
- dartEntry.hasInvalidData(DartEntry.LINTS) ||
- dartEntry.hasInvalidData(DartEntry.VERIFICATION_ERRORS) ||
- dartEntry.hasInvalidData(DartEntry.RESOLUTION_ERRORS);
-
- @override
- RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry) {
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry;
- if (astIsNeeded(dartEntry)) {
- return RetentionPriority.MEDIUM;
- }
- }
- return RetentionPriority.LOW;
- }
-}
-
-/**
- * Instances of the class `GenerateDartErrorsTask` generate errors and warnings for a single
- * Dart source.
- */
-class GenerateDartErrorsTask extends AnalysisTask {
- /**
- * The source for which errors and warnings are to be produced.
- */
- final Source source;
-
- /**
- * The compilation unit used to resolve the dependencies.
- */
- final CompilationUnit _unit;
-
- /**
- * The element model for the library containing the source.
- */
- final LibraryElement libraryElement;
-
- /**
- * The errors that were generated for the source.
- */
- List<AnalysisError> _errors;
-
- /**
- * Initialize a newly created task to perform analysis within the given context.
- *
- * @param context the context in which the task is to be performed
- * @param source the source for which errors and warnings are to be produced
- * @param unit the compilation unit used to resolve the dependencies
- * @param libraryElement the element model for the library containing the source
- */
- GenerateDartErrorsTask(InternalAnalysisContext context, this.source,
- this._unit, this.libraryElement)
- : super(context);
-
- /**
- * Return the errors that were generated for the source.
- *
- * @return the errors that were generated for the source
- */
- List<AnalysisError> get errors => _errors;
-
- @override
- String get taskDescription =>
- "generate errors and warnings for ${source.fullName}";
-
- @override
- accept(AnalysisTaskVisitor visitor) =>
- visitor.visitGenerateDartErrorsTask(this);
-
- @override
- void internalPerform() {
- PerformanceStatistics.errors.makeCurrentWhile(() {
- RecordingErrorListener errorListener = new RecordingErrorListener();
- ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
- TypeProvider typeProvider = context.typeProvider;
- //
- // Validate the directives
- //
- validateDirectives(context, source, _unit, errorListener);
- //
- // Use the ConstantVerifier to verify the use of constants.
- // This needs to happen before using the ErrorVerifier because some error
- // codes need the computed constant values.
- //
- // TODO(paulberry): as a temporary workaround for issue 21572,
- // ConstantVerifier is being run right after ConstantValueComputer, so we
- // don't need to run it here. Once issue 21572 is fixed, re-enable the
- // call to ConstantVerifier.
-// ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, libraryElement, typeProvider);
-// _unit.accept(constantVerifier);
- //
- // Use the ErrorVerifier to compute the rest of the errors.
- //
- ErrorVerifier errorVerifier = new ErrorVerifier(
- errorReporter,
- libraryElement,
- typeProvider,
- new InheritanceManager(libraryElement),
- context.analysisOptions.enableSuperMixins);
- _unit.accept(errorVerifier);
- _errors = errorListener.getErrorsForSource(source);
- });
- }
-
- /**
- * Check each directive in the given compilation unit to see if the referenced source exists and
- * report an error if it does not.
- *
- * @param context the context in which the library exists
- * @param librarySource the source representing the library containing the directives
- * @param unit the compilation unit containing the directives to be validated
- * @param errorListener the error listener to which errors should be reported
- */
- static void validateDirectives(AnalysisContext context, Source librarySource,
- CompilationUnit unit, AnalysisErrorListener errorListener) {
- for (Directive directive in unit.directives) {
- if (directive is UriBasedDirective) {
- validateReferencedSource(
- context, librarySource, directive, errorListener);
- }
- }
- }
-
- /**
- * Check the given directive to see if the referenced source exists and report an error if it does
- * not.
- *
- * @param context the context in which the library exists
- * @param librarySource the source representing the library containing the directive
- * @param directive the directive to be verified
- * @param errorListener the error listener to which errors should be reported
- */
- static void validateReferencedSource(
- AnalysisContext context,
- Source librarySource,
- UriBasedDirective directive,
- AnalysisErrorListener errorListener) {
- Source source = directive.source;
- if (source != null) {
- if (context.exists(source)) {
- return;
- }
- } else {
- // Don't report errors already reported by ParseDartTask.resolveDirective
- if (directive.validate() != null) {
- return;
- }
- }
- StringLiteral uriLiteral = directive.uri;
- errorListener.onError(new AnalysisError(
- librarySource,
- uriLiteral.offset,
- uriLiteral.length,
- CompileTimeErrorCode.URI_DOES_NOT_EXIST,
- [directive.uriContent]));
- }
-}
-
-/**
- * Instances of the class `GenerateDartHintsTask` generate hints for a single Dart library.
- */
-class GenerateDartHintsTask extends AnalysisTask {
- /**
- * The compilation units that comprise the library, with the defining compilation unit appearing
- * first in the list.
- */
- final List<TimestampedData<CompilationUnit>> _units;
-
- /**
- * The element model for the library being analyzed.
- */
- final LibraryElement libraryElement;
-
- /**
- * A table mapping the sources that were analyzed to the hints that were
- * generated for the sources.
- */
- HashMap<Source, List<AnalysisError>> _hintMap;
-
- /**
- * Initialize a newly created task to perform analysis within the given context.
- *
- * @param context the context in which the task is to be performed
- * @param units the compilation units that comprise the library, with the defining compilation
- * unit appearing first in the list
- * @param libraryElement the element model for the library being analyzed
- */
- GenerateDartHintsTask(
- InternalAnalysisContext context, this._units, this.libraryElement)
- : super(context);
-
- /**
- * Return a table mapping the sources that were analyzed to the hints that were generated for the
- * sources, or `null` if the task has not been performed or if the analysis did not complete
- * normally.
- *
- * @return a table mapping the sources that were analyzed to the hints that were generated for the
- * sources
- */
- HashMap<Source, List<AnalysisError>> get hintMap => _hintMap;
-
- @override
- String get taskDescription {
- Source librarySource = libraryElement.source;
- if (librarySource == null) {
- return "generate Dart hints for library without source";
- }
- return "generate Dart hints for ${librarySource.fullName}";
- }
-
- @override
- accept(AnalysisTaskVisitor visitor) =>
- visitor.visitGenerateDartHintsTask(this);
-
- @override
- void internalPerform() {
- //
- // Gather the compilation units.
- //
- int unitCount = _units.length;
- List<CompilationUnit> compilationUnits =
- new List<CompilationUnit>(unitCount);
- for (int i = 0; i < unitCount; i++) {
- compilationUnits[i] = _units[i].data;
- }
- //
- // Analyze all of the units.
- //
- RecordingErrorListener errorListener = new RecordingErrorListener();
- HintGenerator hintGenerator =
- new HintGenerator(compilationUnits, context, errorListener);
- hintGenerator.generateForLibrary();
- //
- // Store the results.
- //
- _hintMap = new HashMap<Source, List<AnalysisError>>();
- for (int i = 0; i < unitCount; i++) {
- Source source = _units[i].data.element.source;
- _hintMap[source] = errorListener.getErrorsForSource(source);
- }
- }
-}
-
-/// Generates lint feedback for a single Dart library.
-class GenerateDartLintsTask extends AnalysisTask {
- ///The compilation units that comprise the library, with the defining
- ///compilation unit appearing first in the list.
- final List<TimestampedData<CompilationUnit>> _units;
-
- /// The element model for the library being analyzed.
- final LibraryElement libraryElement;
-
- /// A mapping of analyzed sources to their associated lint warnings.
- /// May be [null] if the task has not been performed or if analysis did not
- /// complete normally.
- HashMap<Source, List<AnalysisError>> lintMap;
-
- /// Initialize a newly created task to perform lint checking over these
- /// [_units] belonging to this [libraryElement] within the given [context].
- GenerateDartLintsTask(context, this._units, this.libraryElement)
- : super(context);
-
- @override
- String get taskDescription {
- Source librarySource = libraryElement.source;
- return (librarySource == null)
- ? "generate Dart lints for library without source"
- : "generate Dart lints for ${librarySource.fullName}";
- }
-
- @override
- accept(AnalysisTaskVisitor visitor) =>
- visitor.visitGenerateDartLintsTask(this);
-
- @override
- void internalPerform() {
- Iterable<CompilationUnit> compilationUnits =
- _units.map((TimestampedData<CompilationUnit> unit) => unit.data);
- RecordingErrorListener errorListener = new RecordingErrorListener();
- LintGenerator lintGenerator =
- new LintGenerator(compilationUnits, errorListener);
- lintGenerator.generate();
-
- lintMap = new HashMap<Source, List<AnalysisError>>();
- compilationUnits.forEach((CompilationUnit unit) {
- Source source = unit.element.source;
- lintMap[source] = errorListener.getErrorsForSource(source);
- });
- }
-}
-
-/**
- * Instances of the class `GetContentTask` get the contents of a source.
- */
-class GetContentTask extends AnalysisTask {
- /**
- * The source to be read.
- */
- final Source source;
-
- /**
- * A flag indicating whether this task is complete.
- */
- bool _complete = false;
-
- /**
- * The contents of the source.
- */
- String _content;
-
- /**
- * The errors that were produced by getting the source content.
- */
- final List<AnalysisError> errors = <AnalysisError>[];
-
- /**
- * The time at which the contents of the source were last modified.
- */
- int _modificationTime = -1;
-
- /**
- * Initialize a newly created task to perform analysis within the given context.
- *
- * @param context the context in which the task is to be performed
- * @param source the source to be parsed
- * @param contentData the time-stamped contents of the source
- */
- GetContentTask(InternalAnalysisContext context, this.source)
- : super(context) {
- if (source == null) {
- throw new IllegalArgumentException("Cannot get contents of null source");
- }
- }
-
- /**
- * Return the contents of the source, or `null` if the task has not completed or if there
- * was an exception while getting the contents.
- *
- * @return the contents of the source
- */
- String get content => _content;
-
- /**
- * Return `true` if this task is complete. Unlike most tasks, this task is allowed to be
- * visited more than once in order to support asynchronous IO. If the task is not complete when it
- * is visited synchronously as part of the [AnalysisTask.perform]
- * method, it will be visited again, using the same visitor, when the IO operation has been
- * performed.
- *
- * @return `true` if this task is complete
- */
- bool get isComplete => _complete;
-
- /**
- * Return the time at which the contents of the source that was parsed were last modified, or a
- * negative value if the task has not yet been performed or if an exception occurred.
- *
- * @return the time at which the contents of the source that was parsed were last modified
- */
- int get modificationTime => _modificationTime;
-
- @override
- String get taskDescription => "get contents of ${source.fullName}";
-
- @override
- accept(AnalysisTaskVisitor visitor) => visitor.visitGetContentTask(this);
-
- @override
- void internalPerform() {
- _complete = true;
- try {
- TimestampedData<String> data = context.getContents(source);
- _content = data.data;
- _modificationTime = data.modificationTime;
- AnalysisEngine.instance.instrumentationService
- .logFileRead(source.fullName, _modificationTime, _content);
- } catch (exception, stackTrace) {
- if (source.exists()) {
- errors.add(new AnalysisError(
- source, 0, 0, ScannerErrorCode.UNABLE_GET_CONTENT, [exception]));
- }
- throw new AnalysisException("Could not get contents of $source",
- new CaughtException(exception, stackTrace));
- }
- }
-}
-
-/**
- * The information cached by an analysis context about an individual HTML file.
- */
-class HtmlEntry extends SourceEntry {
- /**
- * The data descriptor representing the HTML element.
- */
- static final DataDescriptor<HtmlElement> ELEMENT =
- new DataDescriptor<HtmlElement>("HtmlEntry.ELEMENT");
-
- /**
- * The data descriptor representing the hints resulting from auditing the
- * source.
- */
- static final DataDescriptor<List<AnalysisError>> HINTS =
- new DataDescriptor<List<AnalysisError>>(
- "HtmlEntry.HINTS", AnalysisError.NO_ERRORS);
-
- /**
- * The data descriptor representing the errors resulting from parsing the
- * source.
- */
- static final DataDescriptor<List<AnalysisError>> PARSE_ERRORS =
- new DataDescriptor<List<AnalysisError>>(
- "HtmlEntry.PARSE_ERRORS", AnalysisError.NO_ERRORS);
-
- /**
- * The data descriptor representing the parsed AST structure.
- */
- static final DataDescriptor<ht.HtmlUnit> PARSED_UNIT =
- new DataDescriptor<ht.HtmlUnit>("HtmlEntry.PARSED_UNIT");
-
- /**
- * The data descriptor representing the resolved AST structure.
- */
- static final DataDescriptor<ht.HtmlUnit> RESOLVED_UNIT =
- new DataDescriptor<ht.HtmlUnit>("HtmlEntry.RESOLVED_UNIT");
-
- /**
- * The data descriptor representing the list of referenced libraries.
- */
- static final DataDescriptor<List<Source>> REFERENCED_LIBRARIES =
- new DataDescriptor<List<Source>>(
- "HtmlEntry.REFERENCED_LIBRARIES", Source.EMPTY_LIST);
-
- /**
- * The data descriptor representing the errors resulting from resolving the
- * source.
- */
- static final DataDescriptor<List<AnalysisError>> RESOLUTION_ERRORS =
- new DataDescriptor<List<AnalysisError>>(
- "HtmlEntry.RESOLUTION_ERRORS", AnalysisError.NO_ERRORS);
-
- /**
- * Return all of the errors associated with the HTML file that are currently
- * cached.
- */
- List<AnalysisError> get allErrors {
- List<AnalysisError> errors = new List<AnalysisError>();
- errors.addAll(super.allErrors);
- errors.addAll(getValue(PARSE_ERRORS));
- errors.addAll(getValue(RESOLUTION_ERRORS));
- errors.addAll(getValue(HINTS));
- if (errors.length == 0) {
- return AnalysisError.NO_ERRORS;
- }
- return errors;
- }
-
- /**
- * Return a valid parsed unit, either an unresolved AST structure or the
- * result of resolving the AST structure, or `null` if there is no parsed unit
- * available.
- */
- ht.HtmlUnit get anyParsedUnit {
- if (getState(PARSED_UNIT) == CacheState.VALID) {
- return getValue(PARSED_UNIT);
- }
- if (getState(RESOLVED_UNIT) == CacheState.VALID) {
- return getValue(RESOLVED_UNIT);
- }
- return null;
- }
-
- @override
- List<DataDescriptor> get descriptors {
- List<DataDescriptor> result = super.descriptors;
- result.addAll([
- HtmlEntry.ELEMENT,
- HtmlEntry.PARSE_ERRORS,
- HtmlEntry.PARSED_UNIT,
- HtmlEntry.RESOLUTION_ERRORS,
- HtmlEntry.RESOLVED_UNIT,
- HtmlEntry.HINTS
- ]);
- return result;
- }
-
- @override
- SourceKind get kind => SourceKind.HTML;
-
- /**
- * Flush any AST structures being maintained by this entry.
- */
- void flushAstStructures() {
- _flush(PARSED_UNIT);
- _flush(RESOLVED_UNIT);
- }
-
- @override
- void invalidateAllInformation() {
- super.invalidateAllInformation();
- setState(PARSE_ERRORS, CacheState.INVALID);
- setState(PARSED_UNIT, CacheState.INVALID);
- setState(RESOLVED_UNIT, CacheState.INVALID);
- invalidateAllResolutionInformation(true);
- }
-
- /**
- * Invalidate all of the resolution information associated with the HTML file.
- * If [invalidateUris] is `true`, the cached results of converting URIs to
- * source files should also be invalidated.
- */
- void invalidateAllResolutionInformation(bool invalidateUris) {
- setState(RESOLVED_UNIT, CacheState.INVALID);
- setState(ELEMENT, CacheState.INVALID);
- setState(RESOLUTION_ERRORS, CacheState.INVALID);
- setState(HINTS, CacheState.INVALID);
- if (invalidateUris) {
- setState(REFERENCED_LIBRARIES, CacheState.INVALID);
- }
- }
-
- /**
- * Invalidate all of the parse and resolution information associated with
- * this source.
- */
- void invalidateParseInformation() {
- setState(PARSE_ERRORS, CacheState.INVALID);
- setState(PARSED_UNIT, CacheState.INVALID);
- invalidateAllResolutionInformation(true);
- }
-
- @override
- void recordContentError(CaughtException exception) {
- super.recordContentError(exception);
- recordParseError(exception);
- }
-
- /**
- * Record that an [exception] was encountered while attempting to parse the
- * source associated with this entry.
- */
- void recordParseError(CaughtException exception) {
- // If the scanning and parsing of HTML are separated,
- // the following line can be removed.
- recordScanError(exception);
- setState(PARSE_ERRORS, CacheState.ERROR);
- setState(PARSED_UNIT, CacheState.ERROR);
- setState(REFERENCED_LIBRARIES, CacheState.ERROR);
- recordResolutionError(exception);
- }
-
- /**
- * Record that an [exception] was encountered while attempting to resolve the
- * source associated with this entry.
- */
- void recordResolutionError(CaughtException exception) {
- this.exception = exception;
- setState(RESOLVED_UNIT, CacheState.ERROR);
- setState(ELEMENT, CacheState.ERROR);
- setState(RESOLUTION_ERRORS, CacheState.ERROR);
- setState(HINTS, CacheState.ERROR);
- }
-
- @override
- bool _isValidDescriptor(DataDescriptor descriptor) {
- return descriptor == ELEMENT ||
- descriptor == HINTS ||
- descriptor == PARSED_UNIT ||
- descriptor == PARSE_ERRORS ||
- descriptor == REFERENCED_LIBRARIES ||
- descriptor == RESOLUTION_ERRORS ||
- descriptor == RESOLVED_UNIT ||
- super._isValidDescriptor(descriptor);
- }
-
- @override
- bool _writeDiffOn(StringBuffer buffer, SourceEntry oldEntry) {
- bool needsSeparator = super._writeDiffOn(buffer, oldEntry);
- if (oldEntry is! HtmlEntry) {
- if (needsSeparator) {
- buffer.write("; ");
- }
- buffer.write("entry type changed; was ");
- buffer.write(oldEntry.runtimeType);
- return true;
- }
- needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "parseErrors",
- HtmlEntry.PARSE_ERRORS, oldEntry);
- needsSeparator = _writeStateDiffOn(
- buffer, needsSeparator, "parsedUnit", HtmlEntry.PARSED_UNIT, oldEntry);
- needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "resolvedUnit",
- HtmlEntry.RESOLVED_UNIT, oldEntry);
- needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
- "resolutionErrors", HtmlEntry.RESOLUTION_ERRORS, oldEntry);
- needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
- "referencedLibraries", HtmlEntry.REFERENCED_LIBRARIES, oldEntry);
- needsSeparator = _writeStateDiffOn(
- buffer, needsSeparator, "element", HtmlEntry.ELEMENT, oldEntry);
- return needsSeparator;
- }
-
- @override
- void _writeOn(StringBuffer buffer) {
- buffer.write("Html: ");
- super._writeOn(buffer);
- _writeStateOn(buffer, "parseErrors", PARSE_ERRORS);
- _writeStateOn(buffer, "parsedUnit", PARSED_UNIT);
- _writeStateOn(buffer, "resolvedUnit", RESOLVED_UNIT);
- _writeStateOn(buffer, "resolutionErrors", RESOLUTION_ERRORS);
- _writeStateOn(buffer, "referencedLibraries", REFERENCED_LIBRARIES);
- _writeStateOn(buffer, "element", ELEMENT);
- }
-}
-
-/**
* An event indicating when a source either starts or stops being implicitly
* analyzed.
*/
@@ -9131,296 +1835,6 @@
}
/**
- * Instances of the class `IncrementalAnalysisCache` hold information used to perform
- * incremental analysis.
- *
- * See [AnalysisContextImpl.setChangedContents].
- */
-class IncrementalAnalysisCache {
- final Source librarySource;
-
- final Source source;
-
- final String oldContents;
-
- final CompilationUnit resolvedUnit;
-
- String _newContents;
-
- int _offset = 0;
-
- int _oldLength = 0;
-
- int _newLength = 0;
-
- IncrementalAnalysisCache(
- this.librarySource,
- this.source,
- this.resolvedUnit,
- this.oldContents,
- this._newContents,
- this._offset,
- this._oldLength,
- this._newLength);
-
- /**
- * Determine if the cache contains source changes that need to be analyzed
- *
- * @return `true` if the cache contains changes to be analyzed, else `false`
- */
- bool get hasWork => _oldLength > 0 || _newLength > 0;
-
- /**
- * Return the current contents for the receiver's source.
- *
- * @return the contents (not `null`)
- */
- String get newContents => _newContents;
-
- /**
- * Return the number of characters in the replacement text.
- *
- * @return the replacement length (zero or greater)
- */
- int get newLength => _newLength;
-
- /**
- * Return the character position of the first changed character.
- *
- * @return the offset (zero or greater)
- */
- int get offset => _offset;
-
- /**
- * Return the number of characters that were replaced.
- *
- * @return the replaced length (zero or greater)
- */
- int get oldLength => _oldLength;
-
- /**
- * Determine if the incremental analysis result can be cached for the next incremental analysis.
- *
- * @param cache the prior incremental analysis cache
- * @param unit the incrementally updated compilation unit
- * @return the cache used for incremental analysis or `null` if incremental analysis results
- * cannot be cached for the next incremental analysis
- */
- static IncrementalAnalysisCache cacheResult(
- IncrementalAnalysisCache cache, CompilationUnit unit) {
- if (cache != null && unit != null) {
- return new IncrementalAnalysisCache(cache.librarySource, cache.source,
- unit, cache._newContents, cache._newContents, 0, 0, 0);
- }
- return null;
- }
-
- /**
- * Determine if the cache should be cleared.
- *
- * @param cache the prior cache or `null` if none
- * @param source the source being updated (not `null`)
- * @return the cache used for incremental analysis or `null` if incremental analysis cannot
- * be performed
- */
- static IncrementalAnalysisCache clear(
- IncrementalAnalysisCache cache, Source source) {
- if (cache == null || cache.source == source) {
- return null;
- }
- return cache;
- }
-
- /**
- * Determine if incremental analysis can be performed from the given information.
- *
- * @param cache the prior cache or `null` if none
- * @param source the source being updated (not `null`)
- * @param oldContents the original source contents prior to this update (may be `null`)
- * @param newContents the new contents after this incremental change (not `null`)
- * @param offset the offset at which the change occurred
- * @param oldLength the length of the text being replaced
- * @param newLength the length of the replacement text
- * @param sourceEntry the cached entry for the given source or `null` if none
- * @return the cache used for incremental analysis or `null` if incremental analysis cannot
- * be performed
- */
- static IncrementalAnalysisCache update(
- IncrementalAnalysisCache cache,
- Source source,
- String oldContents,
- String newContents,
- int offset,
- int oldLength,
- int newLength,
- SourceEntry sourceEntry) {
- // Determine the cache resolved unit
- Source librarySource = null;
- CompilationUnit unit = null;
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry;
- List<Source> librarySources = dartEntry.librariesContaining;
- if (librarySources.length == 1) {
- librarySource = librarySources[0];
- if (librarySource != null) {
- unit = dartEntry.getValueInLibrary(
- DartEntry.RESOLVED_UNIT, librarySource);
- }
- }
- }
- // Create a new cache if there is not an existing cache or the source is
- // different or a new resolved compilation unit is available.
- if (cache == null || cache.source != source || unit != null) {
- if (unit == null) {
- return null;
- }
- if (oldContents == null) {
- if (oldLength != 0) {
- return null;
- }
- oldContents =
- "${newContents.substring(0, offset)}${newContents.substring(offset + newLength)}";
- }
- return new IncrementalAnalysisCache(librarySource, source, unit,
- oldContents, newContents, offset, oldLength, newLength);
- }
- // Update the existing cache if the change is contiguous
- if (cache._oldLength == 0 && cache._newLength == 0) {
- cache._offset = offset;
- cache._oldLength = oldLength;
- cache._newLength = newLength;
- } else {
- if (cache._offset > offset || offset > cache._offset + cache._newLength) {
- return null;
- }
- cache._newLength += newLength - oldLength;
- }
- cache._newContents = newContents;
- return cache;
- }
-
- /**
- * Verify that the incrementally parsed and resolved unit in the incremental cache is structurally
- * equivalent to the fully parsed unit.
- *
- * @param cache the prior cache or `null` if none
- * @param source the source of the compilation unit that was parsed (not `null`)
- * @param unit the compilation unit that was just parsed
- * @return the cache used for incremental analysis or `null` if incremental analysis results
- * cannot be cached for the next incremental analysis
- */
- static IncrementalAnalysisCache verifyStructure(
- IncrementalAnalysisCache cache, Source source, CompilationUnit unit) {
- if (cache != null && unit != null && cache.source == source) {
- if (!AstComparator.equalNodes(cache.resolvedUnit, unit)) {
- return null;
- }
- }
- return cache;
- }
-}
-
-/**
- * Instances of the class `IncrementalAnalysisTask` incrementally update existing analysis.
- */
-class IncrementalAnalysisTask extends AnalysisTask {
- /**
- * The information used to perform incremental analysis.
- */
- final IncrementalAnalysisCache cache;
-
- /**
- * The compilation unit that was produced by incrementally updating the existing unit.
- */
- CompilationUnit _updatedUnit;
-
- /**
- * Initialize a newly created task to perform analysis within the given context.
- *
- * @param context the context in which the task is to be performed
- * @param cache the incremental analysis cache used to perform the analysis
- */
- IncrementalAnalysisTask(InternalAnalysisContext context, this.cache)
- : super(context);
-
- /**
- * Return the compilation unit that was produced by incrementally updating the existing
- * compilation unit, or `null` if the task has not yet been performed, could not be
- * performed, or if an exception occurred.
- *
- * @return the compilation unit
- */
- CompilationUnit get compilationUnit => _updatedUnit;
-
- /**
- * Return the source that is to be incrementally analyzed.
- *
- * @return the source
- */
- Source get source => cache != null ? cache.source : null;
-
- @override
- String get taskDescription =>
- "incremental analysis ${cache != null ? cache.source : "null"}";
-
- /**
- * Return the type provider used for incremental resolution.
- *
- * @return the type provider (or `null` if an exception occurs)
- */
- TypeProvider get typeProvider {
- try {
- return context.typeProvider;
- } on AnalysisException {
- return null;
- }
- }
-
- @override
- accept(AnalysisTaskVisitor visitor) =>
- visitor.visitIncrementalAnalysisTask(this);
-
- @override
- void internalPerform() {
- if (cache == null) {
- return;
- }
- // Only handle small changes
- if (cache.oldLength > 0 || cache.newLength > 30) {
- return;
- }
- // Produce an updated token stream
- CharacterReader reader = new CharSequenceReader(cache.newContents);
- BooleanErrorListener errorListener = new BooleanErrorListener();
- IncrementalScanner scanner = new IncrementalScanner(
- cache.source, reader, errorListener, context.analysisOptions);
- scanner.rescan(cache.resolvedUnit.beginToken, cache.offset, cache.oldLength,
- cache.newLength);
- if (errorListener.errorReported) {
- return;
- }
- // Produce an updated AST
- IncrementalParser parser = new IncrementalParser(
- cache.source, scanner.tokenMap, AnalysisErrorListener.NULL_LISTENER);
- _updatedUnit = parser.reparse(cache.resolvedUnit, scanner.leftToken,
- scanner.rightToken, cache.offset, cache.offset + cache.oldLength);
- // Update the resolution
- TypeProvider typeProvider = this.typeProvider;
- if (_updatedUnit != null && typeProvider != null) {
- CompilationUnitElement element = _updatedUnit.element;
- if (element != null) {
- LibraryElement library = element.library;
- if (library != null) {
- IncrementalResolver resolver = new IncrementalResolver(null, null,
- null, element, cache.offset, cache.oldLength, cache.newLength);
- resolver.resolve(parser.updatedNode);
- }
- }
- }
- }
-}
-
-/**
* Additional behavior for an analysis context that is required by internal
* users of the context.
*/
@@ -9428,10 +1842,8 @@
/**
* A table mapping the sources known to the context to the information known
* about the source.
- *
- * TODO(scheglov) add the type, once we have only one cache.
*/
- dynamic get analysisCache;
+ AnalysisCache get analysisCache;
/**
* Allow the client to supply its own content cache. This will take the
@@ -9449,11 +1861,6 @@
List<AnalysisTarget> get explicitTargets;
/**
- * A factory to override how [LibraryResolver] is created.
- */
- LibraryResolverFactory get libraryResolverFactory;
-
- /**
* Return a list containing all of the sources that have been marked as
* priority sources. Clients must not modify the returned list.
*/
@@ -9467,20 +1874,8 @@
/**
* The partition that contains analysis results that are not shared with other
* contexts.
- *
- * TODO(scheglov) add the type, once we have only one cache.
*/
- dynamic get privateAnalysisCachePartition;
-
- /**
- * A factory to override how [ResolverVisitor] is created.
- */
- ResolverVisitorFactory get resolverVisitorFactory;
-
- /**
- * Returns a statistics about this context.
- */
- AnalysisContextStatistics get statistics;
+ CachePartition get privateAnalysisCachePartition;
/**
* Sets the [TypeProvider] for this context.
@@ -9488,14 +1883,9 @@
void set typeProvider(TypeProvider typeProvider);
/**
- * A factory to override how [TypeResolverVisitor] is created.
- */
- TypeResolverVisitorFactory get typeResolverVisitorFactory;
-
- /**
* A list of all [WorkManager]s used by this context.
*/
- List<newContext.WorkManager> get workManagers;
+ List<WorkManager> get workManagers;
/**
* Return a list containing the sources of the libraries that are exported by
@@ -9520,17 +1910,6 @@
List<Source> computeImportedLibraries(Source source);
/**
- * Return an AST structure corresponding to the given [source], but ensure
- * that the structure has not already been resolved and will not be resolved
- * by any other threads or in any other library.
- *
- * Throws an [AnalysisException] if the analysis could not be performed.
- *
- * <b>Note:</b> This method cannot be used in an async environment
- */
- CompilationUnit computeResolvableCompilationUnit(Source source);
-
- /**
* Return all the resolved [CompilationUnit]s for the given [source] if not
* flushed, otherwise return `null` and ensures that the [CompilationUnit]s
* will be eventually returned to the client from [performAnalysisTask].
@@ -9540,7 +1919,7 @@
/**
* Return the cache entry associated with the given [target].
*/
- cache.CacheEntry getCacheEntry(AnalysisTarget target);
+ CacheEntry getCacheEntry(AnalysisTarget target);
/**
* Return context that owns the given [source].
@@ -9587,12 +1966,8 @@
/**
* Return `true` if errors should be produced for the given [source].
- * The [entry] associated with the source is passed in for efficiency.
- *
- * TODO(scheglov) remove [entry] after migration to the new task model.
- * It is not used there anyway.
*/
- bool shouldErrorsBeAnalyzed(Source source, Object entry);
+ bool shouldErrorsBeAnalyzed(Source source);
/**
* For testing only: flush all representations of the AST (both resolved and
@@ -9601,13 +1976,6 @@
void test_flushAstStructures(Source source);
/**
- * Call the given callback function for eache cache item in the context.
- */
- @deprecated
- void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
- DataDescriptor rowDesc, CacheState state));
-
- /**
* Visit all entries of the content cache.
*/
void visitContentCache(ContentCacheVisitor visitor);
@@ -9634,25 +2002,11 @@
void logError(String message, [CaughtException exception]);
/**
- * Log the given [exception] as one representing an error. The [message] is an
- * explanation of why the error occurred or what it means.
- */
- @deprecated // Use logError(message, exception)
- void logError2(String message, Object exception);
-
- /**
* Log the given informational message. The [message] is expected to be an
* explanation of why the error occurred or what it means. The [exception] is
* expected to be the reason for the error.
*/
void logInformation(String message, [CaughtException exception]);
-
- /**
- * Log the given [exception] as one representing an informational message. The
- * [message] is an explanation of why the error occurred or what it means.
- */
- @deprecated // Use logInformation(message, exception)
- void logInformation2(String message, Object exception);
}
/**
@@ -9663,13 +2017,7 @@
void logError(String message, [CaughtException exception]) {}
@override
- void logError2(String message, Object exception) {}
-
- @override
void logInformation(String message, [CaughtException exception]) {}
-
- @override
- void logInformation2(String message, Object exception) {}
}
/**
@@ -9700,547 +2048,6 @@
}
/**
- * Instances of the class `ParseDartTask` parse a specific source as a Dart file.
- */
-class ParseDartTask extends AnalysisTask {
- /**
- * The source to be parsed.
- */
- final Source source;
-
- /**
- * The head of the token stream used for parsing.
- */
- final Token _tokenStream;
-
- /**
- * The line information associated with the source.
- */
- final LineInfo lineInfo;
-
- /**
- * The compilation unit that was produced by parsing the source.
- */
- CompilationUnit _unit;
-
- /**
- * A flag indicating whether the source contains a 'part of' directive.
- */
- bool _containsPartOfDirective = false;
-
- /**
- * A flag indicating whether the source contains any directive other than a 'part of' directive.
- */
- bool _containsNonPartOfDirective = false;
-
- /**
- * A set containing the sources referenced by 'export' directives.
- */
- HashSet<Source> _exportedSources = new HashSet<Source>();
-
- /**
- * A set containing the sources referenced by 'import' directives.
- */
- HashSet<Source> _importedSources = new HashSet<Source>();
-
- /**
- * A set containing the sources referenced by 'part' directives.
- */
- HashSet<Source> _includedSources = new HashSet<Source>();
-
- /**
- * The errors that were produced by scanning and parsing the source.
- */
- List<AnalysisError> _errors = AnalysisError.NO_ERRORS;
-
- /**
- * Initialize a newly created task to perform analysis within the given context.
- *
- * @param context the context in which the task is to be performed
- * @param source the source to be parsed
- * @param tokenStream the head of the token stream used for parsing
- * @param lineInfo the line information associated with the source
- */
- ParseDartTask(InternalAnalysisContext context, this.source, this._tokenStream,
- this.lineInfo)
- : super(context);
-
- /**
- * Return the compilation unit that was produced by parsing the source, or `null` if the
- * task has not yet been performed or if an exception occurred.
- *
- * @return the compilation unit that was produced by parsing the source
- */
- CompilationUnit get compilationUnit => _unit;
-
- /**
- * Return the errors that were produced by scanning and parsing the source, or an empty list if
- * the task has not yet been performed or if an exception occurred.
- *
- * @return the errors that were produced by scanning and parsing the source
- */
- List<AnalysisError> get errors => _errors;
-
- /**
- * Return a list containing the sources referenced by 'export' directives, or an empty list if
- * the task has not yet been performed or if an exception occurred.
- *
- * @return an list containing the sources referenced by 'export' directives
- */
- List<Source> get exportedSources => _toArray(_exportedSources);
-
- /**
- * Return `true` if the source contains any directive other than a 'part of' directive, or
- * `false` if the task has not yet been performed or if an exception occurred.
- *
- * @return `true` if the source contains any directive other than a 'part of' directive
- */
- bool get hasNonPartOfDirective => _containsNonPartOfDirective;
-
- /**
- * Return `true` if the source contains a 'part of' directive, or `false` if the task
- * has not yet been performed or if an exception occurred.
- *
- * @return `true` if the source contains a 'part of' directive
- */
- bool get hasPartOfDirective => _containsPartOfDirective;
-
- /**
- * Return a list containing the sources referenced by 'import' directives, or an empty list if
- * the task has not yet been performed or if an exception occurred.
- *
- * @return a list containing the sources referenced by 'import' directives
- */
- List<Source> get importedSources => _toArray(_importedSources);
-
- /**
- * Return a list containing the sources referenced by 'part' directives, or an empty list if
- * the task has not yet been performed or if an exception occurred.
- *
- * @return a list containing the sources referenced by 'part' directives
- */
- List<Source> get includedSources => _toArray(_includedSources);
-
- @override
- String get taskDescription {
- if (source == null) {
- return "parse as dart null source";
- }
- return "parse as dart ${source.fullName}";
- }
-
- @override
- accept(AnalysisTaskVisitor visitor) => visitor.visitParseDartTask(this);
-
- @override
- void internalPerform() {
- //
- // Then parse the token stream.
- //
- PerformanceStatistics.parse.makeCurrentWhile(() {
- RecordingErrorListener errorListener = new RecordingErrorListener();
- Parser parser = new Parser(source, errorListener);
- AnalysisOptions options = context.analysisOptions;
- parser.parseFunctionBodies =
- options.analyzeFunctionBodiesPredicate(source);
- parser.parseGenericMethods = options.enableGenericMethods;
- _unit = parser.parseCompilationUnit(_tokenStream);
- _unit.lineInfo = lineInfo;
- AnalysisContext analysisContext = context;
- for (Directive directive in _unit.directives) {
- if (directive is PartOfDirective) {
- _containsPartOfDirective = true;
- } else {
- _containsNonPartOfDirective = true;
- if (directive is UriBasedDirective) {
- Source referencedSource = resolveDirective(
- analysisContext, source, directive, errorListener);
- if (referencedSource != null) {
- if (directive is ExportDirective) {
- _exportedSources.add(referencedSource);
- } else if (directive is ImportDirective) {
- _importedSources.add(referencedSource);
- } else if (directive is PartDirective) {
- if (referencedSource != source) {
- _includedSources.add(referencedSource);
- }
- } else {
- throw new AnalysisException(
- "$runtimeType failed to handle a ${directive.runtimeType}");
- }
- }
- }
- }
- }
- _errors = errorListener.getErrorsForSource(source);
- });
- }
-
- /**
- * Efficiently convert the given set of [sources] to a list.
- */
- List<Source> _toArray(HashSet<Source> sources) {
- int size = sources.length;
- if (size == 0) {
- return Source.EMPTY_LIST;
- }
- return new List.from(sources);
- }
-
- /**
- * Return the result of resolving the URI of the given URI-based directive against the URI of the
- * given library, or `null` if the URI is not valid.
- *
- * @param context the context in which the resolution is to be performed
- * @param librarySource the source representing the library containing the directive
- * @param directive the directive which URI should be resolved
- * @param errorListener the error listener to which errors should be reported
- * @return the result of resolving the URI against the URI of the library
- */
- static Source resolveDirective(AnalysisContext context, Source librarySource,
- UriBasedDirective directive, AnalysisErrorListener errorListener) {
- StringLiteral uriLiteral = directive.uri;
- String uriContent = uriLiteral.stringValue;
- if (uriContent != null) {
- uriContent = uriContent.trim();
- directive.uriContent = uriContent;
- }
- UriValidationCode code = directive.validate();
- if (code == null) {
- String encodedUriContent = Uri.encodeFull(uriContent);
- try {
- Source source =
- context.sourceFactory.resolveUri(librarySource, encodedUriContent);
- directive.source = source;
- return source;
- } on JavaIOException {
- code = UriValidationCode.INVALID_URI;
- }
- }
- if (code == UriValidationCode.URI_WITH_DART_EXT_SCHEME) {
- return null;
- }
- if (code == UriValidationCode.URI_WITH_INTERPOLATION) {
- errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset,
- uriLiteral.length, CompileTimeErrorCode.URI_WITH_INTERPOLATION));
- return null;
- }
- if (code == UriValidationCode.INVALID_URI) {
- errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset,
- uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriContent]));
- return null;
- }
- throw new RuntimeException(
- message: "Failed to handle validation code: $code");
- }
-}
-
-/**
- * Instances of the class `ParseHtmlTask` parse a specific source as an HTML file.
- */
-class ParseHtmlTask extends AnalysisTask {
- /**
- * The name of the 'src' attribute in a HTML tag.
- */
- static String _ATTRIBUTE_SRC = "src";
-
- /**
- * The name of the 'script' tag in an HTML file.
- */
- static String _TAG_SCRIPT = "script";
-
- /**
- * The source to be parsed.
- */
- final Source source;
-
- /**
- * The contents of the source.
- */
- final String _content;
-
- /**
- * The line information that was produced.
- */
- LineInfo _lineInfo;
-
- /**
- * The HTML unit that was produced by parsing the source.
- */
- ht.HtmlUnit _unit;
-
- /**
- * The errors that were produced by scanning and parsing the source.
- */
- List<AnalysisError> _errors = AnalysisError.NO_ERRORS;
-
- /**
- * A list containing the sources of the libraries that are referenced within the HTML.
- */
- List<Source> _referencedLibraries = Source.EMPTY_LIST;
-
- /**
- * Initialize a newly created task to perform analysis within the given context.
- *
- * @param context the context in which the task is to be performed
- * @param source the source to be parsed
- * @param content the contents of the source
- */
- ParseHtmlTask(InternalAnalysisContext context, this.source, this._content)
- : super(context);
-
- /**
- * Return the errors that were produced by scanning and parsing the source, or `null` if the
- * task has not yet been performed or if an exception occurred.
- *
- * @return the errors that were produced by scanning and parsing the source
- */
- List<AnalysisError> get errors => _errors;
-
- /**
- * Return the HTML unit that was produced by parsing the source.
- *
- * @return the HTML unit that was produced by parsing the source
- */
- ht.HtmlUnit get htmlUnit => _unit;
-
- /**
- * Return the sources of libraries that are referenced in the specified HTML file.
- *
- * @return the sources of libraries that are referenced in the HTML file
- */
- List<Source> get librarySources {
- List<Source> libraries = new List<Source>();
- _unit.accept(new ParseHtmlTask_getLibrarySources(this, libraries));
- if (libraries.isEmpty) {
- return Source.EMPTY_LIST;
- }
- return libraries;
- }
-
- /**
- * Return the line information that was produced, or `null` if the task has not yet been
- * performed or if an exception occurred.
- *
- * @return the line information that was produced
- */
- LineInfo get lineInfo => _lineInfo;
-
- /**
- * Return a list containing the sources of the libraries that are referenced within the HTML.
- *
- * @return the sources of the libraries that are referenced within the HTML
- */
- List<Source> get referencedLibraries => _referencedLibraries;
-
- @override
- String get taskDescription {
- if (source == null) {
- return "parse as html null source";
- }
- return "parse as html ${source.fullName}";
- }
-
- @override
- accept(AnalysisTaskVisitor visitor) => visitor.visitParseHtmlTask(this);
-
- @override
- void internalPerform() {
- try {
- ht.AbstractScanner scanner = new ht.StringScanner(source, _content);
- scanner.passThroughElements = <String>[_TAG_SCRIPT];
- ht.Token token = scanner.tokenize();
- _lineInfo = new LineInfo(scanner.lineStarts);
- RecordingErrorListener errorListener = new RecordingErrorListener();
- _unit = new ht.HtmlParser(source, errorListener, context.analysisOptions)
- .parse(token, _lineInfo);
- _unit.accept(new RecursiveXmlVisitor_ParseHtmlTask_internalPerform(
- this, errorListener));
- _errors = errorListener.getErrorsForSource(source);
- _referencedLibraries = librarySources;
- } catch (exception, stackTrace) {
- throw new AnalysisException(
- "Exception", new CaughtException(exception, stackTrace));
- }
- }
-
- /**
- * Resolves directives in the given [CompilationUnit].
- */
- void _resolveScriptDirectives(
- CompilationUnit script, AnalysisErrorListener errorListener) {
- if (script == null) {
- return;
- }
- AnalysisContext analysisContext = context;
- for (Directive directive in script.directives) {
- if (directive is UriBasedDirective) {
- ParseDartTask.resolveDirective(
- analysisContext, source, directive, errorListener);
- }
- }
- }
-}
-
-class ParseHtmlTask_getLibrarySources extends ht.RecursiveXmlVisitor<Object> {
- final ParseHtmlTask _task;
-
- List<Source> libraries;
-
- ParseHtmlTask_getLibrarySources(this._task, this.libraries) : super();
-
- @override
- Object visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) {
- ht.XmlAttributeNode scriptAttribute = null;
- for (ht.XmlAttributeNode attribute in node.attributes) {
- if (javaStringEqualsIgnoreCase(
- attribute.name, ParseHtmlTask._ATTRIBUTE_SRC)) {
- scriptAttribute = attribute;
- }
- }
- if (scriptAttribute != null) {
- try {
- Uri uri = Uri.parse(scriptAttribute.text);
- String fileName = uri.path;
- Source librarySource =
- _task.context.sourceFactory.resolveUri(_task.source, fileName);
- if (_task.context.exists(librarySource)) {
- libraries.add(librarySource);
- }
- } on FormatException {
- // ignored - invalid URI reported during resolution phase
- }
- }
- return super.visitHtmlScriptTagNode(node);
- }
-}
-
-/**
- * An object that manages the partitions that can be shared between analysis
- * contexts.
- */
-class PartitionManager {
- /**
- * The default cache size for a Dart SDK partition.
- */
- static int _DEFAULT_SDK_CACHE_SIZE = 256;
-
- /**
- * A table mapping SDK's to the partitions used for those SDK's.
- */
- HashMap<DartSdk, SdkCachePartition> _sdkPartitions =
- new HashMap<DartSdk, SdkCachePartition>();
-
- /**
- * Clear any cached data being maintained by this manager.
- */
- void clearCache() {
- _sdkPartitions.clear();
- }
-
- /**
- * Return the partition being used for the given [sdk], creating the partition
- * if necessary.
- */
- SdkCachePartition forSdk(DartSdk sdk) {
- // Call sdk.context now, because when it creates a new
- // InternalAnalysisContext instance, it calls forSdk() again, so creates an
- // SdkCachePartition instance.
- // So, if we initialize context after "partition == null", we end up
- // with two SdkCachePartition instances.
- InternalAnalysisContext sdkContext = sdk.context;
- // Check cache for an existing partition.
- SdkCachePartition partition = _sdkPartitions[sdk];
- if (partition == null) {
- partition = new SdkCachePartition(sdkContext, _DEFAULT_SDK_CACHE_SIZE);
- _sdkPartitions[sdk] = partition;
- }
- return partition;
- }
-}
-
-/**
- * Representation of a pending computation which is based on the results of
- * analysis that may or may not have been completed.
- */
-class PendingFuture<T> {
- /**
- * The context in which this computation runs.
- */
- final AnalysisContextImpl _context;
-
- /**
- * The source used by this computation to compute its value.
- */
- final Source source;
-
- /**
- * The function which implements the computation.
- */
- final PendingFutureComputer<T> _computeValue;
-
- /**
- * The completer that should be completed once the computation has succeeded.
- */
- CancelableCompleter<T> _completer;
-
- PendingFuture(this._context, this.source, this._computeValue) {
- _completer = new CancelableCompleter<T>(_onCancel);
- }
-
- /**
- * Retrieve the future which will be completed when this object is
- * successfully evaluated.
- */
- CancelableFuture<T> get future => _completer.future;
-
- /**
- * Execute [_computeValue], passing it the given [sourceEntry], and complete
- * the pending future if it's appropriate to do so. If the pending future is
- * completed by this call, true is returned; otherwise false is returned.
- *
- * Once this function has returned true, it should not be called again.
- *
- * Other than completing the future, this method is free of side effects.
- * Note that any code the client has attached to the future will be executed
- * in a microtask, so there is no danger of side effects occurring due to
- * client callbacks.
- */
- bool evaluate(SourceEntry sourceEntry) {
- assert(!_completer.isCompleted);
- try {
- T result = _computeValue(sourceEntry);
- if (result == null) {
- return false;
- } else {
- _completer.complete(result);
- return true;
- }
- } catch (exception, stackTrace) {
- _completer.completeError(exception, stackTrace);
- return true;
- }
- }
-
- /**
- * No further analysis updates are expected which affect this future, so
- * complete it with an AnalysisNotScheduledError in order to avoid
- * deadlocking the client.
- */
- void forciblyComplete() {
- try {
- throw new AnalysisNotScheduledError();
- } catch (exception, stackTrace) {
- _completer.completeError(exception, stackTrace);
- }
- }
-
- void _onCancel() {
- _context._cancelFuture(this);
- }
-}
-
-/**
* Container with global [AnalysisContext] performance statistics.
*/
class PerformanceStatistics {
@@ -10370,44 +2177,6 @@
}
}
-class RecursiveXmlVisitor_ParseHtmlTask_internalPerform
- extends ht.RecursiveXmlVisitor<Object> {
- final ParseHtmlTask ParseHtmlTask_this;
-
- RecordingErrorListener errorListener;
-
- RecursiveXmlVisitor_ParseHtmlTask_internalPerform(
- this.ParseHtmlTask_this, this.errorListener)
- : super();
-
- @override
- Object visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) {
- ParseHtmlTask_this._resolveScriptDirectives(node.script, errorListener);
- return null;
- }
-}
-
-class RecursiveXmlVisitor_ResolveHtmlTask_internalPerform
- extends ht.RecursiveXmlVisitor<Object> {
- final ResolveHtmlTask ResolveHtmlTask_this;
-
- RecordingErrorListener errorListener;
-
- RecursiveXmlVisitor_ResolveHtmlTask_internalPerform(
- this.ResolveHtmlTask_this, this.errorListener)
- : super();
-
- @override
- Object visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) {
- CompilationUnit script = node.script;
- if (script != null) {
- GenerateDartErrorsTask.validateDirectives(ResolveHtmlTask_this.context,
- ResolveHtmlTask_this.source, script, errorListener);
- }
- return null;
- }
-}
-
/**
* An visitor that removes any resolution information from an AST structure when
* used to visit that structure.
@@ -10557,1257 +2326,6 @@
}
/**
- * The information produced by resolving a compilation unit as part of a
- * specific library.
- */
-class ResolutionState {
- /**
- * The next resolution state or `null` if none.
- */
- ResolutionState _nextState;
-
- /**
- * The source for the defining compilation unit of the library that contains
- * this unit. If this unit is the defining compilation unit for it's library,
- * then this will be the source for this unit.
- */
- Source _librarySource;
-
- /**
- * A table mapping descriptors to the cached results for those descriptors.
- * If there is no entry for a given descriptor then the state is implicitly
- * [CacheState.INVALID] and the value is implicitly the default value.
- */
- Map<DataDescriptor, CachedResult> resultMap =
- new HashMap<DataDescriptor, CachedResult>();
-
- /**
- * Flush any AST structures being maintained by this state.
- */
- void flushAstStructures() {
- _flush(DartEntry.BUILT_UNIT);
- _flush(DartEntry.RESOLVED_UNIT);
- if (_nextState != null) {
- _nextState.flushAstStructures();
- }
- }
-
- /**
- * Return the state of the data represented by the given [descriptor].
- */
- CacheState getState(DataDescriptor descriptor) {
- CachedResult result = resultMap[descriptor];
- if (result == null) {
- return CacheState.INVALID;
- }
- return result.state;
- }
-
- /**
- * Return the value of the data represented by the given [descriptor], or
- * `null` if the data represented by the descriptor is not valid.
- */
- /*<V>*/ dynamic /*V*/ getValue(DataDescriptor /*<V>*/ descriptor) {
- CachedResult result = resultMap[descriptor];
- if (result == null) {
- return descriptor.defaultValue;
- }
- return result.value;
- }
-
- /**
- * Return `true` if the state of any data value is [CacheState.ERROR].
- */
- bool hasErrorState() {
- for (CachedResult result in resultMap.values) {
- if (result.state == CacheState.ERROR) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Invalidate all of the resolution information associated with the compilation unit.
- */
- void invalidateAllResolutionInformation() {
- _nextState = null;
- _librarySource = null;
- setState(DartEntry.BUILT_UNIT, CacheState.INVALID);
- setState(DartEntry.BUILT_ELEMENT, CacheState.INVALID);
- setState(DartEntry.HINTS, CacheState.INVALID);
- setState(DartEntry.LINTS, CacheState.INVALID);
- setState(DartEntry.RESOLVED_UNIT, CacheState.INVALID);
- setState(DartEntry.RESOLUTION_ERRORS, CacheState.INVALID);
- setState(DartEntry.VERIFICATION_ERRORS, CacheState.INVALID);
- }
-
- /**
- * Record that an exception occurred while attempting to build the element
- * model for the source associated with this state.
- */
- void recordBuildElementError() {
- setState(DartEntry.BUILT_UNIT, CacheState.ERROR);
- setState(DartEntry.BUILT_ELEMENT, CacheState.ERROR);
- recordResolutionError();
- }
-
- /**
- * Record that an exception occurred while attempting to generate hints for
- * the source associated with this entry. This will set the state of all
- * verification information as being in error.
- */
- void recordHintError() {
- setState(DartEntry.HINTS, CacheState.ERROR);
- }
-
- /**
- * Record that an exception occurred while attempting to generate lints for
- * the source associated with this entry. This will set the state of all
- * verification information as being in error.
- */
- void recordLintError() {
- setState(DartEntry.LINTS, CacheState.ERROR);
- }
-
- /**
- * Record that an exception occurred while attempting to resolve the source
- * associated with this state.
- */
- void recordResolutionError() {
- setState(DartEntry.RESOLVED_UNIT, CacheState.ERROR);
- setState(DartEntry.RESOLUTION_ERRORS, CacheState.ERROR);
- recordVerificationError();
- }
-
- /**
- * Record that an exception occurred while attempting to scan or parse the
- * source associated with this entry. This will set the state of all
- * resolution-based information as being in error.
- */
- void recordResolutionErrorsInAllLibraries() {
- recordBuildElementError();
- if (_nextState != null) {
- _nextState.recordResolutionErrorsInAllLibraries();
- }
- }
-
- /**
- * Record that an exception occurred while attempting to generate errors and
- * warnings for the source associated with this entry. This will set the state
- * of all verification information as being in error.
- */
- void recordVerificationError() {
- setState(DartEntry.VERIFICATION_ERRORS, CacheState.ERROR);
- recordHintError();
- }
-
- /**
- * Set the state of the data represented by the given [descriptor] to the
- * given [state].
- */
- void setState(DataDescriptor descriptor, CacheState state) {
- if (state == CacheState.VALID) {
- throw new ArgumentError("use setValue() to set the state to VALID");
- }
- if (state == CacheState.INVALID) {
- resultMap.remove(descriptor);
- } else {
- CachedResult result =
- resultMap.putIfAbsent(descriptor, () => new CachedResult(descriptor));
- result.state = state;
- if (state != CacheState.IN_PROCESS) {
- //
- // If the state is in-process, we can leave the current value in the
- // cache for any 'get' methods to access.
- //
- result.value = descriptor.defaultValue;
- }
- }
- }
-
- /**
- * Set the value of the data represented by the given [descriptor] to the
- * given [value].
- */
- void setValue(DataDescriptor /*<V>*/ descriptor, dynamic /*V*/ value) {
- CachedResult result =
- resultMap.putIfAbsent(descriptor, () => new CachedResult(descriptor));
- SourceEntry.countTransition(descriptor, result);
- result.state = CacheState.VALID;
- result.value = value == null ? descriptor.defaultValue : value;
- }
-
- /**
- * Flush the value of the data described by the [descriptor].
- */
- void _flush(DataDescriptor descriptor) {
- CachedResult result = resultMap[descriptor];
- if (result != null && result.state == CacheState.VALID) {
- result.state = CacheState.FLUSHED;
- result.value = descriptor.defaultValue;
- }
- }
-
- /**
- * Write a textual representation of the difference between the old entry and
- * this entry to the given string [buffer]. A separator will be written before
- * the first difference if [needsSeparator] is `true`. The [oldEntry] is the
- * entry that was replaced by this entry. Return `true` is a separator is
- * needed before writing any subsequent differences.
- */
- bool _writeDiffOn(
- StringBuffer buffer, bool needsSeparator, DartEntry oldEntry) {
- needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "resolvedUnit",
- DartEntry.RESOLVED_UNIT, oldEntry);
- needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
- "resolutionErrors", DartEntry.RESOLUTION_ERRORS, oldEntry);
- needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
- "verificationErrors", DartEntry.VERIFICATION_ERRORS, oldEntry);
- needsSeparator = _writeStateDiffOn(
- buffer, needsSeparator, "hints", DartEntry.HINTS, oldEntry);
- needsSeparator = _writeStateDiffOn(
- buffer, needsSeparator, "lints", DartEntry.LINTS, oldEntry);
- return needsSeparator;
- }
-
- /**
- * Write a textual representation of this state to the given [buffer]. The
- * result will only be used for debugging purposes.
- */
- void _writeOn(StringBuffer buffer) {
- if (_librarySource != null) {
- _writeStateOn(buffer, "builtElement", DartEntry.BUILT_ELEMENT);
- _writeStateOn(buffer, "builtUnit", DartEntry.BUILT_UNIT);
- _writeStateOn(buffer, "resolvedUnit", DartEntry.RESOLVED_UNIT);
- _writeStateOn(buffer, "resolutionErrors", DartEntry.RESOLUTION_ERRORS);
- _writeStateOn(
- buffer, "verificationErrors", DartEntry.VERIFICATION_ERRORS);
- _writeStateOn(buffer, "hints", DartEntry.HINTS);
- _writeStateOn(buffer, "lints", DartEntry.LINTS);
- if (_nextState != null) {
- _nextState._writeOn(buffer);
- }
- }
- }
-
- /**
- * Write a textual representation of the difference between the state of the
- * value described by the given [descriptor] between the [oldEntry] and this
- * entry to the given [buffer]. Return `true` if some difference was written.
- */
- bool _writeStateDiffOn(StringBuffer buffer, bool needsSeparator, String label,
- DataDescriptor descriptor, SourceEntry oldEntry) {
- CacheState oldState = oldEntry.getState(descriptor);
- CacheState newState = getState(descriptor);
- if (oldState != newState) {
- if (needsSeparator) {
- buffer.write("; ");
- }
- buffer.write(label);
- buffer.write(" = ");
- buffer.write(oldState);
- buffer.write(" -> ");
- buffer.write(newState);
- return true;
- }
- return needsSeparator;
- }
-
- /**
- * Write a textual representation of the state of the value described by the
- * given [descriptor] to the given bugger, prefixed by the given [label] to
- * the given [buffer].
- */
- void _writeStateOn(
- StringBuffer buffer, String label, DataDescriptor descriptor) {
- CachedResult result = resultMap[descriptor];
- buffer.write("; ");
- buffer.write(label);
- buffer.write(" = ");
- buffer.write(result == null ? CacheState.INVALID : result.state);
- }
-}
-
-/**
- * A compilation unit that is not referenced by any other objects. It is used by
- * the [LibraryResolver] to resolve a library.
- */
-class ResolvableCompilationUnit {
- /**
- * The source of the compilation unit.
- */
- final Source source;
-
- /**
- * The compilation unit.
- */
- final CompilationUnit compilationUnit;
-
- /**
- * Initialize a newly created holder to hold the given [source] and
- * [compilationUnit].
- */
- ResolvableCompilationUnit(this.source, this.compilationUnit);
-}
-
-/**
- * Instances of the class `ResolveDartLibraryTask` resolve a specific Dart library.
- */
-class ResolveDartLibraryCycleTask extends AnalysisTask {
- /**
- * The source representing the file whose compilation unit is to be returned. TODO(brianwilkerson)
- * This should probably be removed, but is being left in for now to ease the transition.
- */
- final Source unitSource;
-
- /**
- * The source representing the library to be resolved.
- */
- final Source librarySource;
-
- /**
- * The libraries that are part of the cycle containing the library to be resolved.
- */
- final List<ResolvableLibrary> _librariesInCycle;
-
- /**
- * The library resolver holding information about the libraries that were resolved.
- */
- LibraryResolver2 _resolver;
-
- /**
- * Initialize a newly created task to perform analysis within the given context.
- *
- * @param context the context in which the task is to be performed
- * @param unitSource the source representing the file whose compilation unit is to be returned
- * @param librarySource the source representing the library to be resolved
- * @param librariesInCycle the libraries that are part of the cycle containing the library to be
- * resolved
- */
- ResolveDartLibraryCycleTask(InternalAnalysisContext context, this.unitSource,
- this.librarySource, this._librariesInCycle)
- : super(context);
-
- /**
- * Return the library resolver holding information about the libraries that were resolved.
- *
- * @return the library resolver holding information about the libraries that were resolved
- */
- LibraryResolver2 get libraryResolver => _resolver;
-
- @override
- String get taskDescription {
- if (librarySource == null) {
- return "resolve library null source";
- }
- return "resolve library ${librarySource.fullName}";
- }
-
- @override
- accept(AnalysisTaskVisitor visitor) =>
- visitor.visitResolveDartLibraryCycleTask(this);
-
- @override
- void internalPerform() {
- _resolver = new LibraryResolver2(context);
- _resolver.resolveLibrary(librarySource, _librariesInCycle);
- }
-}
-
-/**
- * Instances of the class `ResolveDartLibraryTask` resolve a specific Dart library.
- */
-class ResolveDartLibraryTask extends AnalysisTask {
- /**
- * The source representing the file whose compilation unit is to be returned.
- */
- final Source unitSource;
-
- /**
- * The source representing the library to be resolved.
- */
- final Source librarySource;
-
- /**
- * The library resolver holding information about the libraries that were resolved.
- */
- LibraryResolver _resolver;
-
- /**
- * Initialize a newly created task to perform analysis within the given context.
- *
- * @param context the context in which the task is to be performed
- * @param unitSource the source representing the file whose compilation unit is to be returned
- * @param librarySource the source representing the library to be resolved
- */
- ResolveDartLibraryTask(
- InternalAnalysisContext context, this.unitSource, this.librarySource)
- : super(context);
-
- /**
- * Return the library resolver holding information about the libraries that were resolved.
- *
- * @return the library resolver holding information about the libraries that were resolved
- */
- LibraryResolver get libraryResolver => _resolver;
-
- @override
- String get taskDescription {
- if (librarySource == null) {
- return "resolve library null source";
- }
- return "resolve library ${librarySource.fullName}";
- }
-
- @override
- accept(AnalysisTaskVisitor visitor) =>
- visitor.visitResolveDartLibraryTask(this);
-
- @override
- void internalPerform() {
- LibraryResolverFactory resolverFactory = context.libraryResolverFactory;
- _resolver = resolverFactory == null
- ? new LibraryResolver(context)
- : resolverFactory(context);
- _resolver.resolveLibrary(librarySource, true);
- }
-}
-
-/**
- * Instances of the class `ResolveDartUnitTask` resolve a single Dart file based on a existing
- * element model.
- */
-class ResolveDartUnitTask extends AnalysisTask {
- /**
- * The source that is to be resolved.
- */
- final Source source;
-
- /**
- * The element model for the library containing the source.
- */
- final LibraryElement _libraryElement;
-
- /**
- * The compilation unit that was resolved by this task.
- */
- CompilationUnit _resolvedUnit;
-
- /**
- * Initialize a newly created task to perform analysis within the given context.
- *
- * @param context the context in which the task is to be performed
- * @param source the source to be parsed
- * @param libraryElement the element model for the library containing the source
- */
- ResolveDartUnitTask(
- InternalAnalysisContext context, this.source, this._libraryElement)
- : super(context);
-
- /**
- * Return the source for the library containing the source that is to be resolved.
- *
- * @return the source for the library containing the source that is to be resolved
- */
- Source get librarySource => _libraryElement.source;
-
- /**
- * Return the compilation unit that was resolved by this task.
- *
- * @return the compilation unit that was resolved by this task
- */
- CompilationUnit get resolvedUnit => _resolvedUnit;
-
- @override
- String get taskDescription {
- Source librarySource = _libraryElement.source;
- if (librarySource == null) {
- return "resolve unit null source";
- }
- return "resolve unit ${librarySource.fullName}";
- }
-
- @override
- accept(AnalysisTaskVisitor visitor) => visitor.visitResolveDartUnitTask(this);
-
- @override
- void internalPerform() {
- TypeProvider typeProvider = _libraryElement.context.typeProvider;
- CompilationUnit unit = context.computeResolvableCompilationUnit(source);
- if (unit == null) {
- throw new AnalysisException(
- "Internal error: computeResolvableCompilationUnit returned a value without a parsed Dart unit");
- }
- //
- // Resolve names in declarations.
- //
- new DeclarationResolver().resolve(unit, _find(_libraryElement, source));
- //
- // Resolve the type names.
- //
- RecordingErrorListener errorListener = new RecordingErrorListener();
- TypeResolverVisitor typeResolverVisitor = new TypeResolverVisitor(
- _libraryElement, source, typeProvider, errorListener);
- unit.accept(typeResolverVisitor);
- //
- // Resolve the rest of the structure
- //
- InheritanceManager inheritanceManager =
- new InheritanceManager(_libraryElement);
- ResolverVisitor resolverVisitor = new ResolverVisitor(
- _libraryElement, source, typeProvider, errorListener,
- inheritanceManager: inheritanceManager);
- unit.accept(resolverVisitor);
- //
- // Perform additional error checking.
- //
- PerformanceStatistics.errors.makeCurrentWhile(() {
- ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
- ErrorVerifier errorVerifier = new ErrorVerifier(
- errorReporter,
- _libraryElement,
- typeProvider,
- inheritanceManager,
- context.analysisOptions.enableSuperMixins);
- unit.accept(errorVerifier);
- // TODO(paulberry): as a temporary workaround for issue 21572,
- // ConstantVerifier is being run right after ConstantValueComputer, so we
- // don't need to run it here. Once issue 21572 is fixed, re-enable the
- // call to ConstantVerifier.
-// ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, _libraryElement, typeProvider);
-// unit.accept(constantVerifier);
- });
- //
- // Capture the results.
- //
- _resolvedUnit = unit;
- }
-
- /**
- * Search the compilation units that are part of the given library and return the element
- * representing the compilation unit with the given source. Return `null` if there is no
- * such compilation unit.
- *
- * @param libraryElement the element representing the library being searched through
- * @param unitSource the source for the compilation unit whose element is to be returned
- * @return the element representing the compilation unit
- */
- CompilationUnitElement _find(
- LibraryElement libraryElement, Source unitSource) {
- CompilationUnitElement element = libraryElement.definingCompilationUnit;
- if (element.source == unitSource) {
- return element;
- }
- for (CompilationUnitElement partElement in libraryElement.parts) {
- if (partElement.source == unitSource) {
- return partElement;
- }
- }
- return null;
- }
-}
-
-/**
- * Instances of the class `ResolveHtmlTask` resolve a specific source as an HTML file.
- */
-class ResolveHtmlTask extends AnalysisTask {
- /**
- * The source to be resolved.
- */
- final Source source;
-
- /**
- * The time at which the contents of the source were last modified.
- */
- final int modificationTime;
-
- /**
- * The HTML unit to be resolved.
- */
- final ht.HtmlUnit _unit;
-
- /**
- * The [HtmlUnit] that was resolved by this task.
- */
- ht.HtmlUnit _resolvedUnit;
-
- /**
- * The element produced by resolving the source.
- */
- HtmlElement _element = null;
-
- /**
- * The resolution errors that were discovered while resolving the source.
- */
- List<AnalysisError> _resolutionErrors = AnalysisError.NO_ERRORS;
-
- /**
- * Initialize a newly created task to perform analysis within the given context.
- *
- * @param context the context in which the task is to be performed
- * @param source the source to be resolved
- * @param modificationTime the time at which the contents of the source were last modified
- * @param unit the HTML unit to be resolved
- */
- ResolveHtmlTask(InternalAnalysisContext context, this.source,
- this.modificationTime, this._unit)
- : super(context);
-
- HtmlElement get element => _element;
-
- List<AnalysisError> get resolutionErrors => _resolutionErrors;
-
- /**
- * Return the [HtmlUnit] that was resolved by this task.
- *
- * @return the [HtmlUnit] that was resolved by this task
- */
- ht.HtmlUnit get resolvedUnit => _resolvedUnit;
-
- @override
- String get taskDescription {
- if (source == null) {
- return "resolve as html null source";
- }
- return "resolve as html ${source.fullName}";
- }
-
- @override
- accept(AnalysisTaskVisitor visitor) => visitor.visitResolveHtmlTask(this);
-
- @override
- void internalPerform() {
- //
- // Build the standard HTML element.
- //
- HtmlUnitBuilder builder = new HtmlUnitBuilder(context);
- _element = builder.buildHtmlElement(source, _unit);
- RecordingErrorListener errorListener = builder.errorListener;
- //
- // Validate the directives
- //
- _unit.accept(new RecursiveXmlVisitor_ResolveHtmlTask_internalPerform(
- this, errorListener));
- //
- // Record all resolution errors.
- //
- _resolutionErrors = errorListener.getErrorsForSource(source);
- //
- // Remember the resolved unit.
- //
- _resolvedUnit = _unit;
- }
-}
-
-/**
- * The priority of data in the cache in terms of the desirability of retaining
- * some specified data about a specified source.
- */
-class RetentionPriority extends Enum<RetentionPriority> {
- /**
- * A priority indicating that a given piece of data can be removed from the
- * cache without reservation.
- */
- static const RetentionPriority LOW = const RetentionPriority('LOW', 0);
-
- /**
- * A priority indicating that a given piece of data should not be removed from
- * the cache unless there are no sources for which the corresponding data has
- * a lower priority. Currently used for data that is needed in order to finish
- * some outstanding analysis task.
- */
- static const RetentionPriority MEDIUM = const RetentionPriority('MEDIUM', 1);
-
- /**
- * A priority indicating that a given piece of data should not be removed from
- * the cache. Currently used for data related to a priority source.
- */
- static const RetentionPriority HIGH = const RetentionPriority('HIGH', 2);
-
- static const List<RetentionPriority> values = const [LOW, MEDIUM, HIGH];
-
- const RetentionPriority(String name, int ordinal) : super(name, ordinal);
-}
-
-/**
- * Instances of the class `ScanDartTask` scan a specific source as a Dart file.
- */
-class ScanDartTask extends AnalysisTask {
- /**
- * The source to be scanned.
- */
- final Source source;
-
- /**
- * The contents of the source.
- */
- final String _content;
-
- /**
- * The token stream that was produced by scanning the source.
- */
- Token _tokenStream;
-
- /**
- * The line information that was produced.
- */
- LineInfo _lineInfo;
-
- /**
- * The errors that were produced by scanning the source.
- */
- List<AnalysisError> _errors = AnalysisError.NO_ERRORS;
-
- /**
- * Initialize a newly created task to perform analysis within the given context.
- *
- * @param context the context in which the task is to be performed
- * @param source the source to be parsed
- * @param content the contents of the source
- */
- ScanDartTask(InternalAnalysisContext context, this.source, this._content)
- : super(context);
-
- /**
- * Return the errors that were produced by scanning the source, or `null` if the task has
- * not yet been performed or if an exception occurred.
- *
- * @return the errors that were produced by scanning the source
- */
- List<AnalysisError> get errors => _errors;
-
- /**
- * Return the line information that was produced, or `null` if the task has not yet been
- * performed or if an exception occurred.
- *
- * @return the line information that was produced
- */
- LineInfo get lineInfo => _lineInfo;
-
- @override
- String get taskDescription {
- if (source == null) {
- return "scan as dart null source";
- }
- return "scan as dart ${source.fullName}";
- }
-
- /**
- * Return the token stream that was produced by scanning the source, or `null` if the task
- * has not yet been performed or if an exception occurred.
- *
- * @return the token stream that was produced by scanning the source
- */
- Token get tokenStream => _tokenStream;
-
- @override
- accept(AnalysisTaskVisitor visitor) => visitor.visitScanDartTask(this);
-
- @override
- void internalPerform() {
- PerformanceStatistics.scan.makeCurrentWhile(() {
- RecordingErrorListener errorListener = new RecordingErrorListener();
- try {
- Scanner scanner = new Scanner(
- source, new CharSequenceReader(_content), errorListener);
- scanner.preserveComments = context.analysisOptions.preserveComments;
- _tokenStream = scanner.tokenize();
- _lineInfo = new LineInfo(scanner.lineStarts);
- _errors = errorListener.getErrorsForSource(source);
- } catch (exception, stackTrace) {
- throw new AnalysisException(
- "Exception", new CaughtException(exception, stackTrace));
- }
- });
- }
-}
-
-/**
- * An [AnalysisContext] that only contains sources for a Dart SDK.
- */
-class SdkAnalysisContext extends AnalysisContextImpl {
- @override
- AnalysisCache createCacheFromSourceFactory(SourceFactory factory) {
- if (factory == null) {
- return super.createCacheFromSourceFactory(factory);
- }
- DartSdk sdk = factory.dartSdk;
- if (sdk == null) {
- throw new IllegalArgumentException(
- "The source factory for an SDK analysis context must have a DartUriResolver");
- }
- return new AnalysisCache(
- <CachePartition>[AnalysisEngine.instance.partitionManager.forSdk(sdk)]);
- }
-}
-
-/**
- * A cache partition that contains all of the sources in the SDK.
- */
-class SdkCachePartition extends CachePartition {
- /**
- * Initialize a newly created partition. The [context] is the context that
- * owns this partition. The [maxCacheSize] is the maximum number of sources
- * for which AST structures should be kept in the cache.
- */
- SdkCachePartition(InternalAnalysisContext context, int maxCacheSize)
- : super(context, maxCacheSize, DefaultRetentionPolicy.POLICY);
-
- @override
- bool contains(Source source) => source.isInSystemLibrary;
-}
-
-/**
- * The information cached by an analysis context about an individual source, no
- * matter what kind of source it is.
- */
-abstract class SourceEntry {
- /**
- * The data descriptor representing the contents of the source.
- */
- static final DataDescriptor<String> CONTENT =
- new DataDescriptor<String>("SourceEntry.CONTENT");
-
- /**
- * The data descriptor representing the errors resulting from reading the
- * source content.
- */
- static final DataDescriptor<List<AnalysisError>> CONTENT_ERRORS =
- new DataDescriptor<List<AnalysisError>>(
- "SourceEntry.CONTENT_ERRORS", AnalysisError.NO_ERRORS);
-
- /**
- * The data descriptor representing the line information.
- */
- static final DataDescriptor<LineInfo> LINE_INFO =
- new DataDescriptor<LineInfo>("SourceEntry.LINE_INFO");
-
- /**
- * The index of the flag indicating whether the source was explicitly added to
- * the context or whether the source was implicitly added because it was
- * referenced by another source.
- */
- static int _EXPLICITLY_ADDED_FLAG = 0;
-
- /**
- * A table mapping data descriptors to a count of the number of times a value
- * was set when in a given state.
- */
- static final Map<DataDescriptor, Map<CacheState, int>> transitionMap =
- new HashMap<DataDescriptor, Map<CacheState, int>>();
-
- /**
- * The most recent time at which the state of the source matched the state
- * represented by this entry.
- */
- int modificationTime = 0;
-
- /**
- * The exception that caused one or more values to have a state of
- * [CacheState.ERROR].
- */
- CaughtException exception;
-
- /**
- * A bit-encoding of boolean flags associated with this element.
- */
- int _flags = 0;
-
- /**
- * A table mapping data descriptors to the cached results for those
- * descriptors.
- */
- Map<DataDescriptor, CachedResult> resultMap =
- new HashMap<DataDescriptor, CachedResult>();
-
- /**
- * Return all of the errors associated with this entry.
- */
- List<AnalysisError> get allErrors {
- return getValue(CONTENT_ERRORS);
- }
-
- /**
- * Get a list of all the library-independent descriptors for which values may
- * be stored in this SourceEntry.
- */
- List<DataDescriptor> get descriptors {
- return <DataDescriptor>[CONTENT, CONTENT_ERRORS, LINE_INFO];
- }
-
- /**
- * Return `true` if the source was explicitly added to the context or `false`
- * if the source was implicitly added because it was referenced by another
- * source.
- */
- bool get explicitlyAdded => _getFlag(_EXPLICITLY_ADDED_FLAG);
-
- /**
- * Set whether the source was explicitly added to the context to match the
- * [explicitlyAdded] flag.
- */
- void set explicitlyAdded(bool explicitlyAdded) {
- _setFlag(_EXPLICITLY_ADDED_FLAG, explicitlyAdded);
- }
-
- /**
- * Return the kind of the source, or `null` if the kind is not currently
- * cached.
- */
- SourceKind get kind;
-
- /**
- * Fix the state of the [exception] to match the current state of the entry.
- */
- void fixExceptionState() {
- if (hasErrorState()) {
- if (exception == null) {
- //
- // This code should never be reached, but is a fail-safe in case an
- // exception is not recorded when it should be.
- //
- String message = "State set to ERROR without setting an exception";
- exception = new CaughtException(new AnalysisException(message), null);
- }
- } else {
- exception = null;
- }
- }
-
- /**
- * Return a textual representation of the difference between the [oldEntry]
- * and this entry. The difference is represented as a sequence of fields whose
- * value would change if the old entry were converted into the new entry.
- */
- String getDiff(SourceEntry oldEntry) {
- StringBuffer buffer = new StringBuffer();
- _writeDiffOn(buffer, oldEntry);
- return buffer.toString();
- }
-
- /**
- * Return the state of the data represented by the given [descriptor].
- */
- CacheState getState(DataDescriptor descriptor) {
- if (!_isValidDescriptor(descriptor)) {
- throw new ArgumentError("Invalid descriptor: $descriptor");
- }
- CachedResult result = resultMap[descriptor];
- if (result == null) {
- return CacheState.INVALID;
- }
- return result.state;
- }
-
- /**
- * Return the value of the data represented by the given [descriptor], or
- * `null` if the data represented by the descriptor is not valid.
- */
- /*<V>*/ dynamic /*V*/ getValue(DataDescriptor /*<V>*/ descriptor) {
- if (!_isValidDescriptor(descriptor)) {
- throw new ArgumentError("Invalid descriptor: $descriptor");
- }
- CachedResult result = resultMap[descriptor];
- if (result == null) {
- return descriptor.defaultValue;
- }
- return result.value;
- }
-
- /**
- * Return `true` if the state of any data value is [CacheState.ERROR].
- */
- bool hasErrorState() {
- for (CachedResult result in resultMap.values) {
- if (result.state == CacheState.ERROR) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Invalidate all of the information associated with this source.
- */
- void invalidateAllInformation() {
- setState(CONTENT, CacheState.INVALID);
- setState(CONTENT_ERRORS, CacheState.INVALID);
- setState(LINE_INFO, CacheState.INVALID);
- }
-
- /**
- * Record that an [exception] occurred while attempting to get the contents of
- * the source represented by this entry. This will set the state of all
- * information, including any resolution-based information, as being in error.
- */
- void recordContentError(CaughtException exception) {
- setState(CONTENT, CacheState.ERROR);
- recordScanError(exception);
- }
-
- /**
- * Record that an [exception] occurred while attempting to scan or parse the
- * entry represented by this entry. This will set the state of all
- * information, including any resolution-based information, as being in error.
- */
- void recordScanError(CaughtException exception) {
- this.exception = exception;
- setState(LINE_INFO, CacheState.ERROR);
- }
-
- /**
- * Set the state of the data represented by the given [descriptor] to the
- * given [state].
- */
- void setState(DataDescriptor descriptor, CacheState state) {
- if (!_isValidDescriptor(descriptor)) {
- throw new ArgumentError("Invalid descriptor: $descriptor");
- }
- if (state == CacheState.VALID) {
- throw new ArgumentError("use setValue() to set the state to VALID");
- }
- _validateStateChange(descriptor, state);
- if (state == CacheState.INVALID) {
- resultMap.remove(descriptor);
- } else {
- CachedResult result =
- resultMap.putIfAbsent(descriptor, () => new CachedResult(descriptor));
- result.state = state;
- if (state != CacheState.IN_PROCESS) {
- //
- // If the state is in-process, we can leave the current value in the
- // cache for any 'get' methods to access.
- //
- result.value = descriptor.defaultValue;
- }
- }
- }
-
- /**
- * Set the value of the data represented by the given [descriptor] to the
- * given [value].
- */
- void setValue(DataDescriptor /*<V>*/ descriptor, dynamic /*V*/ value) {
- if (!_isValidDescriptor(descriptor)) {
- throw new ArgumentError("Invalid descriptor: $descriptor");
- }
- _validateStateChange(descriptor, CacheState.VALID);
- CachedResult result =
- resultMap.putIfAbsent(descriptor, () => new CachedResult(descriptor));
- countTransition(descriptor, result);
- result.state = CacheState.VALID;
- result.value = value == null ? descriptor.defaultValue : value;
- }
-
- @override
- String toString() {
- StringBuffer buffer = new StringBuffer();
- _writeOn(buffer);
- return buffer.toString();
- }
-
- /**
- * Flush the value of the data described by the [descriptor].
- */
- void _flush(DataDescriptor descriptor) {
- CachedResult result = resultMap[descriptor];
- if (result != null && result.state == CacheState.VALID) {
- _validateStateChange(descriptor, CacheState.FLUSHED);
- result.state = CacheState.FLUSHED;
- result.value = descriptor.defaultValue;
- }
- }
-
- /**
- * Return the value of the flag with the given [index].
- */
- bool _getFlag(int index) => BooleanArray.get(_flags, index);
-
- /**
- * Return `true` if the [descriptor] is valid for this entry.
- */
- bool _isValidDescriptor(DataDescriptor descriptor) {
- return descriptor == CONTENT ||
- descriptor == CONTENT_ERRORS ||
- descriptor == LINE_INFO;
- }
-
- /**
- * Set the value of the flag with the given [index] to the given [value].
- */
- void _setFlag(int index, bool value) {
- _flags = BooleanArray.set(_flags, index, value);
- }
-
- /**
- * If the state of the value described by the given [descriptor] is changing
- * from ERROR to anything else, capture the information. This is an attempt to
- * discover the underlying cause of a long-standing bug.
- */
- void _validateStateChange(DataDescriptor descriptor, CacheState newState) {
- // TODO(brianwilkerson) Decide whether we still want to capture this data.
-// if (descriptor != CONTENT) {
-// return;
-// }
-// CachedResult result = resultMap[CONTENT];
-// if (result != null && result.state == CacheState.ERROR) {
-// String message =
-// "contentState changing from ${result.state} to $newState";
-// InstrumentationBuilder builder =
-// Instrumentation.builder2("SourceEntry-validateStateChange");
-// builder.data3("message", message);
-// //builder.data("source", source.getFullName());
-// builder.record(new CaughtException(new AnalysisException(message), null));
-// builder.log();
-// }
- }
-
- /**
- * Write a textual representation of the difference between the [oldEntry] and
- * this entry to the given string [buffer]. Return `true` if some difference
- * was written.
- */
- bool _writeDiffOn(StringBuffer buffer, SourceEntry oldEntry) {
- bool needsSeparator = false;
- CaughtException oldException = oldEntry.exception;
- if (!identical(oldException, exception)) {
- buffer.write("exception = ");
- buffer.write(oldException.runtimeType);
- buffer.write(" -> ");
- buffer.write(exception.runtimeType);
- needsSeparator = true;
- }
- int oldModificationTime = oldEntry.modificationTime;
- if (oldModificationTime != modificationTime) {
- if (needsSeparator) {
- buffer.write("; ");
- }
- buffer.write("time = ");
- buffer.write(oldModificationTime);
- buffer.write(" -> ");
- buffer.write(modificationTime);
- needsSeparator = true;
- }
- needsSeparator =
- _writeStateDiffOn(buffer, needsSeparator, "content", CONTENT, oldEntry);
- needsSeparator = _writeStateDiffOn(
- buffer, needsSeparator, "contentErrors", CONTENT_ERRORS, oldEntry);
- needsSeparator = _writeStateDiffOn(
- buffer, needsSeparator, "lineInfo", LINE_INFO, oldEntry);
- return needsSeparator;
- }
-
- /**
- * Write a textual representation of this entry to the given [buffer]. The
- * result should only be used for debugging purposes.
- */
- void _writeOn(StringBuffer buffer) {
- buffer.write("time = ");
- buffer.write(modificationTime);
- _writeStateOn(buffer, "content", CONTENT);
- _writeStateOn(buffer, "contentErrors", CONTENT_ERRORS);
- _writeStateOn(buffer, "lineInfo", LINE_INFO);
- }
-
- /**
- * Write a textual representation of the difference between the state of the
- * value described by the given [descriptor] between the [oldEntry] and this
- * entry to the given [buffer]. Return `true` if some difference was written.
- */
- bool _writeStateDiffOn(StringBuffer buffer, bool needsSeparator, String label,
- DataDescriptor descriptor, SourceEntry oldEntry) {
- CacheState oldState = oldEntry.getState(descriptor);
- CacheState newState = getState(descriptor);
- if (oldState != newState) {
- if (needsSeparator) {
- buffer.write("; ");
- }
- buffer.write(label);
- buffer.write(" = ");
- buffer.write(oldState);
- buffer.write(" -> ");
- buffer.write(newState);
- return true;
- }
- return needsSeparator;
- }
-
- /**
- * Write a textual representation of the state of the value described by the
- * given [descriptor] to the given bugger, prefixed by the given [label] to
- * the given [buffer].
- */
- void _writeStateOn(
- StringBuffer buffer, String label, DataDescriptor descriptor) {
- CachedResult result = resultMap[descriptor];
- buffer.write("; ");
- buffer.write(label);
- buffer.write(" = ");
- buffer.write(result == null ? CacheState.INVALID : result.state);
- }
-
- /**
- * Increment the count of the number of times that data represented by the
- * given [descriptor] was transitioned from the current state (as found in the
- * given [result] to a valid state.
- */
- static void countTransition(DataDescriptor descriptor, CachedResult result) {
- Map<CacheState, int> countMap = transitionMap.putIfAbsent(
- descriptor, () => new HashMap<CacheState, int>());
- int count = countMap[result.state];
- countMap[result.state] = count == null ? 1 : count + 1;
- }
-}
-
-/**
- * The priority levels used to return sources in an optimal order. A smaller
- * ordinal value equates to a higher priority.
- */
-class SourcePriority extends Enum<SourcePriority> {
- /**
- * Used for a Dart source that is known to be a part contained in a library
- * that was recently resolved. These parts are given a higher priority because
- * there is a high probability that their AST structure is still in the cache
- * and therefore would not need to be re-created.
- */
- static const SourcePriority PRIORITY_PART =
- const SourcePriority('PRIORITY_PART', 0);
-
- /**
- * Used for a Dart source that is known to be a library.
- */
- static const SourcePriority LIBRARY = const SourcePriority('LIBRARY', 1);
-
- /**
- * Used for a Dart source whose kind is unknown.
- */
- static const SourcePriority UNKNOWN = const SourcePriority('UNKNOWN', 2);
-
- /**
- * Used for a Dart source that is known to be a part but whose library has not
- * yet been resolved.
- */
- static const SourcePriority NORMAL_PART =
- const SourcePriority('NORMAL_PART', 3);
-
- /**
- * Used for an HTML source.
- */
- static const SourcePriority HTML = const SourcePriority('HTML', 4);
-
- static const List<SourcePriority> values = const [
- PRIORITY_PART,
- LIBRARY,
- UNKNOWN,
- NORMAL_PART,
- HTML
- ];
-
- const SourcePriority(String name, int ordinal) : super(name, ordinal);
-}
-
-/**
* [SourcesChangedEvent] indicates which sources have been added, removed,
* or whose contents have changed.
*/
@@ -11862,8 +2380,8 @@
*/
bool get wereSourcesRemovedOrDeleted =>
_changeSet.removedSources.length > 0 ||
- _changeSet.removedContainers.length > 0 ||
- _changeSet.deletedSources.length > 0;
+ _changeSet.removedContainers.length > 0 ||
+ _changeSet.deletedSources.length > 0;
}
/**
@@ -11886,280 +2404,3 @@
*/
TimestampedData(this.modificationTime, this.data);
}
-
-/**
- * A cache partition that contains all sources not contained in other
- * partitions.
- */
-class UniversalCachePartition extends CachePartition {
- /**
- * Initialize a newly created partition. The [context] is the context that
- * owns this partition. The [maxCacheSize] is the maximum number of sources
- * for which AST structures should be kept in the cache. The [retentionPolicy]
- * is the policy used to determine which pieces of data to remove from the
- * cache.
- */
- UniversalCachePartition(InternalAnalysisContext context, int maxCacheSize,
- CacheRetentionPolicy retentionPolicy)
- : super(context, maxCacheSize, retentionPolicy);
-
- @override
- bool contains(Source source) => true;
-}
-
-/**
- * The unique instances of the class `WaitForAsyncTask` represents a state in which there is
- * no analysis work that can be done until some asynchronous task (such as IO) has completed, but
- * where analysis is not yet complete.
- */
-class WaitForAsyncTask extends AnalysisTask {
- /**
- * The unique instance of this class.
- */
- static WaitForAsyncTask _UniqueInstance = new WaitForAsyncTask();
-
- /**
- * Return the unique instance of this class.
- *
- * @return the unique instance of this class
- */
- static WaitForAsyncTask get instance => _UniqueInstance;
-
- /**
- * Prevent the creation of instances of this class.
- */
- WaitForAsyncTask() : super(null);
-
- @override
- String get taskDescription => "Waiting for async analysis";
-
- @override
- accept(AnalysisTaskVisitor visitor) => null;
-
- @override
- void internalPerform() {
- // There is no work to be done.
- }
-}
-
-/**
- * An object that manages a list of sources that need to have analysis work
- * performed on them.
- */
-class WorkManager {
- /**
- * A list containing the various queues is priority order.
- */
- List<List<Source>> _workQueues;
-
- /**
- * Initialize a newly created manager to have no work queued up.
- */
- WorkManager() {
- int queueCount = SourcePriority.values.length;
- _workQueues = new List<List<Source>>(queueCount);
- for (int i = 0; i < queueCount; i++) {
- _workQueues[i] = new List<Source>();
- }
- }
-
- /**
- * Record that the given [source] needs to be analyzed. The [priority] level
- * is used to control when the source will be analyzed with respect to other
- * sources. If the source was previously added then it's priority is updated.
- * If it was previously added with the same priority then it's position in the
- * queue is unchanged.
- */
- void add(Source source, SourcePriority priority) {
- int queueCount = _workQueues.length;
- int ordinal = priority.ordinal;
- for (int i = 0; i < queueCount; i++) {
- List<Source> queue = _workQueues[i];
- if (i == ordinal) {
- if (!queue.contains(source)) {
- queue.add(source);
- }
- } else {
- queue.remove(source);
- }
- }
- }
-
- /**
- * Record that the given [source] needs to be analyzed. The [priority] level
- * is used to control when the source will be analyzed with respect to other
- * sources. If the source was previously added then it's priority is updated.
- * In either case, it will be analyzed before other sources of the same
- * priority.
- */
- void addFirst(Source source, SourcePriority priority) {
- int queueCount = _workQueues.length;
- int ordinal = priority.ordinal;
- for (int i = 0; i < queueCount; i++) {
- List<Source> queue = _workQueues[i];
- if (i == ordinal) {
- queue.remove(source);
- queue.insert(0, source);
- } else {
- queue.remove(source);
- }
- }
- }
-
- /**
- * Return an iterator that can be used to access the sources to be analyzed in
- * the order in which they should be analyzed.
- *
- * <b>Note:</b> As with other iterators, no sources can be added or removed
- * from this work manager while the iterator is being used. Unlike some
- * implementations, however, the iterator will not detect when this
- * requirement has been violated; it might work correctly, it might return the
- * wrong source, or it might throw an exception.
- */
- WorkManager_WorkIterator iterator() => new WorkManager_WorkIterator(this);
-
- /**
- * Record that the given source is fully analyzed.
- */
- void remove(Source source) {
- int queueCount = _workQueues.length;
- for (int i = 0; i < queueCount; i++) {
- _workQueues[i].remove(source);
- }
- }
-
- @override
- String toString() {
- StringBuffer buffer = new StringBuffer();
- List<SourcePriority> priorities = SourcePriority.values;
- bool needsSeparator = false;
- int queueCount = _workQueues.length;
- for (int i = 0; i < queueCount; i++) {
- List<Source> queue = _workQueues[i];
- if (!queue.isEmpty) {
- if (needsSeparator) {
- buffer.write("; ");
- }
- buffer.write(priorities[i]);
- buffer.write(": ");
- int queueSize = queue.length;
- for (int j = 0; j < queueSize; j++) {
- if (j > 0) {
- buffer.write(", ");
- }
- buffer.write(queue[j].fullName);
- }
- needsSeparator = true;
- }
- }
- return buffer.toString();
- }
-}
-
-/**
- * An iterator that returns the sources in a work manager in the order in which
- * they are to be analyzed.
- */
-class WorkManager_WorkIterator {
- final WorkManager _manager;
-
- /**
- * The index of the work queue through which we are currently iterating.
- */
- int _queueIndex = 0;
-
- /**
- * The index of the next element of the work queue to be returned.
- */
- int _index = -1;
-
- /**
- * Initialize a newly created iterator to be ready to return the first element
- * in the iteration.
- */
- WorkManager_WorkIterator(this._manager) {
- _advance();
- }
-
- /**
- * Return `true` if there is another [Source] available for processing.
- */
- bool get hasNext => _queueIndex < _manager._workQueues.length;
-
- /**
- * Return the next [Source] available for processing and advance so that the
- * returned source will not be returned again.
- */
- Source next() {
- if (!hasNext) {
- throw new NoSuchElementException();
- }
- Source source = _manager._workQueues[_queueIndex][_index];
- _advance();
- return source;
- }
-
- /**
- * Increment the [index] and [queueIndex] so that they are either indicating
- * the next source to be returned or are indicating that there are no more
- * sources to be returned.
- */
- void _advance() {
- _index++;
- if (_index >= _manager._workQueues[_queueIndex].length) {
- _index = 0;
- _queueIndex++;
- while (_queueIndex < _manager._workQueues.length &&
- _manager._workQueues[_queueIndex].isEmpty) {
- _queueIndex++;
- }
- }
- }
-}
-
-/**
- * A helper class used to create futures for AnalysisContextImpl. Using a helper
- * class allows us to preserve the generic parameter T.
- */
-class _AnalysisFutureHelper<T> {
- final AnalysisContextImpl _context;
-
- _AnalysisFutureHelper(this._context);
-
- /**
- * Return a future that will be completed with the result of calling
- * [computeValue]. If [computeValue] returns non-null, the future will be
- * completed immediately with the resulting value. If it returns null, then
- * it will be re-executed in the future, after the next time the cached
- * information for [source] has changed. If [computeValue] throws an
- * exception, the future will fail with that exception.
- *
- * If the [computeValue] still returns null after there is no further
- * analysis to be done for [source], then the future will be completed with
- * the error AnalysisNotScheduledError.
- *
- * Since [computeValue] will be called while the state of analysis is being
- * updated, it should be free of side effects so that it doesn't cause
- * reentrant changes to the analysis state.
- */
- CancelableFuture<T> computeAsync(
- Source source, T computeValue(SourceEntry sourceEntry)) {
- if (_context.isDisposed) {
- // No further analysis is expected, so return a future that completes
- // immediately with AnalysisNotScheduledError.
- return new CancelableFuture.error(new AnalysisNotScheduledError());
- }
- SourceEntry sourceEntry = _context.getReadableSourceEntryOrNull(source);
- if (sourceEntry == null) {
- return new CancelableFuture.error(new AnalysisNotScheduledError());
- }
- PendingFuture pendingFuture =
- new PendingFuture<T>(_context, source, computeValue);
- if (!pendingFuture.evaluate(sourceEntry)) {
- _context._pendingFutureSources
- .putIfAbsent(source, () => <PendingFuture>[])
- .add(pendingFuture);
- }
- return pendingFuture.future;
- }
-}
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index f547807..621b72d 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -2,10 +2,11 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.error;
+library analyzer.src.generated.error;
import 'dart:collection';
+import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/generated/ast.dart' show AstNode;
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/java_core.dart';
@@ -18,18 +19,11 @@
import 'package:source_span/source_span.dart';
/**
- * The descriptor used to associate error filters with analysis contexts in
+ * The descriptor used to associate error processors with analysis contexts in
* configuration data.
*/
-final ListResultDescriptor<List<ErrorFilter>> CONFIGURED_ERROR_FILTERS =
- new ListResultDescriptorImpl('configured.errors', const <ErrorFilter>[]);
-
-/**
- * A predicate used to potentially filter an [error].
- *
- * Returns `true` if this error should be filtered from analysis results.
- */
-typedef bool ErrorFilter(AnalysisError error);
+final ListResultDescriptor<List<ErrorProcessor>> CONFIGURED_ERROR_PROCESSORS =
+ new ListResultDescriptorImpl('configured.errors', const <ErrorProcessor>[]);
/**
* An error discovered during the analysis of some Dart code.
@@ -124,27 +118,6 @@
}
/**
- * Initialize a newly created analysis error for the specified [source]. The
- * error will have the given [errorCode] and the list of [arguments] will be
- * used to complete the message. The error has no location information.
- */
- @deprecated // Use new AnalysisError(source, 0, 0, errorCode, arguments)
- AnalysisError.con1(Source source, ErrorCode errorCode,
- [List<Object> arguments])
- : this(source, 0, 0, errorCode, arguments);
-
- /**
- * Initialize a newly created analysis error for the specified [source] at the
- * given [offset] with the given [length]. The error will have the given
- * [errorCode] and the list of [arguments] will be used to complete the
- * message.
- */
- @deprecated // Use new AnalysisError(source, offset, length, errorCode, arguments)
- AnalysisError.con2(Source source, int offset, int length, ErrorCode errorCode,
- [List<Object> arguments])
- : this(source, offset, length, errorCode, arguments);
-
- /**
* Return the template used to create the correction to be displayed for this
* error, or `null` if there is no correction information for this error. The
* correction should indicate how the user can fix the error.
@@ -278,28 +251,6 @@
[List<Object> arguments])
: super(source, offset, length, errorCode, arguments);
- /**
- * Initialize a newly created analysis error for the specified [source]. The
- * error will have the given [errorCode] and the list of [arguments] will be
- * used to complete the message. The error has no location information.
- */
- @deprecated // Use new AnalysisErrorWithProperties(source, 0, 0, errorCode, arguments)
- AnalysisErrorWithProperties.con1(Source source, ErrorCode errorCode,
- [List<Object> arguments])
- : this(source, 0, 0, errorCode, arguments);
-
- /**
- * Initialize a newly created analysis error for the specified [source] at the
- * given [offset] with the given [length]. The error will have the given
- * [errorCode] and the list of [arguments] will be used to complete the
- * message.
- */
- @deprecated // Use new AnalysisErrorWithProperties(source, offset, length, errorCode, arguments)
- AnalysisErrorWithProperties.con2(
- Source source, int offset, int length, ErrorCode errorCode,
- [List<Object> arguments])
- : this(source, offset, length, errorCode, arguments);
-
@override
Object getProperty(ErrorProperty property) => _propertyMap[property];
@@ -1178,6 +1129,15 @@
"This class cannot extend the deferred class '{0}'");
/**
+ * DEP 37 extends the syntax for assert() to allow a second "message"
+ * argument. We issue this error if the user tries to supply a "message"
+ * argument but the DEP is not enabled.
+ */
+ static const CompileTimeErrorCode EXTRA_ARGUMENT_TO_ASSERT =
+ const CompileTimeErrorCode('EXTRA_ARGUMENT_TO_ASSERT',
+ "Assertions only accept a single argument");
+
+ /**
* 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m <
* h</i> or if <i>m > n</i>.
*
@@ -3690,6 +3650,12 @@
const HintCode('UNNECESSARY_CAST', "Unnecessary cast");
/**
+ * Unnecessary `noSuchMethod` declaration.
+ */
+ static const HintCode UNNECESSARY_NO_SUCH_METHOD = const HintCode(
+ 'UNNECESSARY_NO_SUCH_METHOD', "Unnecessary 'noSuchMethod' declaration");
+
+ /**
* Unnecessary type checks, the result is always true.
*/
static const HintCode UNNECESSARY_TYPE_CHECK_FALSE = const HintCode(
@@ -4897,6 +4863,35 @@
"The parameter type '{0}' is not assignable to '{1}' as required by the method it is overriding from '{2}'");
/**
+ * Generic Method DEP: number of type parameters must match.
+ * <https://github.com/leafpetersen/dep-generic-methods/blob/master/proposal.md#function-subtyping>
+ *
+ * Parameters:
+ * 0: the number of type parameters in the method
+ * 1: the number of type parameters in the overridden method
+ * 2: the name of the class where the overridden method is declared
+ */
+ static const StaticWarningCode INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS =
+ const StaticWarningCode('INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS',
+ "The method has {0} type parameters, but it is overriding a method with {1} type parameters from '{2}'");
+
+ /**
+ * Generic Method DEP: bounds of type parameters must be compatible.
+ * <https://github.com/leafpetersen/dep-generic-methods/blob/master/proposal.md#function-subtyping>
+ *
+ * Parameters:
+ * 0: the type parameter name
+ * 1: the type parameter bound
+ * 2: the overridden type parameter name
+ * 3: the overridden type parameter bound
+ * 4: the name of the class where the overridden method is declared
+ */
+ static const StaticWarningCode INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND =
+ const StaticWarningCode(
+ 'INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND',
+ "The type parameter '{0}' extends '{1}', but that is stricter than '{2}' extends '{3}' in the overridden method from '{4}'");
+
+ /**
* 7.1 Instance Methods: It is a static warning if an instance method
* <i>m1</i> overrides an instance method <i>m2</i> and the type of <i>m1</i>
* is not a subtype of the type of <i>m2</i>.
@@ -4974,11 +4969,12 @@
*
* Parameters:
* 0: the number of named parameters in the overridden member
- * 1: the name of the class from the overridden method
+ * 1: the signature of the overridden member
+ * 2: the name of the class from the overridden method
*/
static const StaticWarningCode INVALID_OVERRIDE_NAMED = const StaticWarningCode(
'INVALID_OVERRIDE_NAMED',
- "Missing the named parameter '{0}' to match the overridden method from '{1}'");
+ "Missing the named parameter '{0}' to match the overridden method from '{1}' from '{2}'");
/**
* 7.1 Instance Methods: It is a static warning if an instance method
@@ -4987,11 +4983,12 @@
*
* Parameters:
* 0: the number of positional parameters in the overridden member
- * 1: the name of the class from the overridden method
+ * 1: the signature of the overridden member
+ * 2: the name of the class from the overridden method
*/
static const StaticWarningCode INVALID_OVERRIDE_POSITIONAL =
const StaticWarningCode('INVALID_OVERRIDE_POSITIONAL',
- "Must have at least {0} parameters to match the overridden method from '{1}'");
+ "Must have at least {0} parameters to match the overridden method '{1}' from '{2}'");
/**
* 7.1 Instance Methods: It is a static warning if an instance method
@@ -5000,11 +4997,12 @@
*
* Parameters:
* 0: the number of required parameters in the overridden member
- * 1: the name of the class from the overridden method
+ * 1: the signature of the overridden member
+ * 2: the name of the class from the overridden method
*/
static const StaticWarningCode INVALID_OVERRIDE_REQUIRED =
const StaticWarningCode('INVALID_OVERRIDE_REQUIRED',
- "Must have {0} required parameters or less to match the overridden method from '{1}'");
+ "Must have {0} required parameters or less to match the overridden method '{1}' from '{2}'");
/**
* 7.3 Setters: It is a static warning if a setter <i>m1</i> overrides a
@@ -5477,7 +5475,7 @@
*/
static const StaticWarningCode TYPE_PARAMETER_REFERENCED_BY_STATIC =
const StaticWarningCode('TYPE_PARAMETER_REFERENCED_BY_STATIC',
- "Static members cannot reference type parameters");
+ "Static members cannot reference type parameters of the class");
/**
* 12.16.3 Static Invocation: A static method invocation <i>i</i> has the form
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index f76ab09..ef6300b 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -2,24 +2,24 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.resolver.error_verifier;
+library analyzer.src.generated.error_verifier;
import 'dart:collection';
import "dart:math" as math;
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/element_resolver.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/parser.dart'
+ show Parser, ParserErrorCode;
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart' as sc;
+import 'package:analyzer/src/generated/sdk.dart' show DartSdk, SdkLibrary;
import 'package:analyzer/src/generated/static_type_analyzer.dart';
-
-import 'ast.dart';
-import 'constant.dart';
-import 'element.dart';
-import 'element_resolver.dart';
-import 'error.dart';
-import 'java_engine.dart';
-import 'parser.dart' show Parser, ParserErrorCode;
-import 'resolver.dart';
-import 'scanner.dart' as sc;
-import 'sdk.dart' show DartSdk, SdkLibrary;
-import 'utilities_dart.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
/**
* A visitor used to traverse an AST structure looking for additional errors and
@@ -266,10 +266,21 @@
final bool enableSuperMixins;
/**
+ * If `true`, asserts are allowed to take a second argument representing the
+ * assertion failure message (see DEP 37).
+ */
+ final bool enableAssertMessage;
+
+ /**
* Initialize a newly created error verifier.
*/
- ErrorVerifier(this._errorReporter, this._currentLibrary, this._typeProvider,
- this._inheritanceManager, this.enableSuperMixins) {
+ ErrorVerifier(
+ this._errorReporter,
+ this._currentLibrary,
+ this._typeProvider,
+ this._inheritanceManager,
+ this.enableSuperMixins,
+ this.enableAssertMessage) {
this._isInSystemLibrary = _currentLibrary.source.isInSystemLibrary;
this._hasExtUri = _currentLibrary.hasExtUri;
_isEnclosingConstructorConst = false;
@@ -306,6 +317,7 @@
@override
Object visitAssertStatement(AssertStatement node) {
_checkForNonBoolExpression(node);
+ _checkAssertMessage(node);
return super.visitAssertStatement(node);
}
@@ -1117,6 +1129,19 @@
}
/**
+ * If the given assert [statement] specifies a message, verify that support
+ * for assertions with messages is enabled.
+ */
+ void _checkAssertMessage(AssertStatement statement) {
+ Expression expression = statement.message;
+ if (expression != null && !enableAssertMessage) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.EXTRA_ARGUMENT_TO_ASSERT, expression);
+ return;
+ }
+ }
+
+ /**
* Verify that the given list of [typeArguments] contains exactly two
* elements.
*
@@ -1322,6 +1347,71 @@
if (overridingFT == null || overriddenFT == null) {
return false;
}
+
+ // Handle generic function type parameters.
+ // TODO(jmesserly): this duplicates some code in isSubtypeOf and most of
+ // _isGenericFunctionSubtypeOf. Ideally, we'd let TypeSystem produce
+ // an error message once it's ready to "return false".
+ if (!overridingFT.boundTypeParameters.isEmpty) {
+ if (overriddenFT.boundTypeParameters.isEmpty) {
+ overriddenFT = _typeSystem.instantiateToBounds(overriddenFT);
+ } else {
+ List<TypeParameterElement> params1 = overridingFT.boundTypeParameters;
+ List<TypeParameterElement> params2 = overriddenFT.boundTypeParameters;
+ int count = params1.length;
+ if (params2.length != count) {
+ _errorReporter.reportErrorForNode(
+ StaticWarningCode.INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS,
+ errorNameTarget, [
+ count,
+ params2.length,
+ overriddenExecutable.enclosingElement.displayName
+ ]);
+ return true;
+ }
+ // We build up a substitution matching up the type parameters
+ // from the two types, {variablesFresh/variables1} and
+ // {variablesFresh/variables2}
+ List<DartType> variables1 = new List<DartType>();
+ List<DartType> variables2 = new List<DartType>();
+ List<DartType> variablesFresh = new List<DartType>();
+ for (int i = 0; i < count; i++) {
+ TypeParameterElement p1 = params1[i];
+ TypeParameterElement p2 = params2[i];
+ TypeParameterElementImpl pFresh =
+ new TypeParameterElementImpl(p1.name, -1);
+
+ DartType variable1 = p1.type;
+ DartType variable2 = p2.type;
+ DartType variableFresh = new TypeParameterTypeImpl(pFresh);
+
+ variables1.add(variable1);
+ variables2.add(variable2);
+ variablesFresh.add(variableFresh);
+ DartType bound1 = p1.bound ?? DynamicTypeImpl.instance;
+ DartType bound2 = p2.bound ?? DynamicTypeImpl.instance;
+ bound1 = bound1.substitute2(variablesFresh, variables1);
+ bound2 = bound2.substitute2(variablesFresh, variables2);
+ pFresh.bound = bound2;
+ if (!_typeSystem.isSubtypeOf(bound2, bound1)) {
+ _errorReporter.reportErrorForNode(
+ StaticWarningCode.INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND,
+ errorNameTarget, [
+ p1.displayName,
+ p1.bound,
+ p2.displayName,
+ p2.bound,
+ overriddenExecutable.enclosingElement.displayName
+ ]);
+ return true;
+ }
+ }
+ // Proceed with the rest of the checks, using instantiated types.
+ overridingFT = overridingFT.instantiate(variablesFresh);
+ overriddenFT = overriddenFT.instantiate(variablesFresh);
+ }
+ }
+
DartType overridingFTReturnType = overridingFT.returnType;
DartType overriddenFTReturnType = overriddenFT.returnType;
List<DartType> overridingNormalPT = overridingFT.normalParameterTypes;
@@ -1336,6 +1426,7 @@
_errorReporter.reportErrorForNode(
StaticWarningCode.INVALID_OVERRIDE_REQUIRED, errorNameTarget, [
overriddenNormalPT.length,
+ overriddenExecutable,
overriddenExecutable.enclosingElement.displayName
]);
return true;
@@ -1345,6 +1436,7 @@
_errorReporter.reportErrorForNode(
StaticWarningCode.INVALID_OVERRIDE_POSITIONAL, errorNameTarget, [
overriddenPositionalPT.length + overriddenNormalPT.length,
+ overriddenExecutable,
overriddenExecutable.enclosingElement.displayName
]);
return true;
@@ -1358,6 +1450,7 @@
_errorReporter.reportErrorForNode(
StaticWarningCode.INVALID_OVERRIDE_NAMED, errorNameTarget, [
overriddenParamName,
+ overriddenExecutable,
overriddenExecutable.enclosingElement.displayName
]);
return true;
@@ -5210,9 +5303,14 @@
if (_isInStaticMethod || _isInStaticVariableDeclaration) {
DartType type = name.type;
if (type is TypeParameterType) {
- _errorReporter.reportErrorForNode(
- StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, name);
- return true;
+ // The class's type parameters are not in scope for static methods.
+ // However all other type parameters are legal (e.g. the static method's
+ // type parameters, or a local function's type parameters).
+ if (type.element.enclosingElement is ClassElement) {
+ _errorReporter.reportErrorForNode(
+ StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, name);
+ return true;
+ }
}
}
return false;
diff --git a/pkg/analyzer/lib/src/generated/html.dart b/pkg/analyzer/lib/src/generated/html.dart
deleted file mode 100644
index c0012c5..0000000
--- a/pkg/analyzer/lib/src/generated/html.dart
+++ /dev/null
@@ -1,1905 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library engine.html;
-
-import 'dart:collection';
-
-import 'ast.dart';
-import 'element.dart';
-import 'engine.dart' show AnalysisOptions, AnalysisEngine;
-import 'error.dart' show AnalysisErrorListener;
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'parser.dart' show Parser;
-import 'scanner.dart' as sc show Scanner, SubSequenceReader, Token;
-import 'source.dart';
-
-/**
- * The abstract class `AbstractScanner` implements a scanner for HTML code. Subclasses are
- * required to implement the interface used to access the characters being scanned.
- */
-abstract class AbstractScanner {
- static List<String> _NO_PASS_THROUGH_ELEMENTS = <String>[];
-
- /**
- * The source being scanned.
- */
- final Source source;
-
- /**
- * The token pointing to the head of the linked list of tokens.
- */
- Token _tokens;
-
- /**
- * The last token that was scanned.
- */
- Token _tail;
-
- /**
- * A list containing the offsets of the first character of each line in the source code.
- */
- List<int> _lineStarts = new List<int>();
-
- /**
- * An array of element tags for which the content between tags should be consider a single token.
- */
- List<String> _passThroughElements = _NO_PASS_THROUGH_ELEMENTS;
-
- /**
- * Initialize a newly created scanner.
- *
- * @param source the source being scanned
- */
- AbstractScanner(this.source) {
- _tokens = new Token.con1(TokenType.EOF, -1);
- _tokens.setNext(_tokens);
- _tail = _tokens;
- recordStartOfLine();
- }
-
- /**
- * Return an array containing the offsets of the first character of each line in the source code.
- *
- * @return an array containing the offsets of the first character of each line in the source code
- */
- List<int> get lineStarts => _lineStarts;
-
- /**
- * Return the current offset relative to the beginning of the file. Return the initial offset if
- * the scanner has not yet scanned the source code, and one (1) past the end of the source code if
- * the source code has been scanned.
- *
- * @return the current offset of the scanner in the source
- */
- int get offset;
-
- /**
- * Set array of element tags for which the content between tags should be consider a single token.
- */
- void set passThroughElements(List<String> passThroughElements) {
- this._passThroughElements = passThroughElements != null
- ? passThroughElements
- : _NO_PASS_THROUGH_ELEMENTS;
- }
-
- /**
- * Advance the current position and return the character at the new current position.
- *
- * @return the character at the new current position
- */
- int advance();
-
- /**
- * Return the substring of the source code between the start offset and the modified current
- * position. The current position is modified by adding the end delta.
- *
- * @param start the offset to the beginning of the string, relative to the start of the file
- * @param endDelta the number of character after the current location to be included in the
- * string, or the number of characters before the current location to be excluded if the
- * offset is negative
- * @return the specified substring of the source code
- */
- String getString(int start, int endDelta);
-
- /**
- * Return the character at the current position without changing the current position.
- *
- * @return the character at the current position
- */
- int peek();
-
- /**
- * Record the fact that we are at the beginning of a new line in the source.
- */
- void recordStartOfLine() {
- _lineStarts.add(offset);
- }
-
- /**
- * Scan the source code to produce a list of tokens representing the source.
- *
- * @return the first token in the list of tokens that were produced
- */
- Token tokenize() {
- _scan();
- _appendEofToken();
- return _firstToken();
- }
-
- void _appendEofToken() {
- Token eofToken = new Token.con1(TokenType.EOF, offset);
- // The EOF token points to itself so that there is always infinite
- // look-ahead.
- eofToken.setNext(eofToken);
- _tail = _tail.setNext(eofToken);
- }
-
- Token _emit(Token token) {
- _tail.setNext(token);
- _tail = token;
- return token;
- }
-
- Token _emitWithOffset(TokenType type, int start) =>
- _emit(new Token.con1(type, start));
-
- Token _emitWithOffsetAndLength(TokenType type, int start, int count) =>
- _emit(new Token.con2(type, start, getString(start, count)));
-
- Token _firstToken() => _tokens.next;
-
- int _recordStartOfLineAndAdvance(int c) {
- if (c == 0xD) {
- c = advance();
- if (c == 0xA) {
- c = advance();
- }
- recordStartOfLine();
- } else if (c == 0xA) {
- c = advance();
- recordStartOfLine();
- } else {
- c = advance();
- }
- return c;
- }
-
- void _scan() {
- bool inBrackets = false;
- String endPassThrough = null;
- int c = advance();
- while (c >= 0) {
- int start = offset;
- if (c == 0x3C) {
- c = advance();
- if (c == 0x21) {
- c = advance();
- if (c == 0x2D && peek() == 0x2D) {
- // handle a comment
- c = advance();
- int dashCount = 1;
- while (c >= 0) {
- if (c == 0x2D) {
- dashCount++;
- } else if (c == 0x3E && dashCount >= 2) {
- c = advance();
- break;
- } else {
- dashCount = 0;
- }
- c = _recordStartOfLineAndAdvance(c);
- }
- _emitWithOffsetAndLength(TokenType.COMMENT, start, -1);
- // Capture <!--> and <!---> as tokens but report an error
- if (_tail.length < 7) {
- // TODO (danrubel): Report invalid HTML comment
- }
- } else {
- // handle a declaration
- while (c >= 0) {
- if (c == 0x3E) {
- c = advance();
- break;
- }
- c = _recordStartOfLineAndAdvance(c);
- }
- _emitWithOffsetAndLength(TokenType.DECLARATION, start, -1);
- if (!StringUtilities.endsWithChar(_tail.lexeme, 0x3E)) {
- // TODO (danrubel): Report missing '>' in directive
- }
- }
- } else if (c == 0x3F) {
- // handle a directive
- while (c >= 0) {
- if (c == 0x3F) {
- c = advance();
- if (c == 0x3E) {
- c = advance();
- break;
- }
- } else {
- c = _recordStartOfLineAndAdvance(c);
- }
- }
- _emitWithOffsetAndLength(TokenType.DIRECTIVE, start, -1);
- if (_tail.length < 4) {
- // TODO (danrubel): Report invalid directive
- }
- } else if (c == 0x2F) {
- _emitWithOffset(TokenType.LT_SLASH, start);
- inBrackets = true;
- c = advance();
- } else {
- inBrackets = true;
- _emitWithOffset(TokenType.LT, start);
- // ignore whitespace in braces
- while (Character.isWhitespace(c)) {
- c = _recordStartOfLineAndAdvance(c);
- }
- // get tag
- if (Character.isLetterOrDigit(c)) {
- int tagStart = offset;
- c = advance();
- while (Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F) {
- c = advance();
- }
- _emitWithOffsetAndLength(TokenType.TAG, tagStart, -1);
- // check tag against passThrough elements
- String tag = _tail.lexeme;
- for (String str in _passThroughElements) {
- if (str == tag) {
- endPassThrough = "</$str>";
- break;
- }
- }
- }
- }
- } else if (c == 0x3E) {
- _emitWithOffset(TokenType.GT, start);
- inBrackets = false;
- c = advance();
- // if passThrough != null, read until we match it
- if (endPassThrough != null) {
- bool endFound = false;
- int len = endPassThrough.length;
- int firstC = endPassThrough.codeUnitAt(0);
- int index = 0;
- int nextC = firstC;
- while (c >= 0) {
- if (c == nextC) {
- index++;
- if (index == len) {
- endFound = true;
- break;
- }
- nextC = endPassThrough.codeUnitAt(index);
- } else if (c == firstC) {
- index = 1;
- nextC = endPassThrough.codeUnitAt(1);
- } else {
- index = 0;
- nextC = firstC;
- }
- c = _recordStartOfLineAndAdvance(c);
- }
- if (start + 1 < offset) {
- if (endFound) {
- _emitWithOffsetAndLength(TokenType.TEXT, start + 1, -len);
- _emitWithOffset(TokenType.LT_SLASH, offset - len + 1);
- _emitWithOffsetAndLength(TokenType.TAG, offset - len + 3, -1);
- } else {
- _emitWithOffsetAndLength(TokenType.TEXT, start + 1, -1);
- }
- }
- endPassThrough = null;
- }
- } else if (c == 0x2F && peek() == 0x3E) {
- advance();
- _emitWithOffset(TokenType.SLASH_GT, start);
- inBrackets = false;
- c = advance();
- } else if (!inBrackets) {
- c = _recordStartOfLineAndAdvance(c);
- while (c != 0x3C && c >= 0) {
- c = _recordStartOfLineAndAdvance(c);
- }
- _emitWithOffsetAndLength(TokenType.TEXT, start, -1);
- } else if (c == 0x22 || c == 0x27) {
- // read a string
- int endQuote = c;
- c = advance();
- while (c >= 0) {
- if (c == endQuote) {
- c = advance();
- break;
- }
- c = _recordStartOfLineAndAdvance(c);
- }
- _emitWithOffsetAndLength(TokenType.STRING, start, -1);
- } else if (c == 0x3D) {
- // a non-char token
- _emitWithOffset(TokenType.EQ, start);
- c = advance();
- } else if (Character.isWhitespace(c)) {
- // ignore whitespace in braces
- do {
- c = _recordStartOfLineAndAdvance(c);
- } while (Character.isWhitespace(c));
- } else if (Character.isLetterOrDigit(c)) {
- c = advance();
- while (Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F) {
- c = advance();
- }
- _emitWithOffsetAndLength(TokenType.TAG, start, -1);
- } else {
- // a non-char token
- _emitWithOffsetAndLength(TokenType.TEXT, start, 0);
- c = advance();
- }
- }
- }
-}
-
-/**
- * Instances of the class `HtmlParser` are used to parse tokens into a AST structure comprised
- * of [XmlNode]s.
- */
-class HtmlParser extends XmlParser {
- static String _APPLICATION_DART_IN_DOUBLE_QUOTES = "\"application/dart\"";
-
- static String _APPLICATION_DART_IN_SINGLE_QUOTES = "'application/dart'";
-
- static String _SCRIPT = "script";
-
- static String _TYPE = "type";
-
- /**
- * A set containing the names of tags that do not have a closing tag.
- */
- static Set<String> SELF_CLOSING = new HashSet<String>.from(<String>[
- "area",
- "base",
- "basefont",
- "br",
- "col",
- "frame",
- "hr",
- "img",
- "input",
- "link",
- "meta",
- "param",
- "!"
- ]);
-
- /**
- * The line information associated with the source being parsed.
- */
- LineInfo _lineInfo;
-
- /**
- * The error listener to which errors will be reported.
- */
- final AnalysisErrorListener _errorListener;
-
- final AnalysisOptions _options;
-
- /**
- * Construct a parser for the specified source.
- *
- * [source] is the source being parsed. [_errorListener] is the error
- * listener to which errors will be reported. [_options] is the analysis
- * options which should be used for parsing.
- */
- HtmlParser(Source source, this._errorListener, this._options) : super(source);
-
- @override
- XmlAttributeNode createAttributeNode(Token name, Token equals, Token value) =>
- new XmlAttributeNode(name, equals, value);
-
- @override
- XmlTagNode createTagNode(
- Token nodeStart,
- Token tag,
- List<XmlAttributeNode> attributes,
- Token attributeEnd,
- List<XmlTagNode> tagNodes,
- Token contentEnd,
- Token closingTag,
- Token nodeEnd) {
- if (_isScriptNode(tag, attributes, tagNodes)) {
- HtmlScriptTagNode tagNode = new HtmlScriptTagNode(nodeStart, tag,
- attributes, attributeEnd, tagNodes, contentEnd, closingTag, nodeEnd);
- String contents = tagNode.content;
- int contentOffset = attributeEnd.end;
- LineInfo_Location location = _lineInfo.getLocation(contentOffset);
- sc.Scanner scanner = new sc.Scanner(source,
- new sc.SubSequenceReader(contents, contentOffset), _errorListener);
- scanner.setSourceStart(location.lineNumber, location.columnNumber);
- sc.Token firstToken = scanner.tokenize();
- Parser parser = new Parser(source, _errorListener);
- CompilationUnit unit = parser.parseCompilationUnit(firstToken);
- unit.lineInfo = _lineInfo;
- tagNode.script = unit;
- return tagNode;
- }
- return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes,
- contentEnd, closingTag, nodeEnd);
- }
-
- @override
- bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme);
-
- /**
- * Parse the given tokens.
- *
- * @param token the first token in the stream of tokens to be parsed
- * @param lineInfo the line information created by the scanner
- * @return the parse result (not `null`)
- */
- HtmlUnit parse(Token token, LineInfo lineInfo) {
- this._lineInfo = lineInfo;
- List<XmlTagNode> tagNodes = parseTopTagNodes(token);
- return new HtmlUnit(token, tagNodes, currentToken);
- }
-
- /**
- * Determine if the specified node is a Dart script.
- *
- * @param node the node to be tested (not `null`)
- * @return `true` if the node is a Dart script
- */
- bool _isScriptNode(
- Token tag, List<XmlAttributeNode> attributes, List<XmlTagNode> tagNodes) {
- if (tagNodes.length != 0 || tag.lexeme != _SCRIPT) {
- return false;
- }
- for (XmlAttributeNode attribute in attributes) {
- if (attribute.name == _TYPE) {
- Token valueToken = attribute.valueToken;
- if (valueToken != null) {
- String value = valueToken.lexeme;
- if (value == _APPLICATION_DART_IN_DOUBLE_QUOTES ||
- value == _APPLICATION_DART_IN_SINGLE_QUOTES) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
- /**
- * Given the contents of an embedded expression that occurs at the given offset, parse it as a
- * Dart expression. The contents should not include the expression's delimiters.
- *
- * @param source the source that contains that given token
- * @param token the token to start parsing from
- * @return the Dart expression that was parsed
- */
- static Expression parseEmbeddedExpression(
- Source source, sc.Token token, AnalysisErrorListener errorListener) {
- Parser parser = new Parser(source, errorListener);
- return parser.parseExpression(token);
- }
-
- /**
- * Given the contents of an embedded expression that occurs at the given offset, scans it as a
- * Dart code.
- *
- * @param source the source of that contains the given contents
- * @param contents the contents to scan
- * @param contentOffset the offset of the contents in the larger file
- * @return the first Dart token
- */
- static sc.Token scanDartSource(Source source, LineInfo lineInfo,
- String contents, int contentOffset, AnalysisErrorListener errorListener) {
- LineInfo_Location location = lineInfo.getLocation(contentOffset);
- sc.Scanner scanner = new sc.Scanner(source,
- new sc.SubSequenceReader(contents, contentOffset), errorListener);
- scanner.setSourceStart(location.lineNumber, location.columnNumber);
- return scanner.tokenize();
- }
-}
-
-/**
- * Instances of the class `HtmlScriptTagNode` represent a script tag within an HTML file that
- * references a Dart script.
- */
-@deprecated
-class HtmlScriptTagNode extends XmlTagNode {
- /**
- * The AST structure representing the Dart code within this tag.
- */
- CompilationUnit _script;
-
- /**
- * The element representing this script.
- */
- HtmlScriptElement scriptElement;
-
- /**
- * Initialize a newly created node to represent a script tag within an HTML file that references a
- * Dart script.
- *
- * @param nodeStart the token marking the beginning of the tag
- * @param tag the name of the tag
- * @param attributes the attributes in the tag
- * @param attributeEnd the token terminating the region where attributes can be
- * @param tagNodes the children of the tag
- * @param contentEnd the token that starts the closing tag
- * @param closingTag the name of the tag that occurs in the closing tag
- * @param nodeEnd the last token in the tag
- */
- HtmlScriptTagNode(
- Token nodeStart,
- Token tag,
- List<XmlAttributeNode> attributes,
- Token attributeEnd,
- List<XmlTagNode> tagNodes,
- Token contentEnd,
- Token closingTag,
- Token nodeEnd)
- : super(nodeStart, tag, attributes, attributeEnd, tagNodes, contentEnd,
- closingTag, nodeEnd);
-
- /**
- * Return the AST structure representing the Dart code within this tag, or `null` if this
- * tag references an external script.
- *
- * @return the AST structure representing the Dart code within this tag
- */
- CompilationUnit get script => _script;
-
- /**
- * Set the AST structure representing the Dart code within this tag to the given compilation unit.
- *
- * @param unit the AST structure representing the Dart code within this tag
- */
- void set script(CompilationUnit unit) {
- _script = unit;
- }
-
- @override
- accept(XmlVisitor visitor) => visitor.visitHtmlScriptTagNode(this);
-}
-
-/**
- * Instances of the class `HtmlUnit` represent the contents of an HTML file.
- */
-@deprecated
-class HtmlUnit extends XmlNode {
- /**
- * The first token in the token stream that was parsed to form this HTML unit.
- */
- final Token beginToken;
-
- /**
- * The last token in the token stream that was parsed to form this compilation unit. This token
- * should always have a type of [TokenType.EOF].
- */
- final Token endToken;
-
- /**
- * The tag nodes contained in the receiver (not `null`, contains no `null`s).
- */
- List<XmlTagNode> _tagNodes;
-
- /**
- * Construct a new instance representing the content of an HTML file.
- *
- * @param beginToken the first token in the file (not `null`)
- * @param tagNodes child tag nodes of the receiver (not `null`, contains no `null`s)
- * @param endToken the last token in the token stream which should be of type
- * [TokenType.EOF]
- */
- HtmlUnit(this.beginToken, List<XmlTagNode> tagNodes, this.endToken) {
- this._tagNodes = becomeParentOfAll(tagNodes);
- }
-
- /**
- * Return the element associated with this HTML unit.
- *
- * @return the element or `null` if the receiver is not resolved
- */
- @override
- HtmlElement get element => super.element as HtmlElement;
-
- @override
- void set element(Element element) {
- if (element != null && element is! HtmlElement) {
- throw new IllegalArgumentException(
- "HtmlElement expected, but ${element.runtimeType} given");
- }
- super.element = element;
- }
-
- /**
- * Answer the tag nodes contained in the receiver. Callers should not manipulate the returned list
- * to edit the AST structure.
- *
- * @return the children (not `null`, contains no `null`s)
- */
- List<XmlTagNode> get tagNodes => _tagNodes;
-
- @override
- accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this);
-
- @override
- void visitChildren(XmlVisitor visitor) {
- for (XmlTagNode node in _tagNodes) {
- node.accept(visitor);
- }
- }
-}
-
-/**
- * Instances of the class `RecursiveXmlVisitor` implement an XML visitor that will recursively
- * visit all of the nodes in an XML structure. For example, using an instance of this class to visit
- * a [XmlTagNode] will also cause all of the contained [XmlAttributeNode]s and
- * [XmlTagNode]s to be visited.
- *
- * Subclasses that override a visit method must either invoke the overridden visit method or must
- * explicitly ask the visited node to visit its children. Failure to do so will cause the children
- * of the visited node to not be visited.
- */
-class RecursiveXmlVisitor<R> implements XmlVisitor<R> {
- @override
- R visitHtmlScriptTagNode(HtmlScriptTagNode node) {
- node.visitChildren(this);
- return null;
- }
-
- @override
- R visitHtmlUnit(HtmlUnit node) {
- node.visitChildren(this);
- return null;
- }
-
- @override
- R visitXmlAttributeNode(XmlAttributeNode node) {
- node.visitChildren(this);
- return null;
- }
-
- @override
- R visitXmlTagNode(XmlTagNode node) {
- node.visitChildren(this);
- return null;
- }
-}
-
-/**
- * Instances of the class `SimpleXmlVisitor` implement an AST visitor that will do nothing
- * when visiting an AST node. It is intended to be a superclass for classes that use the visitor
- * pattern primarily as a dispatch mechanism (and hence don't need to recursively visit a whole
- * structure) and that only need to visit a small number of node types.
- */
-class SimpleXmlVisitor<R> implements XmlVisitor<R> {
- @override
- R visitHtmlScriptTagNode(HtmlScriptTagNode node) => null;
-
- @override
- R visitHtmlUnit(HtmlUnit htmlUnit) => null;
-
- @override
- R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode) => null;
-
- @override
- R visitXmlTagNode(XmlTagNode xmlTagNode) => null;
-}
-
-/**
- * Instances of the class `StringScanner` implement a scanner that reads from a string. The
- * scanning logic is in the superclass.
- */
-class StringScanner extends AbstractScanner {
- /**
- * The string from which characters will be read.
- */
- final String _string;
-
- /**
- * The number of characters in the string.
- */
- int _stringLength = 0;
-
- /**
- * The index, relative to the string, of the last character that was read.
- */
- int _charOffset = 0;
-
- /**
- * Initialize a newly created scanner to scan the characters in the given string.
- *
- * @param source the source being scanned
- * @param string the string from which characters will be read
- */
- StringScanner(Source source, this._string) : super(source) {
- this._stringLength = _string.length;
- this._charOffset = -1;
- }
-
- @override
- int get offset => _charOffset;
-
- void set offset(int offset) {
- _charOffset = offset;
- }
-
- @override
- int advance() {
- if (++_charOffset < _stringLength) {
- return _string.codeUnitAt(_charOffset);
- }
- _charOffset = _stringLength;
- return -1;
- }
-
- @override
- String getString(int start, int endDelta) =>
- _string.substring(start, _charOffset + 1 + endDelta).toString();
-
- @override
- int peek() {
- if (_charOffset + 1 < _stringLength) {
- return _string.codeUnitAt(_charOffset + 1);
- }
- return -1;
- }
-}
-
-/**
- * Instances of the class `Token` represent a token that was scanned from the input. Each
- * token knows which token follows it, acting as the head of a linked list of tokens.
- */
-class Token {
- /**
- * The offset from the beginning of the file to the first character in the token.
- */
- final int offset;
-
- /**
- * The previous token in the token stream.
- */
- Token previous;
-
- /**
- * The next token in the token stream.
- */
- Token _next;
-
- /**
- * The type of the token.
- */
- final TokenType type;
-
- /**
- * The lexeme represented by this token.
- */
- String _value;
-
- /**
- * Initialize a newly created token.
- *
- * @param type the token type (not `null`)
- * @param offset the offset from the beginning of the file to the first character in the token
- */
- Token.con1(TokenType type, int offset) : this.con2(type, offset, type.lexeme);
-
- /**
- * Initialize a newly created token.
- *
- * @param type the token type (not `null`)
- * @param offset the offset from the beginning of the file to the first character in the token
- * @param value the lexeme represented by this token (not `null`)
- */
- Token.con2(this.type, this.offset, String value) {
- this._value = StringUtilities.intern(value);
- }
-
- /**
- * Return the offset from the beginning of the file to the character after last character of the
- * token.
- *
- * @return the offset from the beginning of the file to the first character after last character
- * of the token
- */
- int get end => offset + length;
-
- /**
- * 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. Synthetic tokens always
- * have a length of zero (`0`).
- *
- * @return `true` if this token is a synthetic token
- */
- bool get isSynthetic => length == 0;
-
- /**
- * Return the number of characters in the node's source range.
- *
- * @return the number of characters in the node's source range
- */
- int get length => lexeme.length;
-
- /**
- * Return the lexeme that represents this token.
- *
- * @return the lexeme (not `null`)
- */
- String get lexeme => _value;
-
- /**
- * Return the next token in the token stream.
- *
- * @return the next token in the token stream
- */
- Token get next => _next;
-
- /**
- * Set the next token in the token stream to the given token. This has the side-effect of setting
- * this token to be the previous token for the given token.
- *
- * @param token the next token in the token stream
- * @return the token that was passed in
- */
- Token setNext(Token token) {
- _next = token;
- token.previous = this;
- return token;
- }
-
- @override
- String toString() => lexeme;
-}
-
-/**
- * The enumeration `TokenType` defines the types of tokens that can be returned by the
- * scanner.
- */
-class TokenType extends Enum<TokenType> {
- /**
- * The type of the token that marks the end of the input.
- */
- static const TokenType EOF = const TokenType_EOF('EOF', 0, "");
-
- static const TokenType EQ = const TokenType('EQ', 1, "=");
-
- static const TokenType GT = const TokenType('GT', 2, ">");
-
- static const TokenType LT_SLASH = const TokenType('LT_SLASH', 3, "</");
-
- static const TokenType LT = const TokenType('LT', 4, "<");
-
- static const TokenType SLASH_GT = const TokenType('SLASH_GT', 5, "/>");
-
- static const TokenType COMMENT = const TokenType('COMMENT', 6, null);
-
- static const TokenType DECLARATION = const TokenType('DECLARATION', 7, null);
-
- static const TokenType DIRECTIVE = const TokenType('DIRECTIVE', 8, null);
-
- static const TokenType STRING = const TokenType('STRING', 9, null);
-
- static const TokenType TAG = const TokenType('TAG', 10, null);
-
- static const TokenType TEXT = const TokenType('TEXT', 11, null);
-
- static const List<TokenType> values = const [
- EOF,
- EQ,
- GT,
- LT_SLASH,
- LT,
- SLASH_GT,
- COMMENT,
- DECLARATION,
- DIRECTIVE,
- STRING,
- TAG,
- TEXT
- ];
-
- /**
- * The lexeme that defines this type of token, or `null` if there is more than one possible
- * lexeme for this type of token.
- */
- final String lexeme;
-
- const TokenType(String name, int ordinal, this.lexeme) : super(name, ordinal);
-}
-
-class TokenType_EOF extends TokenType {
- const TokenType_EOF(String name, int ordinal, String arg0)
- : super(name, ordinal, arg0);
-
- @override
- String toString() => "-eof-";
-}
-
-/**
- * Instances of the class `ToSourceVisitor` write a source representation of a visited XML
- * node (and all of it's children) to a writer.
- */
-class ToSourceVisitor implements XmlVisitor<Object> {
- /**
- * The writer to which the source is to be written.
- */
- final PrintWriter _writer;
-
- /**
- * Initialize a newly created visitor to write source code representing the visited nodes to the
- * given writer.
- *
- * @param writer the writer to which the source is to be written
- */
- ToSourceVisitor(this._writer);
-
- @override
- Object visitHtmlScriptTagNode(HtmlScriptTagNode node) =>
- visitXmlTagNode(node);
-
- @override
- Object visitHtmlUnit(HtmlUnit node) {
- for (XmlTagNode child in node.tagNodes) {
- _visit(child);
- }
- return null;
- }
-
- @override
- Object visitXmlAttributeNode(XmlAttributeNode node) {
- String name = node.name;
- Token value = node.valueToken;
- if (name.length == 0) {
- _writer.print("__");
- } else {
- _writer.print(name);
- }
- _writer.print("=");
- if (value == null) {
- _writer.print("__");
- } else {
- _writer.print(value.lexeme);
- }
- return null;
- }
-
- @override
- Object visitXmlTagNode(XmlTagNode node) {
- _writer.print("<");
- String tagName = node.tag;
- _writer.print(tagName);
- for (XmlAttributeNode attribute in node.attributes) {
- _writer.print(" ");
- _visit(attribute);
- }
- _writer.print(node.attributeEnd.lexeme);
- if (node.closingTag != null) {
- for (XmlTagNode child in node.tagNodes) {
- _visit(child);
- }
- _writer.print("</");
- _writer.print(tagName);
- _writer.print(">");
- }
- return null;
- }
-
- /**
- * Safely visit the given node.
- *
- * @param node the node to be visited
- */
- void _visit(XmlNode node) {
- if (node != null) {
- node.accept(this);
- }
- }
-}
-
-/**
- * Instances of `XmlAttributeNode` represent name/value pairs owned by an [XmlTagNode].
- */
-class XmlAttributeNode extends XmlNode {
- /**
- * An empty list of XML attribute nodes.
- */
- static const List<XmlAttributeNode> EMPTY_LIST = const <XmlAttributeNode>[];
-
- final Token _name;
-
- final Token equals;
-
- final Token _value;
-
- List<XmlExpression> expressions = XmlExpression.EMPTY_ARRAY;
-
- /**
- * Construct a new instance representing an XML attribute.
- *
- * @param name the name token (not `null`). This may be a zero length token if the attribute
- * is badly formed.
- * @param equals the equals sign or `null` if none
- * @param value the value token (not `null`)
- */
- XmlAttributeNode(this._name, this.equals, this._value);
-
- @override
- Token get beginToken => _name;
-
- @override
- Token get endToken => _value;
-
- /**
- * Answer the attribute name. This may be a zero length string if the attribute is badly formed.
- *
- * @return the name (not `null`)
- */
- String get name => _name.lexeme;
-
- /**
- * Answer the attribute name token. This may be a zero length token if the attribute is badly
- * formed.
- *
- * @return the name token (not `null`)
- */
- Token get nameToken => _name;
-
- /**
- * Answer the lexeme for the value token without the leading and trailing quotes.
- *
- * @return the text or `null` if the value is not specified
- */
- String get text {
- if (_value == null) {
- return null;
- }
- //TODO (danrubel): replace HTML character encodings with the actual
- // characters
- String text = _value.lexeme;
- int len = text.length;
- if (len > 0) {
- if (text.codeUnitAt(0) == 0x22) {
- if (len > 1 && text.codeUnitAt(len - 1) == 0x22) {
- return text.substring(1, len - 1);
- } else {
- return text.substring(1);
- }
- } else if (text.codeUnitAt(0) == 0x27) {
- if (len > 1 && text.codeUnitAt(len - 1) == 0x27) {
- return text.substring(1, len - 1);
- } else {
- return text.substring(1);
- }
- }
- }
- return text;
- }
-
- /**
- * Answer the offset of the value after the leading quote.
- *
- * @return the offset of the value, or `-1` if the value is not specified
- */
- int get textOffset {
- if (_value == null) {
- return -1;
- }
- String text = _value.lexeme;
- if (StringUtilities.startsWithChar(text, 0x22) ||
- StringUtilities.startsWithChar(text, 0x27)) {
- return _value.offset + 1;
- }
- return _value.offset;
- }
-
- /**
- * Answer the attribute value token. A properly formed value will start and end with matching
- * quote characters, but the value returned may not be properly formed.
- *
- * @return the value token or `null` if this represents a badly formed attribute
- */
- Token get valueToken => _value;
-
- @override
- accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this);
-
- @override
- void visitChildren(XmlVisitor visitor) {
- // no children to visit
- }
-}
-
-/**
- * Instances of the class `XmlExpression` represent an abstract expression embedded into
- * [XmlNode].
- */
-abstract class XmlExpression {
- /**
- * An empty list of expressions.
- */
- static const List<XmlExpression> EMPTY_ARRAY = const <XmlExpression>[];
-
- /**
- * Return the offset of the character immediately following the last character of this
- * expression's source range. This is equivalent to `getOffset() + getLength()`.
- *
- * @return the offset of the character just past the expression's source range
- */
- int get end;
-
- /**
- * Return the number of characters in the expression's source range.
- */
- int get length;
-
- /**
- * Return the offset of the first character in the expression's source range.
- */
- int get offset;
-
- /**
- * Check if the given offset belongs to the expression's source range.
- */
- bool contains(int offset) => this.offset <= offset && offset < end;
-
- /**
- * Return the [Reference] at the given offset.
- *
- * @param offset the offset from the beginning of the file
- * @return the [Reference] at the given offset, maybe `null`
- */
- XmlExpression_Reference getReference(int offset);
-}
-
-/**
- * The reference to the [Element].
- */
-class XmlExpression_Reference {
- Element element;
-
- int offset = 0;
-
- int length = 0;
-
- XmlExpression_Reference(this.element, this.offset, this.length);
-}
-
-/**
- * The abstract class `XmlNode` defines behavior common to all XML/HTML nodes.
- */
-abstract class XmlNode {
- /**
- * The parent of the node, or `null` if the node is the root of an AST structure.
- */
- XmlNode _parent;
-
- /**
- * The element associated with this node or `null` if the receiver is not resolved.
- */
- Element _element;
-
- /**
- * Return the first token included in this node's source range.
- *
- * @return the first token or `null` if none
- */
- Token get beginToken;
-
- /**
- * Return the element associated with this node.
- *
- * @return the element or `null` if the receiver is not resolved
- */
- Element get element => _element;
-
- /**
- * Set the element associated with this node.
- *
- * @param element the element
- */
- void set element(Element element) {
- this._element = element;
- }
-
- /**
- * Return the offset of the character immediately following the last character of this node's
- * source range. This is equivalent to `node.getOffset() + node.getLength()`. For an html
- * unit this will be equal to the length of the unit's source.
- *
- * @return the offset of the character just past the node's source range
- */
- int get end => offset + length;
-
- /**
- * Return the last token included in this node's source range.
- *
- * @return the last token or `null` if none
- */
- Token get endToken;
-
- /**
- * Return the number of characters in the node's source range.
- *
- * @return the number of characters in the node's source range
- */
- int get length {
- Token beginToken = this.beginToken;
- Token endToken = this.endToken;
- if (beginToken == null || endToken == null) {
- return -1;
- }
- return endToken.offset + endToken.length - beginToken.offset;
- }
-
- /**
- * Return the offset from the beginning of the file to the first character in the node's source
- * range.
- *
- * @return the offset from the beginning of the file to the first character in the node's source
- * range
- */
- int get offset {
- Token beginToken = this.beginToken;
- if (beginToken == null) {
- return -1;
- }
- return this.beginToken.offset;
- }
-
- /**
- * Return this node's parent node, or `null` if this node is the root of an AST structure.
- *
- * Note that the relationship between an AST node and its parent node may change over the lifetime
- * of a node.
- *
- * @return the parent of this node, or `null` if none
- */
- XmlNode get parent => _parent;
-
- /**
- * Set the parent of this node to the given node.
- *
- * @param newParent the node that is to be made the parent of this node
- */
- void set parent(XmlNode newParent) {
- XmlNode current = newParent;
- while (current != null) {
- if (identical(current, this)) {
- AnalysisEngine.instance.logger.logError(
- "Circular structure while setting an XML node's parent",
- new CaughtException(
- new ArgumentError(_buildRecursiveStructureMessage(newParent)),
- null));
- return;
- }
- current = current.parent;
- }
- _parent = newParent;
- }
-
- /**
- * Use the given visitor to visit this node.
- *
- * @param visitor the visitor that will visit this node
- * @return the value returned by the visitor as a result of visiting this node
- */
- accept(XmlVisitor visitor);
-
- /**
- * Make this node the parent of the given child node.
- *
- * @param child the node that will become a child of this node
- * @return the node that was made a child of this node
- */
- XmlNode becomeParentOf(XmlNode child) {
- if (child != null) {
- XmlNode node = child;
- node.parent = this;
- }
- return child;
- }
-
- /**
- * Make this node the parent of the given child nodes.
- *
- * @param children the nodes that will become the children of this node
- * @param ifEmpty the (empty) nodes to return if "children" is empty
- * @return the nodes that were made children of this node
- */
- List becomeParentOfAll(List children, {List ifEmpty}) {
- if (children == null || children.isEmpty) {
- if (ifEmpty != null) {
- return ifEmpty;
- }
- }
- if (children != null) {
- children.forEach((XmlNode node) {
- node.parent = this;
- });
- }
- return children;
- }
-
- @override
- String toString() {
- PrintStringWriter writer = new PrintStringWriter();
- accept(new ToSourceVisitor(writer));
- return writer.toString();
- }
-
- /**
- * Use the given visitor to visit all of the children of this node. The children will be visited
- * in source order.
- *
- * @param visitor the visitor that will be used to visit the children of this node
- */
- void visitChildren(XmlVisitor visitor);
-
- /**
- * This method exists for debugging purposes only.
- */
- void _appendIdentifier(StringBuffer buffer, XmlNode node) {
- if (node is XmlTagNode) {
- buffer.write(node.tag);
- } else if (node is XmlAttributeNode) {
- buffer.write(node.name);
- } else {
- buffer.write("htmlUnit");
- }
- }
-
- /**
- * This method exists for debugging purposes only.
- */
- String _buildRecursiveStructureMessage(XmlNode newParent) {
- StringBuffer buffer = new StringBuffer();
- buffer.write("Attempt to create recursive structure: ");
- XmlNode current = newParent;
- while (current != null) {
- if (!identical(current, newParent)) {
- buffer.write(" -> ");
- }
- if (identical(current, this)) {
- buffer.writeCharCode(0x2A);
- _appendIdentifier(buffer, current);
- buffer.writeCharCode(0x2A);
- } else {
- _appendIdentifier(buffer, current);
- }
- current = current.parent;
- }
- return buffer.toString();
- }
-}
-
-/**
- * Instances of the class `XmlParser` are used to parse tokens into a AST structure comprised
- * of [XmlNode]s.
- */
-class XmlParser {
- /**
- * The source being parsed.
- */
- final Source source;
-
- /**
- * The next token to be parsed.
- */
- Token _currentToken;
-
- /**
- * Construct a parser for the specified source.
- *
- * @param source the source being parsed
- */
- XmlParser(this.source);
-
- /**
- * Answer the current token.
- *
- * @return the current token
- */
- Token get currentToken => _currentToken;
-
- /**
- * Create a node representing an attribute.
- *
- * @param name the name of the attribute
- * @param equals the equals sign, or `null` if there is no value
- * @param value the value of the attribute
- * @return the node that was created
- */
- XmlAttributeNode createAttributeNode(Token name, Token equals, Token value) =>
- new XmlAttributeNode(name, equals, value);
-
- /**
- * Create a node representing a tag.
- *
- * @param nodeStart the token marking the beginning of the tag
- * @param tag the name of the tag
- * @param attributes the attributes in the tag
- * @param attributeEnd the token terminating the region where attributes can be
- * @param tagNodes the children of the tag
- * @param contentEnd the token that starts the closing tag
- * @param closingTag the name of the tag that occurs in the closing tag
- * @param nodeEnd the last token in the tag
- * @return the node that was created
- */
- XmlTagNode createTagNode(
- Token nodeStart,
- Token tag,
- List<XmlAttributeNode> attributes,
- Token attributeEnd,
- List<XmlTagNode> tagNodes,
- Token contentEnd,
- Token closingTag,
- Token nodeEnd) =>
- new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes,
- contentEnd, closingTag, nodeEnd);
-
- /**
- * Answer `true` if the specified tag is self closing and thus should never have content or
- * child tag nodes.
- *
- * @param tag the tag (not `null`)
- * @return `true` if self closing
- */
- bool isSelfClosing(Token tag) => false;
-
- /**
- * Parse the entire token stream and in the process, advance the current token to the end of the
- * token stream.
- *
- * @return the list of tag nodes found (not `null`, contains no `null`)
- */
- List<XmlTagNode> parseTopTagNodes(Token firstToken) {
- _currentToken = firstToken;
- List<XmlTagNode> tagNodes = new List<XmlTagNode>();
- TokenType type = _currentToken.type;
- while (type != TokenType.EOF) {
- if (type == TokenType.LT) {
- tagNodes.add(_parseTagNode());
- } else if (type == TokenType.DECLARATION ||
- type == TokenType.DIRECTIVE ||
- type == TokenType.COMMENT) {
- // ignored tokens
- _currentToken = _currentToken.next;
- } else {
- _reportUnexpectedToken();
- _currentToken = _currentToken.next;
- }
- type = _currentToken.type;
- }
- return tagNodes;
- }
-
- /**
- * Insert a synthetic token of the specified type before the current token
- *
- * @param type the type of token to be inserted (not `null`)
- * @return the synthetic token that was inserted (not `null`)
- */
- Token _insertSyntheticToken(TokenType type) {
- Token token = new Token.con2(type, _currentToken.offset, "");
- _currentToken.previous.setNext(token);
- token.setNext(_currentToken);
- return token;
- }
-
- /**
- * Parse the token stream for an attribute. This method advances the current token over the
- * attribute, but should not be called if the [currentToken] is not [TokenType.TAG].
- *
- * @return the attribute (not `null`)
- */
- XmlAttributeNode _parseAttribute() {
- // Assume the current token is a tag
- Token name = _currentToken;
- _currentToken = _currentToken.next;
- // Equals sign
- Token equals;
- if (_currentToken.type == TokenType.EQ) {
- equals = _currentToken;
- _currentToken = _currentToken.next;
- } else {
- _reportUnexpectedToken();
- equals = _insertSyntheticToken(TokenType.EQ);
- }
- // String value
- Token value;
- if (_currentToken.type == TokenType.STRING) {
- value = _currentToken;
- _currentToken = _currentToken.next;
- } else {
- _reportUnexpectedToken();
- value = _insertSyntheticToken(TokenType.STRING);
- }
- return createAttributeNode(name, equals, value);
- }
-
- /**
- * Parse the stream for a sequence of attributes. This method advances the current token to the
- * next [TokenType.GT], [TokenType.SLASH_GT], or [TokenType.EOF].
- *
- * @return a collection of zero or more attributes (not `null`, contains no `null`s)
- */
- List<XmlAttributeNode> _parseAttributes() {
- TokenType type = _currentToken.type;
- if (type == TokenType.GT ||
- type == TokenType.SLASH_GT ||
- type == TokenType.EOF) {
- return XmlTagNode.NO_ATTRIBUTES;
- }
- List<XmlAttributeNode> attributes = new List<XmlAttributeNode>();
- while (type != TokenType.GT &&
- type != TokenType.SLASH_GT &&
- type != TokenType.EOF) {
- if (type == TokenType.TAG) {
- attributes.add(_parseAttribute());
- } else {
- _reportUnexpectedToken();
- _currentToken = _currentToken.next;
- }
- type = _currentToken.type;
- }
- return attributes;
- }
-
- /**
- * Parse the stream for a sequence of tag nodes existing within a parent tag node. This method
- * advances the current token to the next [TokenType.LT_SLASH] or [TokenType.EOF].
- *
- * @return a list of nodes (not `null`, contains no `null`s)
- */
- List<XmlTagNode> _parseChildTagNodes() {
- TokenType type = _currentToken.type;
- if (type == TokenType.LT_SLASH || type == TokenType.EOF) {
- return XmlTagNode.NO_TAG_NODES;
- }
- List<XmlTagNode> nodes = new List<XmlTagNode>();
- while (type != TokenType.LT_SLASH && type != TokenType.EOF) {
- if (type == TokenType.LT) {
- nodes.add(_parseTagNode());
- } else if (type == TokenType.COMMENT) {
- // ignored token
- _currentToken = _currentToken.next;
- } else {
- _reportUnexpectedToken();
- _currentToken = _currentToken.next;
- }
- type = _currentToken.type;
- }
- return nodes;
- }
-
- /**
- * Parse the token stream for the next tag node. This method advances current token over the
- * parsed tag node, but should only be called if the current token is [TokenType.LT]
- *
- * @return the tag node or `null` if none found
- */
- XmlTagNode _parseTagNode() {
- // Assume that the current node is a tag node start TokenType.LT
- Token nodeStart = _currentToken;
- _currentToken = _currentToken.next;
- // Get the tag or create a synthetic tag and report an error
- Token tag;
- if (_currentToken.type == TokenType.TAG) {
- tag = _currentToken;
- _currentToken = _currentToken.next;
- } else {
- _reportUnexpectedToken();
- tag = _insertSyntheticToken(TokenType.TAG);
- }
- // Parse the attributes
- List<XmlAttributeNode> attributes = _parseAttributes();
- // Token ending attribute list
- Token attributeEnd;
- if (_currentToken.type == TokenType.GT ||
- _currentToken.type == TokenType.SLASH_GT) {
- attributeEnd = _currentToken;
- _currentToken = _currentToken.next;
- } else {
- _reportUnexpectedToken();
- attributeEnd = _insertSyntheticToken(TokenType.SLASH_GT);
- }
- // If the node has no children, then return the node
- if (attributeEnd.type == TokenType.SLASH_GT || isSelfClosing(tag)) {
- return createTagNode(nodeStart, tag, attributes, attributeEnd,
- XmlTagNode.NO_TAG_NODES, _currentToken, null, attributeEnd);
- }
- // Parse the child tag nodes
- List<XmlTagNode> tagNodes = _parseChildTagNodes();
- // Token ending child tag nodes
- Token contentEnd;
- if (_currentToken.type == TokenType.LT_SLASH) {
- contentEnd = _currentToken;
- _currentToken = _currentToken.next;
- } else {
- // TODO (danrubel): handle self closing HTML elements by inserting
- // synthetic tokens but not reporting an error
- _reportUnexpectedToken();
- contentEnd = _insertSyntheticToken(TokenType.LT_SLASH);
- }
- // Closing tag
- Token closingTag;
- if (_currentToken.type == TokenType.TAG) {
- closingTag = _currentToken;
- _currentToken = _currentToken.next;
- } else {
- _reportUnexpectedToken();
- closingTag = _insertSyntheticToken(TokenType.TAG);
- }
- // Token ending node
- Token nodeEnd;
- if (_currentToken.type == TokenType.GT) {
- nodeEnd = _currentToken;
- _currentToken = _currentToken.next;
- } else {
- _reportUnexpectedToken();
- nodeEnd = _insertSyntheticToken(TokenType.GT);
- }
- return createTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes,
- contentEnd, closingTag, nodeEnd);
- }
-
- /**
- * Report the current token as unexpected
- */
- void _reportUnexpectedToken() {
- // TODO (danrubel): report unexpected token
- }
-}
-
-/**
- * Instances of `XmlTagNode` represent XML or HTML elements such as `` and
- * `<body foo="bar"> ... </body>`.
- */
-class XmlTagNode extends XmlNode {
- /**
- * Constant representing empty list of attributes.
- */
- static List<XmlAttributeNode> NO_ATTRIBUTES =
- new UnmodifiableListView(new List<XmlAttributeNode>());
-
- /**
- * Constant representing empty list of tag nodes.
- */
- static List<XmlTagNode> NO_TAG_NODES =
- new UnmodifiableListView(new List<XmlTagNode>());
-
- /**
- * The starting [TokenType.LT] token (not `null`).
- */
- final Token nodeStart;
-
- /**
- * The [TokenType.TAG] token after the starting '<' (not `null`).
- */
- final Token _tag;
-
- /**
- * The attributes contained by the receiver (not `null`, contains no `null`s).
- */
- List<XmlAttributeNode> _attributes;
-
- /**
- * The [TokenType.GT] or [TokenType.SLASH_GT] token after the attributes (not
- * `null`). The token may be the same token as [nodeEnd] if there are no child
- * [tagNodes].
- */
- final Token attributeEnd;
-
- /**
- * The tag nodes contained in the receiver (not `null`, contains no `null`s).
- */
- List<XmlTagNode> _tagNodes;
-
- /**
- * The token (not `null`) after the content, which may be
- * * (1) [TokenType.LT_SLASH] for nodes with open and close tags, or
- * * (2) the [TokenType.LT] nodeStart of the next sibling node if this node is self
- * closing or the attributeEnd is [TokenType.SLASH_GT], or
- * * (3) [TokenType.EOF] if the node does not have a closing tag and is the last node in
- * the stream [TokenType.LT_SLASH] token after the content, or `null` if there is no
- * content and the attributes ended with [TokenType.SLASH_GT].
- */
- final Token contentEnd;
-
- /**
- * The closing [TokenType.TAG] after the child elements or `null` if there is no
- * content and the attributes ended with [TokenType.SLASH_GT]
- */
- final Token closingTag;
-
- /**
- * The ending [TokenType.GT] or [TokenType.SLASH_GT] token (not `null`).
- */
- final Token nodeEnd;
-
- /**
- * The expressions that are embedded in the tag's content.
- */
- List<XmlExpression> expressions = XmlExpression.EMPTY_ARRAY;
-
- /**
- * Construct a new instance representing an XML or HTML element
- *
- * @param nodeStart the starting [TokenType.LT] token (not `null`)
- * @param tag the [TokenType.TAG] token after the starting '<' (not `null`).
- * @param attributes the attributes associated with this element or [NO_ATTRIBUTES] (not
- * `null`, contains no `null`s)
- * @param attributeEnd The [TokenType.GT] or [TokenType.SLASH_GT] token after the
- * attributes (not `null`). The token may be the same token as [nodeEnd] if
- * there are no child [tagNodes].
- * @param tagNodes child tag nodes of the receiver or [NO_TAG_NODES] (not `null`,
- * contains no `null`s)
- * @param contentEnd the token (not `null`) after the content, which may be
- * * (1) [TokenType.LT_SLASH] for nodes with open and close tags, or
- * * (2) the [TokenType.LT] nodeStart of the next sibling node if this node is
- * self closing or the attributeEnd is [TokenType.SLASH_GT], or
- * * (3) [TokenType.EOF] if the node does not have a closing tag and is the last
- * node in the stream [TokenType.LT_SLASH] token after the content, or `null`
- * if there is no content and the attributes ended with [TokenType.SLASH_GT].
- * @param closingTag the closing [TokenType.TAG] after the child elements or `null` if
- * there is no content and the attributes ended with [TokenType.SLASH_GT]
- * @param nodeEnd the ending [TokenType.GT] or [TokenType.SLASH_GT] token (not
- * `null`)
- */
- XmlTagNode(
- this.nodeStart,
- this._tag,
- List<XmlAttributeNode> attributes,
- this.attributeEnd,
- List<XmlTagNode> tagNodes,
- this.contentEnd,
- this.closingTag,
- this.nodeEnd) {
- this._attributes = becomeParentOfAll(attributes, ifEmpty: NO_ATTRIBUTES);
- this._tagNodes = becomeParentOfAll(tagNodes, ifEmpty: NO_TAG_NODES);
- }
-
- /**
- * Answer the receiver's attributes. Callers should not manipulate the returned list to edit the
- * AST structure.
- *
- * @return the attributes (not `null`, contains no `null`s)
- */
- List<XmlAttributeNode> get attributes => _attributes;
-
- @override
- Token get beginToken => nodeStart;
-
- /**
- * Return a string representing the content contained in the receiver. This
- * includes the textual representation of any child tag nodes ([getTagNodes]).
- * Whitespace between '<', '</', and '>', '/>' is discarded, but all
- * other whitespace is preserved.
- */
- String get content {
- Token token = attributeEnd.next;
- if (identical(token, contentEnd)) {
- return "";
- }
- // TODO(danrubel) Handle CDATA and replace HTML character encodings with
- // the actual characters.
- String content = token.lexeme;
- token = token.next;
- if (identical(token, contentEnd)) {
- return content;
- }
- StringBuffer buffer = new StringBuffer();
- buffer.write(content);
- while (!identical(token, contentEnd)) {
- buffer.write(token.lexeme);
- token = token.next;
- }
- return buffer.toString();
- }
-
- @override
- Token get endToken {
- if (nodeEnd != null) {
- return nodeEnd;
- }
- if (closingTag != null) {
- return closingTag;
- }
- if (contentEnd != null) {
- return contentEnd;
- }
- if (!_tagNodes.isEmpty) {
- return _tagNodes[_tagNodes.length - 1].endToken;
- }
- if (attributeEnd != null) {
- return attributeEnd;
- }
- if (!_attributes.isEmpty) {
- return _attributes[_attributes.length - 1].endToken;
- }
- return _tag;
- }
-
- /**
- * Answer the tag name after the starting '<'.
- *
- * @return the tag name (not `null`)
- */
- String get tag => _tag.lexeme;
-
- /**
- * Answer the tag nodes contained in the receiver. Callers should not manipulate the returned list
- * to edit the AST structure.
- *
- * @return the children (not `null`, contains no `null`s)
- */
- List<XmlTagNode> get tagNodes => _tagNodes;
-
- /**
- * Answer the [TokenType.TAG] token after the starting '<'.
- *
- * @return the token (not `null`)
- */
- Token get tagToken => _tag;
-
- @override
- accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this);
-
- /**
- * Answer the attribute with the specified name.
- *
- * @param name the attribute name
- * @return the attribute or `null` if no matching attribute is found
- */
- XmlAttributeNode getAttribute(String name) {
- for (XmlAttributeNode attribute in _attributes) {
- if (attribute.name == name) {
- return attribute;
- }
- }
- return null;
- }
-
- /**
- * Find the attribute with the given name (see [getAttribute] and answer the lexeme
- * for the attribute's value token without the leading and trailing quotes (see
- * [XmlAttributeNode.getText]).
- *
- * @param name the attribute name
- * @return the attribute text or `null` if no matching attribute is found
- */
- String getAttributeText(String name) {
- XmlAttributeNode attribute = getAttribute(name);
- return attribute != null ? attribute.text : null;
- }
-
- @override
- void visitChildren(XmlVisitor visitor) {
- for (XmlAttributeNode node in _attributes) {
- node.accept(visitor);
- }
- for (XmlTagNode node in _tagNodes) {
- node.accept(visitor);
- }
- }
-}
-
-/**
- * The interface `XmlVisitor` defines the behavior of objects that can be used to visit an
- * [XmlNode] structure.
- */
-abstract class XmlVisitor<R> {
- R visitHtmlScriptTagNode(HtmlScriptTagNode node);
-
- R visitHtmlUnit(HtmlUnit htmlUnit);
-
- R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode);
-
- R visitXmlTagNode(XmlTagNode xmlTagNode);
-}
diff --git a/pkg/analyzer/lib/src/generated/incremental_logger.dart b/pkg/analyzer/lib/src/generated/incremental_logger.dart
index 8abc6fe..d942aba 100644
--- a/pkg/analyzer/lib/src/generated/incremental_logger.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_logger.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.incremental_logger;
+library analyzer.src.generated.incremental_logger;
/**
* The shared instance of [Logger] used by several incremental resolution
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart b/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
index bab107e..6cf9af1 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.incremental_resolution_validator;
+library analyzer.src.generated.incremental_resolution_validator;
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
@@ -63,6 +63,7 @@
visitAssertStatement(AssertStatement node) {
AssertStatement other = this.other;
_visitNode(node.condition, other.condition);
+ _visitNode(node.message, other.message);
}
@override
@@ -185,6 +186,14 @@
}
@override
+ visitConfiguration(Configuration node) {
+ Configuration other = this.other;
+ _visitNode(node.name, other.name);
+ _visitNode(node.value, other.value);
+ _visitNode(node.libraryUri, other.libraryUri);
+ }
+
+ @override
visitConstructorDeclaration(ConstructorDeclaration node) {
ConstructorDeclaration other = this.other;
_visitDeclaration(node, other);
@@ -238,6 +247,12 @@
}
@override
+ visitDottedName(DottedName node) {
+ DottedName other = this.other;
+ _visitList(node.components, other.components);
+ }
+
+ @override
visitDoubleLiteral(DoubleLiteral node) {
DoubleLiteral other = this.other;
_visitExpression(node, other);
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index 1192f2c..a80de52 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -2,41 +2,30 @@
// for 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 engine.incremental_resolver;
+library analyzer.src.generated.incremental_resolver;
import 'dart:collection';
import 'dart:math' as math;
-import 'package:analyzer/src/context/cache.dart'
- show CacheEntry, Delta, DeltaResult;
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/error_verifier.dart';
+import 'package:analyzer/src/generated/incremental_logger.dart'
+ show logger, LoggingTimer;
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/task/dart.dart';
import 'package:analyzer/task/general.dart' show CONTENT, LINE_INFO;
-import 'package:analyzer/task/model.dart'
- show AnalysisTarget, ResultDescriptor, TargetedResult, TaskDescriptor;
-
-import 'ast.dart';
-import 'element.dart';
-import 'engine.dart'
- show
- AnalysisContext,
- AnalysisOptions,
- CacheState,
- DartEntry,
- DataDescriptor,
- InternalAnalysisContext,
- RecordingErrorListener,
- SourceEntry;
-import 'error.dart';
-import 'error_verifier.dart';
-import 'incremental_logger.dart' show logger, LoggingTimer;
-import 'java_engine.dart';
-import 'parser.dart';
-import 'resolver.dart';
-import 'scanner.dart';
-import 'source.dart';
-import 'utilities_dart.dart';
+import 'package:analyzer/task/model.dart';
/**
* If `true`, an attempt to resolve API-changing modifications is made.
@@ -971,11 +960,6 @@
LibraryElementImpl _definingLibrary;
/**
- * The [DartEntry] corresponding to the source being resolved.
- */
- DartEntry oldEntry;
-
- /**
* The [CacheEntry] corresponding to the source being resolved.
*/
CacheEntry newSourceEntry;
@@ -1031,7 +1015,6 @@
* given source in the given library.
*/
IncrementalResolver(
- this.oldEntry,
this.newSourceEntry,
this.newUnitEntry,
this._definingUnit,
@@ -1243,14 +1226,6 @@
}
void _shiftEntryErrors() {
- if (oldEntry != null) {
- _shiftEntryErrors_OLD();
- } else {
- _shiftEntryErrors_NEW();
- }
- }
-
- void _shiftEntryErrors_NEW() {
_shiftErrors_NEW(HINTS);
_shiftErrors_NEW(LINTS);
_shiftErrors_NEW(LIBRARY_UNIT_ERRORS);
@@ -1261,13 +1236,6 @@
_shiftErrors_NEW(VERIFY_ERRORS);
}
- void _shiftEntryErrors_OLD() {
- _shiftErrors_OLD(DartEntry.RESOLUTION_ERRORS);
- _shiftErrors_OLD(DartEntry.VERIFICATION_ERRORS);
- _shiftErrors_OLD(DartEntry.HINTS);
- _shiftErrors_OLD(DartEntry.LINTS);
- }
-
void _shiftErrors(List<AnalysisError> errors) {
for (AnalysisError error in errors) {
if (_alreadyShiftedErrors.add(error)) {
@@ -1284,12 +1252,6 @@
_shiftErrors(errors);
}
- void _shiftErrors_OLD(DataDescriptor<List<AnalysisError>> descriptor) {
- List<AnalysisError> errors =
- oldEntry.getValueInLibrary(descriptor, _librarySource);
- _shiftErrors(errors);
- }
-
void _updateCache() {
if (newSourceEntry != null) {
LoggingTimer timer = logger.startTimer();
@@ -1315,14 +1277,6 @@
}
void _updateEntry() {
- if (oldEntry != null) {
- _updateEntry_OLD();
- } else {
- _updateEntry_NEW();
- }
- }
-
- void _updateEntry_NEW() {
_updateErrors_NEW(RESOLVE_TYPE_NAMES_ERRORS, []);
_updateErrors_NEW(RESOLVE_UNIT_ERRORS, _resolveErrors);
_updateErrors_NEW(VARIABLE_REFERENCE_ERRORS, []);
@@ -1335,11 +1289,6 @@
newUnitEntry.setState(LINTS, CacheState.INVALID);
}
- void _updateEntry_OLD() {
- _updateErrors_OLD(DartEntry.RESOLUTION_ERRORS, _resolveErrors);
- _updateErrors_OLD(DartEntry.VERIFICATION_ERRORS, _verifyErrors);
- }
-
List<AnalysisError> _updateErrors(
List<AnalysisError> oldErrors, List<AnalysisError> newErrors) {
List<AnalysisError> errors = new List<AnalysisError>();
@@ -1371,14 +1320,6 @@
newUnitEntry.setValueIncremental(descriptor, errors, true);
}
- void _updateErrors_OLD(DataDescriptor<List<AnalysisError>> descriptor,
- List<AnalysisError> newErrors) {
- List<AnalysisError> oldErrors =
- oldEntry.getValueInLibrary(descriptor, _librarySource);
- List<AnalysisError> errors = _updateErrors(oldErrors, newErrors);
- oldEntry.setValueInLibrary(descriptor, _librarySource, errors);
- }
-
void _verify(AstNode node) {
LoggingTimer timer = logger.startTimer();
try {
@@ -1389,7 +1330,8 @@
_definingLibrary,
_typeProvider,
new InheritanceManager(_definingLibrary),
- _context.analysisOptions.enableSuperMixins);
+ _context.analysisOptions.enableSuperMixins,
+ _context.analysisOptions.enableAssertMessage);
if (_resolutionContext.enclosingClassDeclaration != null) {
errorVerifier.visitClassDeclarationIncrementally(
_resolutionContext.enclosingClassDeclaration);
@@ -1407,19 +1349,14 @@
final Source _unitSource;
/**
- * The [DartEntry] corresponding to the source being resolved.
- */
- DartEntry _oldEntry;
-
- /**
* The [CacheEntry] corresponding to the source being resolved.
*/
- CacheEntry _newSourceEntry;
+ CacheEntry _sourceEntry;
/**
* The [CacheEntry] corresponding to the [LibrarySpecificUnit] being resolved.
*/
- CacheEntry _newUnitEntry;
+ CacheEntry _unitEntry;
final CompilationUnit _oldUnit;
CompilationUnitElement _unitElement;
@@ -1436,9 +1373,8 @@
PoorMansIncrementalResolver(
this._typeProvider,
this._unitSource,
- this._oldEntry,
- this._newSourceEntry,
- this._newUnitEntry,
+ this._sourceEntry,
+ this._unitEntry,
this._oldUnit,
bool resolveApiChanges) {
_resolveApiChanges = resolveApiChanges;
@@ -1497,9 +1433,8 @@
_shiftTokens(firstPair.oldToken);
{
IncrementalResolver incrementalResolver = new IncrementalResolver(
- _oldEntry,
- _newSourceEntry,
- _newUnitEntry,
+ _sourceEntry,
+ _unitEntry,
_unitElement,
_updateOffset,
_updateEndOld,
@@ -1594,9 +1529,8 @@
}
// perform incremental resolution
IncrementalResolver incrementalResolver = new IncrementalResolver(
- _oldEntry,
- _newSourceEntry,
- _newUnitEntry,
+ _sourceEntry,
+ _unitEntry,
_unitElement,
_updateOffset,
_updateEndOld,
@@ -1665,9 +1599,8 @@
NodeReplacer.replace(oldComment, newComment);
// update elements
IncrementalResolver incrementalResolver = new IncrementalResolver(
- _oldEntry,
- _newSourceEntry,
- _newUnitEntry,
+ _sourceEntry,
+ _unitEntry,
_unitElement,
_updateOffset,
_updateEndOld,
@@ -1731,26 +1664,12 @@
}
void _updateEntry() {
- if (_oldEntry != null) {
- _updateEntry_OLD();
- } else {
- _updateEntry_NEW();
- }
- }
-
- void _updateEntry_NEW() {
// scan results
- _newSourceEntry.setValueIncremental(SCAN_ERRORS, _newScanErrors, true);
- _newSourceEntry.setValueIncremental(LINE_INFO, _newLineInfo, false);
+ _sourceEntry.setValueIncremental(SCAN_ERRORS, _newScanErrors, true);
+ _sourceEntry.setValueIncremental(LINE_INFO, _newLineInfo, false);
// parse results
- _newSourceEntry.setValueIncremental(PARSE_ERRORS, _newParseErrors, true);
- _newSourceEntry.setValueIncremental(PARSED_UNIT, _oldUnit, false);
- }
-
- void _updateEntry_OLD() {
- _oldEntry.setValue(SourceEntry.LINE_INFO, _newLineInfo);
- _oldEntry.setValue(DartEntry.SCAN_ERRORS, _newScanErrors);
- _oldEntry.setValue(DartEntry.PARSE_ERRORS, _newParseErrors);
+ _sourceEntry.setValueIncremental(PARSE_ERRORS, _newParseErrors, true);
+ _sourceEntry.setValueIncremental(PARSED_UNIT, _oldUnit, false);
}
/**
diff --git a/pkg/analyzer/lib/src/generated/incremental_scanner.dart b/pkg/analyzer/lib/src/generated/incremental_scanner.dart
index a2e4daf..6f4abee 100644
--- a/pkg/analyzer/lib/src/generated/incremental_scanner.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_scanner.dart
@@ -2,16 +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.
-library engine.incremental_scanner;
+library analyzer.src.generated.incremental_scanner;
import "dart:math" as math;
import 'package:analyzer/src/generated/engine.dart';
-
-import 'error.dart';
-import 'scanner.dart';
-import 'source.dart';
-import 'utilities_collection.dart' show TokenMap;
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap;
/**
* An `IncrementalScanner` is a scanner that scans a subset of a string and
diff --git a/pkg/analyzer/lib/src/generated/interner.dart b/pkg/analyzer/lib/src/generated/interner.dart
index 9ff047b..9741f28 100644
--- a/pkg/analyzer/lib/src/generated/interner.dart
+++ b/pkg/analyzer/lib/src/generated/interner.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library interner;
+library analyzer.src.generated.interner;
import 'dart:collection';
diff --git a/pkg/analyzer/lib/src/generated/java_core.dart b/pkg/analyzer/lib/src/generated/java_core.dart
index 8c96357..acd2337 100644
--- a/pkg/analyzer/lib/src/generated/java_core.dart
+++ b/pkg/analyzer/lib/src/generated/java_core.dart
@@ -1,4 +1,8 @@
-library java.core;
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.src.generated.java_core;
const int LONG_MAX_VALUE = 0x7fffffffffffffff;
@@ -295,14 +299,6 @@
}
class JavaSystem {
- @deprecated
- static void arraycopy(
- List src, int srcPos, List dest, int destPos, int length) {
- for (int i = 0; i < length; i++) {
- dest[destPos + i] = src[srcPos + i];
- }
- }
-
static int currentTimeMillis() {
return (new DateTime.now()).millisecondsSinceEpoch;
}
diff --git a/pkg/analyzer/lib/src/generated/java_engine.dart b/pkg/analyzer/lib/src/generated/java_engine.dart
index affcf8d..be2020f 100644
--- a/pkg/analyzer/lib/src/generated/java_engine.dart
+++ b/pkg/analyzer/lib/src/generated/java_engine.dart
@@ -1,7 +1,11 @@
-library java.engine;
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
-import 'interner.dart';
-import 'java_core.dart';
+library analyzer.src.generated.java_engine;
+
+import 'package:analyzer/src/generated/interner.dart';
+import 'package:analyzer/src/generated/java_core.dart';
/**
* A predicate is a one-argument function that returns a boolean value.
diff --git a/pkg/analyzer/lib/src/generated/java_engine_io.dart b/pkg/analyzer/lib/src/generated/java_engine_io.dart
index 749695a..aa7023d 100644
--- a/pkg/analyzer/lib/src/generated/java_engine_io.dart
+++ b/pkg/analyzer/lib/src/generated/java_engine_io.dart
@@ -1,16 +1,21 @@
-library java.engine.io;
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.src.generated.java_engine_io;
import "dart:io";
-import "java_io.dart";
-class OSUtilities {
- static String LINE_SEPARATOR = isWindows() ? '\r\n' : '\n';
- static bool isWindows() => Platform.operatingSystem == 'windows';
- static bool isMac() => Platform.operatingSystem == 'macos';
-}
+import "package:analyzer/src/generated/java_io.dart";
class FileUtilities2 {
static JavaFile createFile(String path) {
return new JavaFile(path).getAbsoluteFile();
}
}
+
+class OSUtilities {
+ static String LINE_SEPARATOR = isWindows() ? '\r\n' : '\n';
+ static bool isMac() => Platform.operatingSystem == 'macos';
+ static bool isWindows() => Platform.operatingSystem == 'windows';
+}
diff --git a/pkg/analyzer/lib/src/generated/java_io.dart b/pkg/analyzer/lib/src/generated/java_io.dart
index 000746f..dc054d0 100644
--- a/pkg/analyzer/lib/src/generated/java_io.dart
+++ b/pkg/analyzer/lib/src/generated/java_io.dart
@@ -1,11 +1,14 @@
-library java.io;
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.src.generated.java_io;
import "dart:io";
+import 'package:analyzer/src/generated/java_core.dart' show JavaIOException;
import 'package:path/path.dart' as path;
-import 'java_core.dart' show JavaIOException;
-
class JavaFile {
static path.Context pathContext = path.context;
static final String separator = Platform.pathSeparator;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 2074525..b15a92e 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -2,20 +2,21 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.parser;
+library analyzer.src.generated.parser;
import 'dart:collection';
import "dart:math" as math;
-import 'ast.dart';
-import 'engine.dart' show AnalysisEngine, AnalysisOptionsImpl;
-import 'error.dart';
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'scanner.dart';
-import 'source.dart';
-import 'utilities_collection.dart' show TokenMap;
-import 'utilities_dart.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart'
+ show AnalysisEngine, AnalysisOptionsImpl;
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap;
+import 'package:analyzer/src/generated/utilities_dart.dart';
Map<String, MethodTrampoline> methodTable_Parser = <String, MethodTrampoline>{
'parseCompilationUnit_1': new MethodTrampoline(
@@ -196,6 +197,8 @@
1, (Parser target, arg0) => target._parseCommentReferences(arg0)),
'parseCompilationUnitMember_1': new MethodTrampoline(
1, (Parser target, arg0) => target._parseCompilationUnitMember(arg0)),
+ 'parseConfiguration_0':
+ new MethodTrampoline(0, (Parser target) => target._parseConfiguration()),
'parseConstExpression_0': new MethodTrampoline(
0, (Parser target) => target._parseConstExpression()),
'parseConstructor_8': new MethodTrampoline(
@@ -214,6 +217,8 @@
0, (Parser target) => target._parseDocumentationComment()),
'parseDoStatement_0':
new MethodTrampoline(0, (Parser target) => target._parseDoStatement()),
+ 'parseDottedName_0':
+ new MethodTrampoline(0, (Parser target) => target._parseDottedName()),
'parseEmptyStatement_0':
new MethodTrampoline(0, (Parser target) => target._parseEmptyStatement()),
'parseEnumConstantDeclaration_0': new MethodTrampoline(
@@ -574,6 +579,9 @@
if (identical(_oldNode, node.condition)) {
return _parser.parseExpression2();
}
+ if (identical(_oldNode, node.message)) {
+ return _parser.parseExpression2();
+ }
return _notAChild(node);
}
@@ -745,6 +753,18 @@
}
@override
+ AstNode visitConfiguration(Configuration node) {
+ if (identical(_oldNode, node.name)) {
+ throw new InsufficientContextException();
+ } else if (identical(_oldNode, node.value)) {
+ return _parser.parseStringLiteral();
+ } else if (identical(_oldNode, node.libraryUri)) {
+ return _parser.parseStringLiteral();
+ }
+ return _notAChild(node);
+ }
+
+ @override
AstNode visitConstructorDeclaration(ConstructorDeclaration node) {
if (identical(_oldNode, node.documentationComment)) {
throw new InsufficientContextException();
@@ -829,6 +849,14 @@
}
@override
+ AstNode visitDottedName(DottedName node) {
+ if (node.components.contains(_oldNode)) {
+ throw new InsufficientContextException();
+ }
+ return _notAChild(node);
+ }
+
+ @override
AstNode visitDoubleLiteral(DoubleLiteral node) => _notAChild(node);
@override
@@ -2118,6 +2146,12 @@
bool _inInitializer = false;
/**
+ * A flag indicating whether the parser is to parse conditional directives
+ * syntax.
+ */
+ bool parseConditionalDirectives = false;
+
+ /**
* A flag indicating whether the parser is to parse generic method syntax.
*/
bool parseGenericMethods = false;
@@ -2154,30 +2188,6 @@
}
/**
- * Set whether the parser is to parse the async support.
- */
- @deprecated
- void set parseAsync(bool parseAsync) {
- // Async support cannot be disabled
- }
-
- /**
- * Set whether the parser is to parse deferred libraries.
- */
- @deprecated
- void set parseDeferredLibraries(bool parseDeferredLibraries) {
- // Deferred libraries support cannot be disabled
- }
-
- /**
- * Set whether the parser is to parse enum declarations.
- */
- @deprecated
- void set parseEnum(bool parseEnum) {
- // Enum support cannot be disabled
- }
-
- /**
* Set whether parser is to parse function bodies.
*/
void set parseFunctionBodies(bool parseFunctionBodies) {
@@ -4378,10 +4388,16 @@
_reportErrorForNode(
ParserErrorCode.ASSERT_DOES_NOT_TAKE_RETHROW, expression);
}
+ Token comma;
+ Expression message;
+ if (_matches(TokenType.COMMA)) {
+ comma = getAndAdvance();
+ message = parseExpression2();
+ }
Token rightParen = _expect(TokenType.CLOSE_PAREN);
Token semicolon = _expect(TokenType.SEMICOLON);
return new AssertStatement(
- keyword, leftParen, expression, rightParen, semicolon);
+ keyword, leftParen, expression, comma, message, rightParen, semicolon);
}
/**
@@ -5262,6 +5278,52 @@
}
/**
+ * Parse a configuration in either an import or export directive.
+ *
+ * configuration ::=
+ * 'if' '(' test ')' uri
+ *
+ * test ::=
+ * dottedName ('==' stringLiteral)?
+ *
+ * dottedName ::=
+ * identifier ('.' identifier)*
+ */
+ Configuration _parseConfiguration() {
+ Token ifKeyword = _expectKeyword(Keyword.IF);
+ Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
+ DottedName name = _parseDottedName();
+ Token equalToken = null;
+ StringLiteral value = null;
+ if (_matches(TokenType.EQ_EQ)) {
+ equalToken = getAndAdvance();
+ value = parseStringLiteral();
+ if (value is StringInterpolation) {
+ _reportErrorForNode(
+ ParserErrorCode.INVALID_LITERAL_IN_CONFIGURATION, value);
+ }
+ }
+ Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
+ StringLiteral libraryUri = _parseUri();
+ return new Configuration(ifKeyword, leftParenthesis, name, equalToken,
+ value, rightParenthesis, libraryUri);
+ }
+
+ /**
+ * Parse a list of configurations. If conditional directives are not
+ * supported, return an empty list without attempting to parse anything.
+ */
+ List<Configuration> _parseConfigurations() {
+ List<Configuration> configurations = <Configuration>[];
+ if (parseConditionalDirectives) {
+ while (_matchesKeyword(Keyword.IF)) {
+ configurations.add(_parseConfiguration());
+ }
+ }
+ return configurations;
+ }
+
+ /**
* Parse a const expression. Return the const expression that was parsed.
*
* constExpression ::=
@@ -5577,6 +5639,22 @@
}
/**
+ * Parse a dotted name. Return the dotted name that was parsed.
+ *
+ * dottedName ::=
+ * identifier ('.' identifier)*
+ */
+ DottedName _parseDottedName() {
+ List<SimpleIdentifier> components = new List<SimpleIdentifier>();
+ components.add(parseSimpleIdentifier());
+ while (_matches(TokenType.PERIOD)) {
+ _advance();
+ components.add(parseSimpleIdentifier());
+ }
+ return new DottedName(components);
+ }
+
+ /**
* Parse an empty statement. Return the empty statement that was parsed.
*
* emptyStatement ::=
@@ -5683,11 +5761,12 @@
* associated with the directive. Return the export directive that was parsed.
*
* exportDirective ::=
- * metadata 'export' stringLiteral combinator*';'
+ * metadata 'export' stringLiteral configuration* combinator*';'
*/
ExportDirective _parseExportDirective(CommentAndMetadata commentAndMetadata) {
Token exportKeyword = _expectKeyword(Keyword.EXPORT);
StringLiteral libraryUri = _parseUri();
+ List<Configuration> configurations = _parseConfigurations();
List<Combinator> combinators = _parseCombinators();
Token semicolon = _expectSemicolon();
return new ExportDirective(
@@ -5695,6 +5774,7 @@
commentAndMetadata.metadata,
exportKeyword,
libraryUri,
+ configurations,
combinators,
semicolon);
}
@@ -6350,11 +6430,12 @@
* associated with the directive. Return the import directive that was parsed.
*
* importDirective ::=
- * metadata 'import' stringLiteral (deferred)? ('as' identifier)? combinator*';'
+ * metadata 'import' stringLiteral configuration* (deferred)? ('as' identifier)? combinator*';'
*/
ImportDirective _parseImportDirective(CommentAndMetadata commentAndMetadata) {
Token importKeyword = _expectKeyword(Keyword.IMPORT);
StringLiteral libraryUri = _parseUri();
+ List<Configuration> configurations = _parseConfigurations();
Token deferredToken = null;
Token asToken = null;
SimpleIdentifier prefix = null;
@@ -6390,6 +6471,7 @@
commentAndMetadata.metadata,
importKeyword,
libraryUri,
+ configurations,
deferredToken,
asToken,
prefix,
@@ -9469,6 +9551,10 @@
'INVALID_HEX_ESCAPE',
"An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits");
+ static const ParserErrorCode INVALID_LITERAL_IN_CONFIGURATION =
+ const ParserErrorCode('INVALID_LITERAL_IN_CONFIGURATION',
+ "The literal in a configuration cannot contain interpolation");
+
static const ParserErrorCode INVALID_OPERATOR = const ParserErrorCode(
'INVALID_OPERATOR', "The string '{0}' is not a valid operator");
@@ -9862,6 +9948,8 @@
_isEqualTokens(node.assertKeyword, toNode.assertKeyword),
_isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
_isEqualNodes(node.condition, toNode.condition),
+ _isEqualTokens(node.comma, toNode.comma),
+ _isEqualNodes(node.message, toNode.message),
_isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
_isEqualTokens(node.semicolon, toNode.semicolon));
}
@@ -10057,6 +10145,22 @@
}
@override
+ bool visitConfiguration(Configuration node) {
+ Configuration toNode = this._toNode as Configuration;
+ if (_and(
+ _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
+ _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+ _isEqualNodes(node.name, toNode.name),
+ _isEqualTokens(node.equalToken, toNode.equalToken),
+ _isEqualNodes(node.value, toNode.value),
+ _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+ _isEqualNodes(node.libraryUri, toNode.libraryUri))) {
+ return true;
+ }
+ return false;
+ }
+
+ @override
bool visitConstructorDeclaration(ConstructorDeclaration node) {
ConstructorDeclaration toNode = this._toNode as ConstructorDeclaration;
if (_and(
@@ -10152,6 +10256,12 @@
}
@override
+ bool visitDottedName(DottedName node) {
+ DottedName toNode = this._toNode as DottedName;
+ return _isEqualNodeLists(node.components, toNode.components);
+ }
+
+ @override
bool visitDoubleLiteral(DoubleLiteral node) {
DoubleLiteral toNode = this._toNode as DoubleLiteral;
if (_and(_isEqualTokens(node.literal, toNode.literal),
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 0d17e72..03452f4 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -2,53 +2,27 @@
// for 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 engine.resolver;
+library analyzer.src.generated.resolver;
import 'dart:collection';
-import '../task/strong/info.dart' show InferredType, StaticInfo;
-import '../task/strong/rules.dart' show TypeRules;
-import 'ast.dart';
-import 'constant.dart';
-import 'element.dart';
-import 'element_resolver.dart';
-import 'engine.dart';
-import 'error.dart';
-import 'error_verifier.dart';
-import 'html.dart' as ht;
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'scanner.dart';
-import 'scanner.dart' as sc;
-import 'sdk.dart' show DartSdk, SdkLibrary;
-import 'source.dart';
-import 'static_type_analyzer.dart';
-import 'type_system.dart';
-import 'utilities_dart.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/element_resolver.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/error_verifier.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/static_type_analyzer.dart';
+import 'package:analyzer/src/generated/type_system.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/task/strong/info.dart' show InferredType, StaticInfo;
-export 'type_system.dart';
-
-/**
- * Callback signature used by ImplicitConstructorBuilder to register
- * computations to be performed, and their dependencies. A call to this
- * callback indicates that [computation] may be used to compute implicit
- * constructors for [classElement], but that the computation may not be invoked
- * until after implicit constructors have been built for [superclassElement].
- */
-typedef void ImplicitConstructorBuilderCallback(ClassElement classElement,
- ClassElement superclassElement, void computation());
-
-typedef LibraryResolver LibraryResolverFactory(AnalysisContext context);
-
-typedef ResolverVisitor ResolverVisitorFactory(
- Library library, Source source, TypeProvider typeProvider);
-
-typedef StaticTypeAnalyzer StaticTypeAnalyzerFactory(ResolverVisitor visitor);
-
-typedef TypeResolverVisitor TypeResolverVisitorFactory(
- Library library, Source source, TypeProvider typeProvider);
-
-typedef void VoidFunction();
+export 'package:analyzer/src/generated/type_system.dart';
/**
* Instances of the class `BestPracticesVerifier` traverse an AST structure looking for
@@ -113,8 +87,8 @@
@override
Object visitAssignmentExpression(AssignmentExpression node) {
- sc.TokenType operatorType = node.operator.type;
- if (operatorType == sc.TokenType.EQ) {
+ TokenType operatorType = node.operator.type;
+ if (operatorType == TokenType.EQ) {
_checkForUseOfVoidResult(node.rightHandSide);
_checkForInvalidAssignment(node.leftHandSide, node.rightHandSide);
} else {
@@ -214,6 +188,7 @@
// This was determined to not be a good hint, see: dartbug.com/16029
//checkForOverridingPrivateMember(node);
_checkForMissingReturn(node.returnType, node.body);
+ _checkForUnnecessaryNoSuchMethod(node);
return super.visitMethodDeclaration(node);
}
@@ -293,7 +268,7 @@
}
String rhsNameStr = typeName.name.name;
// if x is dynamic
- if (rhsType.isDynamic && rhsNameStr == sc.Keyword.DYNAMIC.syntax) {
+ if (rhsType.isDynamic && rhsNameStr == Keyword.DYNAMIC.syntax) {
if (node.notOperator == null) {
// the is case
_errorReporter.reportErrorForNode(
@@ -553,7 +528,7 @@
*/
bool _checkForDivisionOptimizationHint(BinaryExpression node) {
// Return if the operator is not '/'
- if (node.operator.type != sc.TokenType.SLASH) {
+ if (node.operator.type != TokenType.SLASH) {
return false;
}
// Return if the '/' operator is not defined in core, or if we don't know
@@ -753,35 +728,6 @@
}
/**
- * Check for the passed class declaration for the
- * [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
- *
- * @param node the class declaration to check
- * @return `true` if and only if a hint code is generated on the passed node
- * See [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE].
- */
-// bool _checkForOverrideEqualsButNotHashCode(ClassDeclaration node) {
-// ClassElement classElement = node.element;
-// if (classElement == null) {
-// return false;
-// }
-// MethodElement equalsOperatorMethodElement =
-// classElement.getMethod(sc.TokenType.EQ_EQ.lexeme);
-// if (equalsOperatorMethodElement != null) {
-// PropertyAccessorElement hashCodeElement =
-// classElement.getGetter(_HASHCODE_GETTER_NAME);
-// if (hashCodeElement == null) {
-// _errorReporter.reportErrorForNode(
-// HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
-// node.name,
-// [classElement.displayName]);
-// return true;
-// }
-// }
-// return false;
-// }
-
- /**
* Check for the passed as expression for the [HintCode.UNNECESSARY_CAST] hint code.
*
* @param node the as expression to check
@@ -831,6 +777,83 @@
}
/**
+ * Check for the passed class declaration for the
+ * [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
+ *
+ * @param node the class declaration to check
+ * @return `true` if and only if a hint code is generated on the passed node
+ * See [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE].
+ */
+// bool _checkForOverrideEqualsButNotHashCode(ClassDeclaration node) {
+// ClassElement classElement = node.element;
+// if (classElement == null) {
+// return false;
+// }
+// MethodElement equalsOperatorMethodElement =
+// classElement.getMethod(sc.TokenType.EQ_EQ.lexeme);
+// if (equalsOperatorMethodElement != null) {
+// PropertyAccessorElement hashCodeElement =
+// classElement.getGetter(_HASHCODE_GETTER_NAME);
+// if (hashCodeElement == null) {
+// _errorReporter.reportErrorForNode(
+// HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
+// node.name,
+// [classElement.displayName]);
+// return true;
+// }
+// }
+// return false;
+// }
+
+ /**
+ * Generate a hint for `noSuchMethod` methods that do nothing except of
+ * calling another `noSuchMethod` that is not defined by `Object`.
+ *
+ * @return `true` if and only if a hint code is generated on the passed node
+ * See [HintCode.UNNECESSARY_NO_SUCH_METHOD].
+ */
+ bool _checkForUnnecessaryNoSuchMethod(MethodDeclaration node) {
+ if (node.name.name != FunctionElement.NO_SUCH_METHOD_METHOD_NAME) {
+ return false;
+ }
+ bool isNonObjectNoSuchMethodInvocation(Expression invocation) {
+ if (invocation is MethodInvocation &&
+ invocation.target is SuperExpression &&
+ invocation.argumentList.arguments.length == 1) {
+ SimpleIdentifier name = invocation.methodName;
+ if (name.name == FunctionElement.NO_SUCH_METHOD_METHOD_NAME) {
+ Element methodElement = name.staticElement;
+ Element classElement = methodElement?.enclosingElement;
+ return methodElement is MethodElement &&
+ classElement is ClassElement &&
+ !classElement.type.isObject;
+ }
+ }
+ return false;
+ }
+ FunctionBody body = node.body;
+ if (body is ExpressionFunctionBody) {
+ if (isNonObjectNoSuchMethodInvocation(body.expression)) {
+ _errorReporter.reportErrorForNode(
+ HintCode.UNNECESSARY_NO_SUCH_METHOD, node);
+ return true;
+ }
+ } else if (body is BlockFunctionBody) {
+ List<Statement> statements = body.block.statements;
+ if (statements.length == 1) {
+ Statement returnStatement = statements.first;
+ if (returnStatement is ReturnStatement &&
+ isNonObjectNoSuchMethodInvocation(returnStatement.expression)) {
+ _errorReporter.reportErrorForNode(
+ HintCode.UNNECESSARY_NO_SUCH_METHOD, node);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
* Check for situations where the result of a method or function is used, when it returns 'void'.
*
* TODO(jwren) Many other situations of use could be covered. We currently cover the cases var x =
@@ -1647,9 +1670,9 @@
@override
Object visitBinaryExpression(BinaryExpression node) {
- sc.Token operator = node.operator;
- bool isAmpAmp = operator.type == sc.TokenType.AMPERSAND_AMPERSAND;
- bool isBarBar = operator.type == sc.TokenType.BAR_BAR;
+ Token operator = node.operator;
+ bool isAmpAmp = operator.type == TokenType.AMPERSAND_AMPERSAND;
+ bool isBarBar = operator.type == TokenType.BAR_BAR;
if (isAmpAmp || isBarBar) {
Expression lhsCondition = node.leftOperand;
if (!_isDebugConstant(lhsCondition)) {
@@ -2144,7 +2167,7 @@
ExecutableElement outerExecutable = _enclosingExecutable;
try {
SimpleIdentifier functionName = node.name;
- sc.Token property = node.propertyKeyword;
+ Token property = node.propertyKeyword;
if (property == null) {
if (_enclosingExecutable != null) {
_enclosingExecutable =
@@ -2160,7 +2183,7 @@
} else {
PropertyAccessorElement accessor =
_findIdentifier(_enclosingUnit.accessors, functionName);
- if ((property as sc.KeywordToken).keyword == sc.Keyword.SET) {
+ if ((property as KeywordToken).keyword == Keyword.SET) {
accessor = accessor.variable.setter;
functionName.staticElement = accessor;
}
@@ -2254,7 +2277,7 @@
Object visitMethodDeclaration(MethodDeclaration node) {
ExecutableElement outerExecutable = _enclosingExecutable;
try {
- sc.Token property = node.propertyKeyword;
+ Token property = node.propertyKeyword;
SimpleIdentifier methodName = node.name;
String nameOfMethod = methodName.name;
if (property == null) {
@@ -2264,7 +2287,7 @@
} else {
PropertyAccessorElement accessor =
_findIdentifier(_enclosingClass.accessors, methodName);
- if ((property as sc.KeywordToken).keyword == sc.Keyword.SET) {
+ if ((property as KeywordToken).keyword == Keyword.SET) {
accessor = accessor.variable.setter;
methodName.staticElement = accessor;
}
@@ -2894,7 +2917,7 @@
_inFunction = wasInFunction;
}
FunctionBody body = expression.body;
- sc.Token property = node.propertyKeyword;
+ Token property = node.propertyKeyword;
if (property == null || _inFunction) {
SimpleIdentifier functionName = node.name;
FunctionElementImpl element =
@@ -3123,12 +3146,12 @@
_inFunction = wasInFunction;
}
bool isStatic = node.isStatic;
- sc.Token property = node.propertyKeyword;
+ Token property = node.propertyKeyword;
FunctionBody body = node.body;
if (property == null) {
SimpleIdentifier methodName = node.name;
String nameOfMethod = methodName.name;
- if (nameOfMethod == sc.TokenType.MINUS.lexeme &&
+ if (nameOfMethod == TokenType.MINUS.lexeme &&
node.parameters.parameters.length == 0) {
nameOfMethod = "unary-";
}
@@ -4129,11 +4152,11 @@
if (_nodeExits(leftHandSide)) {
return true;
}
- if (node.operator.type == sc.TokenType.QUESTION_QUESTION_EQ) {
+ if (node.operator.type == TokenType.QUESTION_QUESTION_EQ) {
return false;
}
if (leftHandSide is PropertyAccess &&
- leftHandSide.operator.type == sc.TokenType.QUESTION_PERIOD) {
+ leftHandSide.operator.type == TokenType.QUESTION_PERIOD) {
return false;
}
return _nodeExits(node.rightHandSide);
@@ -4147,13 +4170,13 @@
bool visitBinaryExpression(BinaryExpression node) {
Expression lhsExpression = node.leftOperand;
Expression rhsExpression = node.rightOperand;
- sc.TokenType operatorType = node.operator.type;
+ TokenType operatorType = node.operator.type;
// If the operator is ||, then only consider the RHS of the binary
// expression if the left hand side is the false literal.
// TODO(jwren) Do we want to take constant expressions into account,
// evaluate if(false) {} differently than if(<condition>), when <condition>
// evaluates to a constant false value?
- if (operatorType == sc.TokenType.BAR_BAR) {
+ if (operatorType == TokenType.BAR_BAR) {
if (lhsExpression is BooleanLiteral) {
BooleanLiteral booleanLiteral = lhsExpression;
if (!booleanLiteral.value) {
@@ -4164,7 +4187,7 @@
}
// If the operator is &&, then only consider the RHS of the binary
// expression if the left hand side is the true literal.
- if (operatorType == sc.TokenType.AMPERSAND_AMPERSAND) {
+ if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
if (lhsExpression is BooleanLiteral) {
BooleanLiteral booleanLiteral = lhsExpression;
if (booleanLiteral.value) {
@@ -4175,7 +4198,7 @@
}
// If the operator is ??, then don't consider the RHS of the binary
// expression.
- if (operatorType == sc.TokenType.QUESTION_QUESTION) {
+ if (operatorType == TokenType.QUESTION_QUESTION) {
return _nodeExits(lhsExpression);
}
return _nodeExits(lhsExpression) || _nodeExits(rhsExpression);
@@ -4376,7 +4399,7 @@
if (target.accept(this)) {
return true;
}
- if (node.operator.type == sc.TokenType.QUESTION_PERIOD) {
+ if (node.operator.type == TokenType.QUESTION_PERIOD) {
return false;
}
}
@@ -4898,7 +4921,10 @@
return;
}
if (parent2 is VariableDeclarationList) {
- return;
+ // If it's a field's type, it still counts as used.
+ if (parent2.parent is! FieldDeclaration) {
+ return;
+ }
}
}
}
@@ -5011,438 +5037,6 @@
}
/**
- * Instances of the class {@code HtmlTagInfo} record information about the tags used in an HTML
- * file.
- */
-class HtmlTagInfo {
- /**
- * An array containing all of the tags used in the HTML file.
- */
- List<String> allTags;
-
- /**
- * A table mapping the id's defined in the HTML file to an array containing the names of tags with
- * that identifier.
- */
- HashMap<String, String> idToTagMap;
-
- /**
- * A table mapping the classes defined in the HTML file to an array containing the names of tags
- * with that class.
- */
- HashMap<String, List<String>> classToTagsMap;
-
- /**
- * Initialize a newly created information holder to hold the given information about the tags in
- * an HTML file.
- *
- * @param allTags an array containing all of the tags used in the HTML file
- * @param idToTagMap a table mapping the id's defined in the HTML file to an array containing the
- * names of tags with that identifier
- * @param classToTagsMap a table mapping the classes defined in the HTML file to an array
- * containing the names of tags with that class
- */
- HtmlTagInfo(this.allTags, this.idToTagMap, this.classToTagsMap);
-
- /**
- * Return an array containing the tags that have the given class, or {@code null} if there are no
- * such tags.
- *
- * @return an array containing the tags that have the given class
- */
- List<String> getTagsWithClass(String identifier) {
- return classToTagsMap[identifier];
- }
-
- /**
- * Return the tag that has the given identifier, or {@code null} if there is no such tag (the
- * identifier is not defined).
- *
- * @return the tag that has the given identifier
- */
- String getTagWithId(String identifier) {
- return idToTagMap[identifier];
- }
-}
-
-/**
- * Instances of the class {@code HtmlTagInfoBuilder} gather information about the tags used in one
- * or more HTML structures.
- */
-class HtmlTagInfoBuilder implements ht.XmlVisitor {
- /**
- * The name of the 'id' attribute.
- */
- static final String ID_ATTRIBUTE = "id";
-
- /**
- * The name of the 'class' attribute.
- */
- static final String ID_CLASS = "class";
-
- /**
- * A set containing all of the tag names used in the HTML.
- */
- HashSet<String> tagSet = new HashSet<String>();
-
- /**
- * A table mapping the id's that are defined to the tag name with that id.
- */
- HashMap<String, String> idMap = new HashMap<String, String>();
-
- /**
- * A table mapping the classes that are defined to a set of the tag names with that class.
- */
- HashMap<String, HashSet<String>> classMap =
- new HashMap<String, HashSet<String>>();
-
- /**
- * Initialize a newly created HTML tag info builder.
- */
- HtmlTagInfoBuilder();
-
- /**
- * Create a tag information holder holding all of the information gathered about the tags in the
- * HTML structures that were visited.
- *
- * @return the information gathered about the tags in the visited HTML structures
- */
- HtmlTagInfo getTagInfo() {
- List<String> allTags = tagSet.toList();
- HashMap<String, List<String>> classToTagsMap =
- new HashMap<String, List<String>>();
- classMap.forEach((String key, Set<String> tags) {
- classToTagsMap[key] = tags.toList();
- });
- return new HtmlTagInfo(allTags, idMap, classToTagsMap);
- }
-
- @override
- visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) {
- visitXmlTagNode(node);
- }
-
- @override
- visitHtmlUnit(ht.HtmlUnit node) {
- node.visitChildren(this);
- }
-
- @override
- visitXmlAttributeNode(ht.XmlAttributeNode node) {}
-
- @override
- visitXmlTagNode(ht.XmlTagNode node) {
- node.visitChildren(this);
- String tagName = node.tag;
- tagSet.add(tagName);
- for (ht.XmlAttributeNode attribute in node.attributes) {
- String attributeName = attribute.name;
- if (attributeName == ID_ATTRIBUTE) {
- String attributeValue = attribute.text;
- if (attributeValue != null) {
- String tag = idMap[attributeValue];
- if (tag == null) {
- idMap[attributeValue] = tagName;
- } else {
-// reportError(HtmlWarningCode.MULTIPLY_DEFINED_ID, valueToken);
- }
- }
- } else if (attributeName == ID_CLASS) {
- String attributeValue = attribute.text;
- if (attributeValue != null) {
- HashSet<String> tagList = classMap[attributeValue];
- if (tagList == null) {
- tagList = new HashSet<String>();
- classMap[attributeValue] = tagList;
- } else {
-// reportError(HtmlWarningCode.MULTIPLY_DEFINED_ID, valueToken);
- }
- tagList.add(tagName);
- }
- }
- }
- }
-
-// /**
-// * Report an error with the given error code at the given location. Use the given arguments to
-// * compose the error message.
-// *
-// * @param errorCode the error code of the error to be reported
-// * @param offset the offset of the first character to be highlighted
-// * @param length the number of characters to be highlighted
-// * @param arguments the arguments used to compose the error message
-// */
-// private void reportError(ErrorCode errorCode, Token token, Object... arguments) {
-// errorListener.onError(new AnalysisError(
-// htmlElement.getSource(),
-// token.getOffset(),
-// token.getLength(),
-// errorCode,
-// arguments));
-// }
-//
-// /**
-// * Report an error with the given error code at the given location. Use the given arguments to
-// * compose the error message.
-// *
-// * @param errorCode the error code of the error to be reported
-// * @param offset the offset of the first character to be highlighted
-// * @param length the number of characters to be highlighted
-// * @param arguments the arguments used to compose the error message
-// */
-// private void reportError(ErrorCode errorCode, int offset, int length, Object... arguments) {
-// errorListener.onError(new AnalysisError(
-// htmlElement.getSource(),
-// offset,
-// length,
-// errorCode,
-// arguments));
-// }
-}
-
-/**
- * Instances of the class `HtmlUnitBuilder` build an element model for a single HTML unit.
- */
-class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
- static String _SRC = "src";
-
- /**
- * The analysis context in which the element model will be built.
- */
- final InternalAnalysisContext _context;
-
- /**
- * The error listener to which errors will be reported.
- */
- RecordingErrorListener _errorListener;
-
- /**
- * The HTML element being built.
- */
- HtmlElementImpl _htmlElement;
-
- /**
- * The elements in the path from the HTML unit to the current tag node.
- */
- List<ht.XmlTagNode> _parentNodes;
-
- /**
- * The script elements being built.
- */
- List<HtmlScriptElement> _scripts;
-
- /**
- * A set of the libraries that were resolved while resolving the HTML unit.
- */
- Set<Library> _resolvedLibraries = new HashSet<Library>();
-
- /**
- * Initialize a newly created HTML unit builder.
- *
- * @param context the analysis context in which the element model will be built
- */
- HtmlUnitBuilder(this._context) {
- this._errorListener = new RecordingErrorListener();
- }
-
- /**
- * Return the listener to which analysis errors will be reported.
- *
- * @return the listener to which analysis errors will be reported
- */
- RecordingErrorListener get errorListener => _errorListener;
-
- /**
- * Return an array containing information about all of the libraries that were resolved.
- *
- * @return an array containing the libraries that were resolved
- */
- Set<Library> get resolvedLibraries => _resolvedLibraries;
-
- /**
- * Build the HTML element for the given source.
- *
- * @param source the source describing the compilation unit
- * @param unit the AST structure representing the HTML
- * @throws AnalysisException if the analysis could not be performed
- */
- HtmlElementImpl buildHtmlElement(Source source, ht.HtmlUnit unit) {
- HtmlElementImpl result = new HtmlElementImpl(_context, source.shortName);
- result.source = source;
- _htmlElement = result;
- unit.accept(this);
- _htmlElement = null;
- unit.element = result;
- return result;
- }
-
- @override
- Object visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) {
- if (_parentNodes.contains(node)) {
- return _reportCircularity(node);
- }
- _parentNodes.add(node);
- try {
- Source htmlSource = _htmlElement.source;
- ht.XmlAttributeNode scriptAttribute = _getScriptSourcePath(node);
- String scriptSourcePath =
- scriptAttribute == null ? null : scriptAttribute.text;
- if (node.attributeEnd.type == ht.TokenType.GT &&
- scriptSourcePath == null) {
- EmbeddedHtmlScriptElementImpl script =
- new EmbeddedHtmlScriptElementImpl(node);
- try {
- LibraryResolver resolver = new LibraryResolver(_context);
- LibraryElementImpl library =
- resolver.resolveEmbeddedLibrary(htmlSource, node.script, true);
- script.scriptLibrary = library;
- _resolvedLibraries.addAll(resolver.resolvedLibraries);
- _errorListener.addAll(resolver.errorListener);
- } on AnalysisException catch (exception, stackTrace) {
- //TODO (danrubel): Handle or forward the exception
- AnalysisEngine.instance.logger.logError(
- "Could not resolve script tag",
- new CaughtException(exception, stackTrace));
- }
- node.scriptElement = script;
- _scripts.add(script);
- } else {
- ExternalHtmlScriptElementImpl script =
- new ExternalHtmlScriptElementImpl(node);
- if (scriptSourcePath != null) {
- try {
- scriptSourcePath = Uri.encodeFull(scriptSourcePath);
- // Force an exception to be thrown if the URI is invalid so that we
- // can report the problem.
- parseUriWithException(scriptSourcePath);
- Source scriptSource =
- _context.sourceFactory.resolveUri(htmlSource, scriptSourcePath);
- script.scriptSource = scriptSource;
- if (!_context.exists(scriptSource)) {
- _reportValueError(HtmlWarningCode.URI_DOES_NOT_EXIST,
- scriptAttribute, [scriptSourcePath]);
- }
- } on URISyntaxException {
- _reportValueError(HtmlWarningCode.INVALID_URI, scriptAttribute,
- [scriptSourcePath]);
- }
- }
- node.scriptElement = script;
- _scripts.add(script);
- }
- } finally {
- _parentNodes.remove(node);
- }
- return null;
- }
-
- @override
- Object visitHtmlUnit(ht.HtmlUnit node) {
- _parentNodes = new List<ht.XmlTagNode>();
- _scripts = new List<HtmlScriptElement>();
- try {
- node.visitChildren(this);
- _htmlElement.scripts = new List.from(_scripts);
- } finally {
- _scripts = null;
- _parentNodes = null;
- }
- return null;
- }
-
- @override
- Object visitXmlAttributeNode(ht.XmlAttributeNode node) => null;
-
- @override
- Object visitXmlTagNode(ht.XmlTagNode node) {
- if (_parentNodes.contains(node)) {
- return _reportCircularity(node);
- }
- _parentNodes.add(node);
- try {
- node.visitChildren(this);
- } finally {
- _parentNodes.remove(node);
- }
- return null;
- }
-
- /**
- * Return the first source attribute for the given tag node, or `null` if it does not exist.
- *
- * @param node the node containing attributes
- * @return the source attribute contained in the given tag
- */
- ht.XmlAttributeNode _getScriptSourcePath(ht.XmlTagNode node) {
- for (ht.XmlAttributeNode attribute in node.attributes) {
- if (attribute.name == _SRC) {
- return attribute;
- }
- }
- return null;
- }
-
- Object _reportCircularity(ht.XmlTagNode node) {
- //
- // This should not be possible, but we have an error report that suggests
- // that it happened at least once. This code will guard against infinite
- // recursion and might help us identify the cause of the issue.
- //
- StringBuffer buffer = new StringBuffer();
- buffer.write("Found circularity in XML nodes: ");
- bool first = true;
- for (ht.XmlTagNode pathNode in _parentNodes) {
- if (first) {
- first = false;
- } else {
- buffer.write(", ");
- }
- String tagName = pathNode.tag;
- if (identical(pathNode, node)) {
- buffer.write("*");
- buffer.write(tagName);
- buffer.write("*");
- } else {
- buffer.write(tagName);
- }
- }
- AnalysisEngine.instance.logger.logError(buffer.toString());
- return null;
- }
-
- /**
- * Report an error with the given error code at the given location. Use the given arguments to
- * compose the error message.
- *
- * @param errorCode the error code of the error to be reported
- * @param offset the offset of the first character to be highlighted
- * @param length the number of characters to be highlighted
- * @param arguments the arguments used to compose the error message
- */
- void _reportErrorForOffset(
- ErrorCode errorCode, int offset, int length, List<Object> arguments) {
- _errorListener.onError(new AnalysisError(
- _htmlElement.source, offset, length, errorCode, arguments));
- }
-
- /**
- * Report an error with the given error code at the location of the value of the given attribute.
- * Use the given arguments to compose the error message.
- *
- * @param errorCode the error code of the error to be reported
- * @param offset the offset of the first character to be highlighted
- * @param length the number of characters to be highlighted
- * @param arguments the arguments used to compose the error message
- */
- void _reportValueError(ErrorCode errorCode, ht.XmlAttributeNode attribute,
- List<Object> arguments) {
- int offset = attribute.valueToken.offset + 1;
- int length = attribute.valueToken.length - 2;
- _reportErrorForOffset(errorCode, offset, length, arguments);
- }
-}
-
-/**
* Instances of the class `ImplicitLabelScope` represent the scope statements
* that can be the target of unlabeled break and continue statements.
*/
@@ -5792,11 +5386,6 @@
final TypeSystem _typeSystem;
/**
- * The DDC type rules, used to create the inference info nodes.
- */
- final TypeRules _rules;
-
- /**
* A stack of return types for all of the enclosing
* functions and methods.
*/
@@ -5804,8 +5393,7 @@
InferenceContext._(this._errorListener, TypeProvider typeProvider,
this._typeSystem, this._inferenceHints)
- : _typeProvider = typeProvider,
- _rules = new TypeRules(typeProvider);
+ : _typeProvider = typeProvider;
/**
* Get the return type of the current enclosing function, if any.
@@ -5846,7 +5434,7 @@
* [type] has been inferred as the type of [node].
*/
void recordInference(Expression node, DartType type) {
- StaticInfo info = InferredType.create(_rules, node, type);
+ StaticInfo info = InferredType.create(_typeSystem, node, type);
if (!_inferenceHints || info == null) {
return;
}
@@ -6905,7 +6493,7 @@
List<String> namedParameters) {
DynamicTypeImpl dynamicType = DynamicTypeImpl.instance;
SimpleIdentifier nameIdentifier = new SimpleIdentifier(
- new sc.StringToken(sc.TokenType.IDENTIFIER, name, 0));
+ new StringToken(TokenType.IDENTIFIER, name, 0));
ExecutableElementImpl executable;
if (elementArrayToMerge[0] is MethodElement) {
MultiplyInheritedMethodElementImpl unionedMethod =
@@ -7094,652 +6682,6 @@
}
/**
- * Instances of the class `Library` represent the data about a single library during the
- * resolution of some (possibly different) library. They are not intended to be used except during
- * the resolution process.
- */
-class Library {
- /**
- * An empty list that can be used to initialize lists of libraries.
- */
- static const List<Library> _EMPTY_ARRAY = const <Library>[];
-
- /**
- * The prefix of a URI using the dart-ext scheme to reference a native code library.
- */
- static String _DART_EXT_SCHEME = "dart-ext:";
-
- /**
- * The analysis context in which this library is being analyzed.
- */
- final InternalAnalysisContext _analysisContext;
-
- /**
- * The inheritance manager which is used for this member lookups in this library.
- */
- InheritanceManager _inheritanceManager;
-
- /**
- * The listener to which analysis errors will be reported.
- */
- final AnalysisErrorListener errorListener;
-
- /**
- * The source specifying the defining compilation unit of this library.
- */
- final Source librarySource;
-
- /**
- * The library element representing this library.
- */
- LibraryElementImpl _libraryElement;
-
- /**
- * A list containing all of the libraries that are imported into this library.
- */
- List<Library> _importedLibraries = _EMPTY_ARRAY;
-
- /**
- * A table mapping URI-based directive to the actual URI value.
- */
- HashMap<UriBasedDirective, String> _directiveUris =
- new HashMap<UriBasedDirective, String>();
-
- /**
- * A flag indicating whether this library explicitly imports core.
- */
- bool explicitlyImportsCore = false;
-
- /**
- * A list containing all of the libraries that are exported from this library.
- */
- List<Library> _exportedLibraries = _EMPTY_ARRAY;
-
- /**
- * A table mapping the sources for the compilation units in this library to their corresponding
- * AST structures.
- */
- HashMap<Source, CompilationUnit> _astMap =
- new HashMap<Source, CompilationUnit>();
-
- /**
- * The library scope used when resolving elements within this library's compilation units.
- */
- LibraryScope _libraryScope;
-
- /**
- * Initialize a newly created data holder that can maintain the data associated with a library.
- *
- * @param analysisContext the analysis context in which this library is being analyzed
- * @param errorListener the listener to which analysis errors will be reported
- * @param librarySource the source specifying the defining compilation unit of this library
- */
- Library(this._analysisContext, this.errorListener, this.librarySource) {
- this._libraryElement =
- _analysisContext.getLibraryElement(librarySource) as LibraryElementImpl;
- }
-
- /**
- * Return an array of the [CompilationUnit]s that make up the library. The first unit is
- * always the defining unit.
- *
- * @return an array of the [CompilationUnit]s that make up the library. The first unit is
- * always the defining unit
- */
- List<CompilationUnit> get compilationUnits {
- List<CompilationUnit> unitArrayList = new List<CompilationUnit>();
- unitArrayList.add(definingCompilationUnit);
- for (Source source in _astMap.keys.toSet()) {
- if (librarySource != source) {
- unitArrayList.add(getAST(source));
- }
- }
- return unitArrayList;
- }
-
- /**
- * Return a collection containing the sources for the compilation units in this library, including
- * the defining compilation unit.
- *
- * @return the sources for the compilation units in this library
- */
- Set<Source> get compilationUnitSources => _astMap.keys.toSet();
-
- /**
- * Return the AST structure associated with the defining compilation unit for this library.
- *
- * @return the AST structure associated with the defining compilation unit for this library
- * @throws AnalysisException if an AST structure could not be created for the defining compilation
- * unit
- */
- CompilationUnit get definingCompilationUnit => getAST(librarySource);
-
- /**
- * Set the libraries that are exported by this library to be those in the given array.
- *
- * @param exportedLibraries the libraries that are exported by this library
- */
- void set exportedLibraries(List<Library> exportedLibraries) {
- this._exportedLibraries = exportedLibraries;
- }
-
- /**
- * Return an array containing the libraries that are exported from this library.
- *
- * @return an array containing the libraries that are exported from this library
- */
- List<Library> get exports => _exportedLibraries;
-
- /**
- * Set the libraries that are imported into this library to be those in the given array.
- *
- * @param importedLibraries the libraries that are imported into this library
- */
- void set importedLibraries(List<Library> importedLibraries) {
- this._importedLibraries = importedLibraries;
- }
-
- /**
- * Return an array containing the libraries that are imported into this library.
- *
- * @return an array containing the libraries that are imported into this library
- */
- List<Library> get imports => _importedLibraries;
-
- /**
- * Return an array containing the libraries that are either imported or exported from this
- * library.
- *
- * @return the libraries that are either imported or exported from this library
- */
- List<Library> get importsAndExports {
- HashSet<Library> libraries = new HashSet<Library>();
- for (Library library in _importedLibraries) {
- libraries.add(library);
- }
- for (Library library in _exportedLibraries) {
- libraries.add(library);
- }
- return new List.from(libraries);
- }
-
- /**
- * Return the inheritance manager for this library.
- *
- * @return the inheritance manager for this library
- */
- InheritanceManager get inheritanceManager {
- if (_inheritanceManager == null) {
- return _inheritanceManager = new InheritanceManager(_libraryElement);
- }
- return _inheritanceManager;
- }
-
- /**
- * Return the library element representing this library, creating it if necessary.
- *
- * @return the library element representing this library
- */
- LibraryElementImpl get libraryElement {
- if (_libraryElement == null) {
- try {
- _libraryElement = _analysisContext.computeLibraryElement(librarySource)
- as LibraryElementImpl;
- } on AnalysisException catch (exception, stackTrace) {
- AnalysisEngine.instance.logger.logError(
- "Could not compute library element for ${librarySource.fullName}",
- new CaughtException(exception, stackTrace));
- }
- }
- return _libraryElement;
- }
-
- /**
- * Set the library element representing this library to the given library element.
- *
- * @param libraryElement the library element representing this library
- */
- void set libraryElement(LibraryElementImpl libraryElement) {
- this._libraryElement = libraryElement;
- if (_inheritanceManager != null) {
- _inheritanceManager.libraryElement = libraryElement;
- }
- }
-
- /**
- * Return the library scope used when resolving elements within this library's compilation units.
- *
- * @return the library scope used when resolving elements within this library's compilation units
- */
- LibraryScope get libraryScope {
- if (_libraryScope == null) {
- _libraryScope = new LibraryScope(_libraryElement, errorListener);
- }
- return _libraryScope;
- }
-
- /**
- * Return the AST structure associated with the given source.
- *
- * @param source the source representing the compilation unit whose AST is to be returned
- * @return the AST structure associated with the given source
- * @throws AnalysisException if an AST structure could not be created for the compilation unit
- */
- CompilationUnit getAST(Source source) {
- CompilationUnit unit = _astMap[source];
- if (unit == null) {
- unit = _analysisContext.computeResolvableCompilationUnit(source);
- _astMap[source] = unit;
- }
- return unit;
- }
-
- /**
- * Return the result of resolving the URI of the given URI-based directive against the URI of the
- * library, or `null` if the URI is not valid. If the URI is not valid, report the error.
- *
- * @param directive the directive which URI should be resolved
- * @return the result of resolving the URI against the URI of the library
- */
- Source getSource(UriBasedDirective directive) {
- StringLiteral uriLiteral = directive.uri;
- if (uriLiteral is StringInterpolation) {
- errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset,
- uriLiteral.length, CompileTimeErrorCode.URI_WITH_INTERPOLATION));
- return null;
- }
- String uriContent = uriLiteral.stringValue.trim();
- _directiveUris[directive] = uriContent;
- uriContent = Uri.encodeFull(uriContent);
- if (directive is ImportDirective &&
- uriContent.startsWith(_DART_EXT_SCHEME)) {
- _libraryElement.hasExtUri = true;
- return null;
- }
- try {
- parseUriWithException(uriContent);
- Source source =
- _analysisContext.sourceFactory.resolveUri(librarySource, uriContent);
- if (!_analysisContext.exists(source)) {
- errorListener.onError(new AnalysisError(
- librarySource,
- uriLiteral.offset,
- uriLiteral.length,
- CompileTimeErrorCode.URI_DOES_NOT_EXIST,
- [uriContent]));
- }
- return source;
- } on URISyntaxException {
- errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset,
- uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriContent]));
- }
- return null;
- }
-
- /**
- * Returns the URI value of the given directive.
- */
- String getUri(UriBasedDirective directive) => _directiveUris[directive];
-
- /**
- * Set the AST structure associated with the defining compilation unit for this library to the
- * given AST structure.
- *
- * @param unit the AST structure associated with the defining compilation unit for this library
- */
- void setDefiningCompilationUnit(CompilationUnit unit) {
- _astMap[librarySource] = unit;
- }
-
- @override
- String toString() => librarySource.shortName;
-}
-
-/**
- * Instances of the class `LibraryElementBuilder` build an element model for a single library.
- */
-class LibraryElementBuilder {
- /**
- * The analysis context in which the element model will be built.
- */
- final InternalAnalysisContext _analysisContext;
-
- /**
- * The listener to which errors will be reported.
- */
- final AnalysisErrorListener _errorListener;
-
- /**
- * Initialize a newly created library element builder.
- *
- * @param analysisContext the analysis context in which the element model will be built
- * @param errorListener the listener to which errors will be reported
- */
- LibraryElementBuilder(this._analysisContext, this._errorListener);
-
- /**
- * Build the library element for the given library.
- *
- * @param library the library for which an element model is to be built
- * @return the library element that was built
- * @throws AnalysisException if the analysis could not be performed
- */
- LibraryElementImpl buildLibrary(Library library) {
- CompilationUnitBuilder builder = new CompilationUnitBuilder();
- Source librarySource = library.librarySource;
- CompilationUnit definingCompilationUnit = library.definingCompilationUnit;
- CompilationUnitElementImpl definingCompilationUnitElement = builder
- .buildCompilationUnit(
- librarySource, definingCompilationUnit, librarySource);
- NodeList<Directive> directives = definingCompilationUnit.directives;
- LibraryDirective libraryDirective = null;
- LibraryIdentifier libraryNameNode = null;
- bool hasPartDirective = false;
- FunctionElement entryPoint =
- _findEntryPoint(definingCompilationUnitElement);
- List<Directive> directivesToResolve = new List<Directive>();
- List<CompilationUnitElementImpl> sourcedCompilationUnits =
- new List<CompilationUnitElementImpl>();
- for (Directive directive in directives) {
- //
- // We do not build the elements representing the import and export
- // directives at this point. That is not done until we get to
- // LibraryResolver.buildDirectiveModels() because we need the
- // LibraryElements for the referenced libraries, which might not exist at
- // this point (due to the possibility of circular references).
- //
- if (directive is LibraryDirective) {
- if (libraryNameNode == null) {
- libraryDirective = directive;
- libraryNameNode = directive.name;
- directivesToResolve.add(directive);
- }
- } else if (directive is PartDirective) {
- PartDirective partDirective = directive;
- StringLiteral partUri = partDirective.uri;
- Source partSource = partDirective.source;
- if (_analysisContext.exists(partSource)) {
- hasPartDirective = true;
- CompilationUnit partUnit = library.getAST(partSource);
- CompilationUnitElementImpl part =
- builder.buildCompilationUnit(partSource, partUnit, librarySource);
- part.uriOffset = partUri.offset;
- part.uriEnd = partUri.end;
- part.uri = partDirective.uriContent;
- //
- // Validate that the part contains a part-of directive with the same
- // name as the library.
- //
- String partLibraryName =
- _getPartLibraryName(partSource, partUnit, directivesToResolve);
- if (partLibraryName == null) {
- _errorListener.onError(new AnalysisError(
- librarySource,
- partUri.offset,
- partUri.length,
- CompileTimeErrorCode.PART_OF_NON_PART,
- [partUri.toSource()]));
- } else if (libraryNameNode == null) {
- // TODO(brianwilkerson) Collect the names declared by the part.
- // If they are all the same then we can use that name as the
- // inferred name of the library and present it in a quick-fix.
- // partLibraryNames.add(partLibraryName);
- } else if (libraryNameNode.name != partLibraryName) {
- _errorListener.onError(new AnalysisError(
- librarySource,
- partUri.offset,
- partUri.length,
- StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
- [libraryNameNode.name, partLibraryName]));
- }
- if (entryPoint == null) {
- entryPoint = _findEntryPoint(part);
- }
- directive.element = part;
- sourcedCompilationUnits.add(part);
- }
- }
- }
- if (hasPartDirective && libraryNameNode == null) {
- _errorListener.onError(new AnalysisError(librarySource, 0, 0,
- ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART));
- }
- //
- // Create and populate the library element.
- //
- LibraryElementImpl libraryElement = new LibraryElementImpl.forNode(
- _analysisContext.getContextFor(librarySource), libraryNameNode);
- _setDocRange(libraryElement, libraryDirective);
- libraryElement.definingCompilationUnit = definingCompilationUnitElement;
- if (entryPoint != null) {
- libraryElement.entryPoint = entryPoint;
- }
- int sourcedUnitCount = sourcedCompilationUnits.length;
- libraryElement.parts = sourcedCompilationUnits;
- for (Directive directive in directivesToResolve) {
- directive.element = libraryElement;
- }
- library.libraryElement = libraryElement;
- if (sourcedUnitCount > 0) {
- _patchTopLevelAccessors(libraryElement);
- }
- return libraryElement;
- }
-
- /**
- * Build the library element for the given library. The resulting element is
- * stored in the [ResolvableLibrary] structure.
- *
- * @param library the library for which an element model is to be built
- * @throws AnalysisException if the analysis could not be performed
- */
- void buildLibrary2(ResolvableLibrary library) {
- CompilationUnitBuilder builder = new CompilationUnitBuilder();
- Source librarySource = library.librarySource;
- CompilationUnit definingCompilationUnit = library.definingCompilationUnit;
- CompilationUnitElementImpl definingCompilationUnitElement = builder
- .buildCompilationUnit(
- librarySource, definingCompilationUnit, librarySource);
- NodeList<Directive> directives = definingCompilationUnit.directives;
- LibraryDirective libraryDirective = null;
- LibraryIdentifier libraryNameNode = null;
- bool hasPartDirective = false;
- FunctionElement entryPoint =
- _findEntryPoint(definingCompilationUnitElement);
- List<Directive> directivesToResolve = new List<Directive>();
- List<CompilationUnitElementImpl> sourcedCompilationUnits =
- new List<CompilationUnitElementImpl>();
- for (Directive directive in directives) {
- //
- // We do not build the elements representing the import and export
- // directives at this point. That is not done until we get to
- // LibraryResolver.buildDirectiveModels() because we need the
- // LibraryElements for the referenced libraries, which might not exist at
- // this point (due to the possibility of circular references).
- //
- if (directive is LibraryDirective) {
- if (libraryNameNode == null) {
- libraryDirective = directive;
- libraryNameNode = directive.name;
- directivesToResolve.add(directive);
- }
- } else if (directive is PartDirective) {
- PartDirective partDirective = directive;
- StringLiteral partUri = partDirective.uri;
- Source partSource = partDirective.source;
- if (_analysisContext.exists(partSource)) {
- hasPartDirective = true;
- CompilationUnit partUnit = library.getAST(partSource);
- if (partUnit != null) {
- CompilationUnitElementImpl part = builder.buildCompilationUnit(
- partSource, partUnit, librarySource);
- part.uriOffset = partUri.offset;
- part.uriEnd = partUri.end;
- part.uri = partDirective.uriContent;
- //
- // Validate that the part contains a part-of directive with the same
- // name as the library.
- //
- String partLibraryName =
- _getPartLibraryName(partSource, partUnit, directivesToResolve);
- if (partLibraryName == null) {
- _errorListener.onError(new AnalysisError(
- librarySource,
- partUri.offset,
- partUri.length,
- CompileTimeErrorCode.PART_OF_NON_PART,
- [partUri.toSource()]));
- } else if (libraryNameNode == null) {
- // TODO(brianwilkerson) Collect the names declared by the part.
- // If they are all the same then we can use that name as the
- // inferred name of the library and present it in a quick-fix.
- // partLibraryNames.add(partLibraryName);
- } else if (libraryNameNode.name != partLibraryName) {
- _errorListener.onError(new AnalysisError(
- librarySource,
- partUri.offset,
- partUri.length,
- StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
- [libraryNameNode.name, partLibraryName]));
- }
- if (entryPoint == null) {
- entryPoint = _findEntryPoint(part);
- }
- directive.element = part;
- sourcedCompilationUnits.add(part);
- }
- }
- }
- }
- if (hasPartDirective && libraryNameNode == null) {
- _errorListener.onError(new AnalysisError(librarySource, 0, 0,
- ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART));
- }
- //
- // Create and populate the library element.
- //
- LibraryElementImpl libraryElement = new LibraryElementImpl.forNode(
- _analysisContext.getContextFor(librarySource), libraryNameNode);
- _setDocRange(libraryElement, libraryDirective);
- libraryElement.definingCompilationUnit = definingCompilationUnitElement;
- if (entryPoint != null) {
- libraryElement.entryPoint = entryPoint;
- }
- int sourcedUnitCount = sourcedCompilationUnits.length;
- libraryElement.parts = sourcedCompilationUnits;
- for (Directive directive in directivesToResolve) {
- directive.element = libraryElement;
- }
- library.libraryElement = libraryElement;
- if (sourcedUnitCount > 0) {
- _patchTopLevelAccessors(libraryElement);
- }
- }
-
- /**
- * Add all of the non-synthetic getters and setters defined in the given compilation unit that
- * have no corresponding accessor to one of the given collections.
- *
- * @param getters the map to which getters are to be added
- * @param setters the list to which setters are to be added
- * @param unit the compilation unit defining the accessors that are potentially being added
- */
- void _collectAccessors(HashMap<String, PropertyAccessorElement> getters,
- List<PropertyAccessorElement> setters, CompilationUnitElement unit) {
- for (PropertyAccessorElement accessor in unit.accessors) {
- if (accessor.isGetter) {
- if (!accessor.isSynthetic && accessor.correspondingSetter == null) {
- getters[accessor.displayName] = accessor;
- }
- } else {
- if (!accessor.isSynthetic && accessor.correspondingGetter == null) {
- setters.add(accessor);
- }
- }
- }
- }
-
- /**
- * Search the top-level functions defined in the given compilation unit for the entry point.
- *
- * @param element the compilation unit to be searched
- * @return the entry point that was found, or `null` if the compilation unit does not define
- * an entry point
- */
- FunctionElement _findEntryPoint(CompilationUnitElementImpl element) {
- for (FunctionElement function in element.functions) {
- if (function.isEntryPoint) {
- return function;
- }
- }
- return null;
- }
-
- /**
- * Return the name of the library that the given part is declared to be a part of, or `null`
- * if the part does not contain a part-of directive.
- *
- * @param partSource the source representing the part
- * @param partUnit the AST structure of the part
- * @param directivesToResolve a list of directives that should be resolved to the library being
- * built
- * @return the name of the library that the given part is declared to be a part of
- */
- String _getPartLibraryName(Source partSource, CompilationUnit partUnit,
- List<Directive> directivesToResolve) {
- for (Directive directive in partUnit.directives) {
- if (directive is PartOfDirective) {
- directivesToResolve.add(directive);
- LibraryIdentifier libraryName = directive.libraryName;
- if (libraryName != null) {
- return libraryName.name;
- }
- }
- }
- return null;
- }
-
- /**
- * Look through all of the compilation units defined for the given library, looking for getters
- * and setters that are defined in different compilation units but that have the same names. If
- * any are found, make sure that they have the same variable element.
- *
- * @param libraryElement the library defining the compilation units to be processed
- */
- void _patchTopLevelAccessors(LibraryElementImpl libraryElement) {
- HashMap<String, PropertyAccessorElement> getters =
- new HashMap<String, PropertyAccessorElement>();
- List<PropertyAccessorElement> setters = new List<PropertyAccessorElement>();
- _collectAccessors(getters, setters, libraryElement.definingCompilationUnit);
- for (CompilationUnitElement unit in libraryElement.parts) {
- _collectAccessors(getters, setters, unit);
- }
- for (PropertyAccessorElement setter in setters) {
- PropertyAccessorElement getter = getters[setter.displayName];
- if (getter != null) {
- PropertyInducingElementImpl variable =
- getter.variable as PropertyInducingElementImpl;
- variable.setter = setter;
- (setter as PropertyAccessorElementImpl).variable = variable;
- }
- }
- }
-
- /**
- * If the given [node] has a documentation comment, remember its range
- * into the given [element].
- */
- void _setDocRange(ElementImpl element, LibraryDirective node) {
- if (node != null) {
- Comment comment = node.documentationComment;
- if (comment != null && comment.isDocumentation) {
- element.setDocRange(comment.offset, comment.length);
- }
- }
- }
-}
-
-/**
* Instances of the class `LibraryImportScope` represent the scope containing all of the names
* available from imported libraries.
*/
@@ -7951,1374 +6893,11 @@
* Instances of the class `LibraryResolver` are used to resolve one or more mutually dependent
* libraries within a single context.
*/
-class LibraryResolver {
- /**
- * The analysis context in which the libraries are being analyzed.
- */
- final InternalAnalysisContext analysisContext;
-
- /**
- * The listener to which analysis errors will be reported, this error listener is either
- * references [recordingErrorListener], or it unions the passed
- * [AnalysisErrorListener] with the [recordingErrorListener].
- */
- RecordingErrorListener _errorListener;
-
- /**
- * A source object representing the core library (dart:core).
- */
- Source _coreLibrarySource;
-
- /**
- * A Source object representing the async library (dart:async).
- */
- Source _asyncLibrarySource;
-
- /**
- * The object representing the core library.
- */
- Library _coreLibrary;
-
- /**
- * The object representing the async library.
- */
- Library _asyncLibrary;
-
- /**
- * The object used to access the types from the core library.
- */
- TypeProvider _typeProvider;
-
- /**
- * The type system in use for the library
- */
- TypeSystem _typeSystem;
-
- /**
- * A table mapping library sources to the information being maintained for those libraries.
- */
- HashMap<Source, Library> _libraryMap = new HashMap<Source, Library>();
-
- /**
- * A collection containing the libraries that are being resolved together.
- */
- Set<Library> _librariesInCycles;
-
- /**
- * Initialize a newly created library resolver to resolve libraries within the given context.
- *
- * @param analysisContext the analysis context in which the library is being analyzed
- */
- LibraryResolver(this.analysisContext) {
- this._errorListener = new RecordingErrorListener();
- _coreLibrarySource =
- analysisContext.sourceFactory.forUri(DartSdk.DART_CORE);
- _asyncLibrarySource =
- analysisContext.sourceFactory.forUri(DartSdk.DART_ASYNC);
- }
-
- /**
- * Return the listener to which analysis errors will be reported.
- *
- * @return the listener to which analysis errors will be reported
- */
- RecordingErrorListener get errorListener => _errorListener;
-
- /**
- * Return an array containing information about all of the libraries that were resolved.
- *
- * @return an array containing the libraries that were resolved
- */
- Set<Library> get resolvedLibraries => _librariesInCycles;
-
- /**
- * The object used to access the types from the core library.
- */
- TypeProvider get typeProvider => _typeProvider;
-
- /**
- * The type system in use.
- */
- TypeSystem get typeSystem => _typeSystem;
-
- /**
- * Create an object to represent the information about the library defined by the compilation unit
- * with the given source.
- *
- * @param librarySource the source of the library's defining compilation unit
- * @return the library object that was created
- * @throws AnalysisException if the library source is not valid
- */
- Library createLibrary(Source librarySource) {
- Library library =
- new Library(analysisContext, _errorListener, librarySource);
- _libraryMap[librarySource] = library;
- return library;
- }
-
- /**
- * Resolve the library specified by the given source in the given context. The library is assumed
- * to be embedded in the given source.
- *
- * @param librarySource the source specifying the defining compilation unit of the library to be
- * resolved
- * @param unit the compilation unit representing the embedded library
- * @param fullAnalysis `true` if a full analysis should be performed
- * @return the element representing the resolved library
- * @throws AnalysisException if the library could not be resolved for some reason
- */
- LibraryElement resolveEmbeddedLibrary(
- Source librarySource, CompilationUnit unit, bool fullAnalysis) {
- //
- // Create the objects representing the library being resolved and the core
- // library.
- //
- Library targetLibrary = _createLibraryWithUnit(librarySource, unit);
- _coreLibrary = _libraryMap[_coreLibrarySource];
- if (_coreLibrary == null) {
- // This will only happen if the library being analyzed is the core
- // library.
- _coreLibrary = createLibrary(_coreLibrarySource);
- if (_coreLibrary == null) {
- LibraryResolver2.missingCoreLibrary(
- analysisContext, _coreLibrarySource);
- }
- }
- _asyncLibrary = _libraryMap[_asyncLibrarySource];
- if (_asyncLibrary == null) {
- // This will only happen if the library being analyzed is the async
- // library.
- _asyncLibrary = createLibrary(_asyncLibrarySource);
- if (_asyncLibrary == null) {
- LibraryResolver2.missingAsyncLibrary(
- analysisContext, _asyncLibrarySource);
- }
- }
- //
- // Compute the set of libraries that need to be resolved together.
- //
- _computeEmbeddedLibraryDependencies(targetLibrary, unit);
- _librariesInCycles = _computeLibrariesInCycles(targetLibrary);
- //
- // Build the element models representing the libraries being resolved.
- // This is done in three steps:
- //
- // 1. Build the basic element models without making any connections
- // between elements other than the basic parent/child relationships.
- // This includes building the elements representing the libraries.
- // 2. Build the elements for the import and export directives. This
- // requires that we have the elements built for the referenced
- // libraries, but because of the possibility of circular references
- // needs to happen after all of the library elements have been created.
- // 3. Build the rest of the type model by connecting superclasses, mixins,
- // and interfaces. This requires that we be able to compute the names
- // visible in the libraries being resolved, which in turn requires that
- // we have resolved the import directives.
- //
- _buildElementModels();
- LibraryElement coreElement = _coreLibrary.libraryElement;
- if (coreElement == null) {
- throw new AnalysisException("Could not resolve dart:core");
- }
- LibraryElement asyncElement = _asyncLibrary.libraryElement;
- if (asyncElement == null) {
- throw new AnalysisException("Could not resolve dart:async");
- }
- _buildDirectiveModels();
- _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
- _typeSystem = TypeSystem.create(analysisContext);
- _buildTypeHierarchies();
- //
- // Perform resolution and type analysis.
- //
- // TODO(brianwilkerson) Decide whether we want to resolve all of the
- // libraries or whether we want to only resolve the target library.
- // The advantage to resolving everything is that we have already done part
- // of the work so we'll avoid duplicated effort. The disadvantage of
- // resolving everything is that we might do extra work that we don't
- // really care about. Another possibility is to add a parameter to this
- // method and punt the decision to the clients.
- //
- //if (analyzeAll) {
- resolveReferencesAndTypes();
- //} else {
- // resolveReferencesAndTypes(targetLibrary);
- //}
- _performConstantEvaluation();
- return targetLibrary.libraryElement;
- }
-
- /**
- * Resolve the library specified by the given source in the given context.
- *
- * Note that because Dart allows circular imports between libraries, it is possible that more than
- * one library will need to be resolved. In such cases the error listener can receive errors from
- * multiple libraries.
- *
- * @param librarySource the source specifying the defining compilation unit of the library to be
- * resolved
- * @param fullAnalysis `true` if a full analysis should be performed
- * @return the element representing the resolved library
- * @throws AnalysisException if the library could not be resolved for some reason
- */
- LibraryElement resolveLibrary(Source librarySource, bool fullAnalysis) {
- //
- // Create the object representing the library being resolved and compute
- // the dependency relationship. Note that all libraries depend implicitly
- // on core, and we inject an ersatz dependency on async, so once this is
- // done the core and async library elements will have been created.
- //
- Library targetLibrary = createLibrary(librarySource);
- _computeLibraryDependencies(targetLibrary);
- _coreLibrary = _libraryMap[_coreLibrarySource];
- _asyncLibrary = _libraryMap[_asyncLibrarySource];
- //
- // Compute the set of libraries that need to be resolved together.
- //
- _librariesInCycles = _computeLibrariesInCycles(targetLibrary);
- //
- // Build the element models representing the libraries being resolved.
- // This is done in three steps:
- //
- // 1. Build the basic element models without making any connections
- // between elements other than the basic parent/child relationships.
- // This includes building the elements representing the libraries, but
- // excludes members defined in enums.
- // 2. Build the elements for the import and export directives. This
- // requires that we have the elements built for the referenced
- // libraries, but because of the possibility of circular references
- // needs to happen after all of the library elements have been created.
- // 3. Build the members in enum declarations.
- // 4. Build the rest of the type model by connecting superclasses, mixins,
- // and interfaces. This requires that we be able to compute the names
- // visible in the libraries being resolved, which in turn requires that
- // we have resolved the import directives.
- //
- _buildElementModels();
- LibraryElement coreElement = _coreLibrary.libraryElement;
- if (coreElement == null) {
- throw new AnalysisException("Could not resolve dart:core");
- }
- LibraryElement asyncElement = _asyncLibrary.libraryElement;
- if (asyncElement == null) {
- throw new AnalysisException("Could not resolve dart:async");
- }
- _buildDirectiveModels();
- _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
- _typeSystem = TypeSystem.create(analysisContext);
- _buildEnumMembers();
- _buildTypeHierarchies();
- //
- // Perform resolution and type analysis.
- //
- // TODO(brianwilkerson) Decide whether we want to resolve all of the
- // libraries or whether we want to only resolve the target library. The
- // advantage to resolving everything is that we have already done part of
- // the work so we'll avoid duplicated effort. The disadvantage of
- // resolving everything is that we might do extra work that we don't
- // really care about. Another possibility is to add a parameter to this
- // method and punt the decision to the clients.
- //
- //if (analyzeAll) {
- resolveReferencesAndTypes();
- //} else {
- // resolveReferencesAndTypes(targetLibrary);
- //}
- _performConstantEvaluation();
- return targetLibrary.libraryElement;
- }
-
- /**
- * Resolve the identifiers and perform type analysis in the libraries in the current cycle.
- *
- * @throws AnalysisException if any of the identifiers could not be resolved or if any of the
- * libraries could not have their types analyzed
- */
- void resolveReferencesAndTypes() {
- for (Library library in _librariesInCycles) {
- _resolveReferencesAndTypesInLibrary(library);
- }
- }
-
- /**
- * Add a dependency to the given map from the referencing library to the referenced library.
- *
- * @param dependencyMap the map to which the dependency is to be added
- * @param referencingLibrary the library that references the referenced library
- * @param referencedLibrary the library referenced by the referencing library
- */
- void _addDependencyToMap(HashMap<Library, List<Library>> dependencyMap,
- Library referencingLibrary, Library referencedLibrary) {
- List<Library> dependentLibraries = dependencyMap[referencedLibrary];
- if (dependentLibraries == null) {
- dependentLibraries = new List<Library>();
- dependencyMap[referencedLibrary] = dependentLibraries;
- }
- dependentLibraries.add(referencingLibrary);
- }
-
- /**
- * Given a library that is part of a cycle that includes the root library, add to the given set of
- * libraries all of the libraries reachable from the root library that are also included in the
- * cycle.
- *
- * @param library the library to be added to the collection of libraries in cycles
- * @param librariesInCycle a collection of the libraries that are in the cycle
- * @param dependencyMap a table mapping libraries to the collection of libraries from which those
- * libraries are referenced
- */
- void _addLibrariesInCycle(Library library, Set<Library> librariesInCycle,
- HashMap<Library, List<Library>> dependencyMap) {
- if (librariesInCycle.add(library)) {
- List<Library> dependentLibraries = dependencyMap[library];
- if (dependentLibraries != null) {
- for (Library dependentLibrary in dependentLibraries) {
- _addLibrariesInCycle(
- dependentLibrary, librariesInCycle, dependencyMap);
- }
- }
- }
- }
-
- /**
- * Add the given library, and all libraries reachable from it that have not already been visited,
- * to the given dependency map.
- *
- * @param library the library currently being added to the dependency map
- * @param dependencyMap the dependency map being computed
- * @param visitedLibraries the libraries that have already been visited, used to prevent infinite
- * recursion
- */
- void _addToDependencyMap(
- Library library,
- HashMap<Library, List<Library>> dependencyMap,
- Set<Library> visitedLibraries) {
- if (visitedLibraries.add(library)) {
- bool asyncFound = false;
- for (Library referencedLibrary in library.importsAndExports) {
- _addDependencyToMap(dependencyMap, library, referencedLibrary);
- _addToDependencyMap(referencedLibrary, dependencyMap, visitedLibraries);
- if (identical(referencedLibrary, _asyncLibrary)) {
- asyncFound = true;
- }
- }
- if (!library.explicitlyImportsCore && !identical(library, _coreLibrary)) {
- _addDependencyToMap(dependencyMap, library, _coreLibrary);
- }
- if (!asyncFound && !identical(library, _asyncLibrary)) {
- _addDependencyToMap(dependencyMap, library, _asyncLibrary);
- _addToDependencyMap(_asyncLibrary, dependencyMap, visitedLibraries);
- }
- }
- }
-
- /**
- * Build the element model representing the combinators declared by the given directive.
- *
- * @param directive the directive that declares the combinators
- * @return an array containing the import combinators that were built
- */
- List<NamespaceCombinator> _buildCombinators(NamespaceDirective directive) {
- List<NamespaceCombinator> combinators = new List<NamespaceCombinator>();
- for (Combinator combinator in directive.combinators) {
- if (combinator is HideCombinator) {
- HideElementCombinatorImpl hide = new HideElementCombinatorImpl();
- hide.hiddenNames = _getIdentifiers(combinator.hiddenNames);
- combinators.add(hide);
- } else {
- ShowElementCombinatorImpl show = new ShowElementCombinatorImpl();
- show.offset = combinator.offset;
- show.end = combinator.end;
- show.shownNames =
- _getIdentifiers((combinator as ShowCombinator).shownNames);
- combinators.add(show);
- }
- }
- return combinators;
- }
-
- /**
- * Every library now has a corresponding [LibraryElement], so it is now possible to resolve
- * the import and export directives.
- *
- * @throws AnalysisException if the defining compilation unit for any of the libraries could not
- * be accessed
- */
- void _buildDirectiveModels() {
- for (Library library in _librariesInCycles) {
- HashMap<String, PrefixElementImpl> nameToPrefixMap =
- new HashMap<String, PrefixElementImpl>();
- List<ImportElement> imports = new List<ImportElement>();
- List<ExportElement> exports = new List<ExportElement>();
- for (Directive directive in library.definingCompilationUnit.directives) {
- if (directive is ImportDirective) {
- ImportDirective importDirective = directive;
- String uriContent = importDirective.uriContent;
- if (DartUriResolver.isDartExtUri(uriContent)) {
- library.libraryElement.hasExtUri = true;
- }
- Source importedSource = importDirective.source;
- if (importedSource != null) {
- // The imported source will be null if the URI in the import
- // directive was invalid.
- Library importedLibrary = _libraryMap[importedSource];
- if (importedLibrary != null) {
- ImportElementImpl importElement =
- new ImportElementImpl(directive.offset);
- StringLiteral uriLiteral = importDirective.uri;
- importElement.uriOffset = uriLiteral.offset;
- importElement.uriEnd = uriLiteral.end;
- importElement.uri = uriContent;
- importElement.deferred = importDirective.deferredKeyword != null;
- importElement.combinators = _buildCombinators(importDirective);
- LibraryElement importedLibraryElement =
- importedLibrary.libraryElement;
- if (importedLibraryElement != null) {
- importElement.importedLibrary = importedLibraryElement;
- }
- SimpleIdentifier prefixNode = directive.prefix;
- if (prefixNode != null) {
- importElement.prefixOffset = prefixNode.offset;
- String prefixName = prefixNode.name;
- PrefixElementImpl prefix = nameToPrefixMap[prefixName];
- if (prefix == null) {
- prefix = new PrefixElementImpl.forNode(prefixNode);
- nameToPrefixMap[prefixName] = prefix;
- }
- importElement.prefix = prefix;
- prefixNode.staticElement = prefix;
- }
- directive.element = importElement;
- imports.add(importElement);
- if (analysisContext.computeKindOf(importedSource) !=
- SourceKind.LIBRARY) {
- ErrorCode errorCode = (importElement.isDeferred
- ? StaticWarningCode.IMPORT_OF_NON_LIBRARY
- : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY);
- _errorListener.onError(new AnalysisError(
- library.librarySource,
- uriLiteral.offset,
- uriLiteral.length,
- errorCode,
- [uriLiteral.toSource()]));
- }
- }
- }
- } else if (directive is ExportDirective) {
- ExportDirective exportDirective = directive;
- Source exportedSource = exportDirective.source;
- if (exportedSource != null) {
- // The exported source will be null if the URI in the export
- // directive was invalid.
- Library exportedLibrary = _libraryMap[exportedSource];
- if (exportedLibrary != null) {
- ExportElementImpl exportElement =
- new ExportElementImpl(directive.offset);
- StringLiteral uriLiteral = exportDirective.uri;
- exportElement.uriOffset = uriLiteral.offset;
- exportElement.uriEnd = uriLiteral.end;
- exportElement.uri = exportDirective.uriContent;
- exportElement.combinators = _buildCombinators(exportDirective);
- LibraryElement exportedLibraryElement =
- exportedLibrary.libraryElement;
- if (exportedLibraryElement != null) {
- exportElement.exportedLibrary = exportedLibraryElement;
- }
- directive.element = exportElement;
- exports.add(exportElement);
- if (analysisContext.computeKindOf(exportedSource) !=
- SourceKind.LIBRARY) {
- _errorListener.onError(new AnalysisError(
- library.librarySource,
- uriLiteral.offset,
- uriLiteral.length,
- CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
- [uriLiteral.toSource()]));
- }
- }
- }
- }
- }
- Source librarySource = library.librarySource;
- if (!library.explicitlyImportsCore &&
- _coreLibrarySource != librarySource) {
- ImportElementImpl importElement = new ImportElementImpl(-1);
- importElement.importedLibrary = _coreLibrary.libraryElement;
- importElement.synthetic = true;
- imports.add(importElement);
- }
- LibraryElementImpl libraryElement = library.libraryElement;
- libraryElement.imports = imports;
- libraryElement.exports = exports;
- if (libraryElement.entryPoint == null) {
- Namespace namespace = new NamespaceBuilder()
- .createExportNamespaceForLibrary(libraryElement);
- Element element = namespace.get(FunctionElement.MAIN_FUNCTION_NAME);
- if (element is FunctionElement) {
- libraryElement.entryPoint = element;
- }
- }
- }
- }
-
- /**
- * Build element models for all of the libraries in the current cycle.
- *
- * @throws AnalysisException if any of the element models cannot be built
- */
- void _buildElementModels() {
- for (Library library in _librariesInCycles) {
- LibraryElementBuilder builder =
- new LibraryElementBuilder(analysisContext, errorListener);
- LibraryElementImpl libraryElement = builder.buildLibrary(library);
- library.libraryElement = libraryElement;
- }
- }
-
- /**
- * Build the members in enum declarations. This cannot be done while building the rest of the
- * element model because it depends on being able to access core types, which cannot happen until
- * the rest of the element model has been built (when resolving the core library).
- *
- * @throws AnalysisException if any of the enum members could not be built
- */
- void _buildEnumMembers() {
- PerformanceStatistics.resolve.makeCurrentWhile(() {
- for (Library library in _librariesInCycles) {
- for (Source source in library.compilationUnitSources) {
- EnumMemberBuilder builder = new EnumMemberBuilder(_typeProvider);
- library.getAST(source).accept(builder);
- }
- }
- });
- }
-
- /**
- * Resolve the type hierarchy across all of the types declared in the libraries in the current
- * cycle.
- *
- * @throws AnalysisException if any of the type hierarchies could not be resolved
- */
- void _buildTypeHierarchies() {
- PerformanceStatistics.resolve.makeCurrentWhile(() {
- for (Library library in _librariesInCycles) {
- for (Source source in library.compilationUnitSources) {
- TypeResolverVisitorFactory typeResolverVisitorFactory =
- analysisContext.typeResolverVisitorFactory;
- TypeResolverVisitor visitor = (typeResolverVisitorFactory == null)
- ? new TypeResolverVisitor(library.libraryElement, source,
- _typeProvider, library.errorListener,
- nameScope: library.libraryScope)
- : typeResolverVisitorFactory(library, source, _typeProvider);
- library.getAST(source).accept(visitor);
- }
- library.libraryElement.createLoadLibraryFunction(_typeProvider);
- }
- });
- }
-
- /**
- * Compute a dependency map of libraries reachable from the given library. A dependency map is a
- * table that maps individual libraries to a list of the libraries that either import or export
- * those libraries.
- *
- * This map is used to compute all of the libraries involved in a cycle that include the root
- * library. Given that we only add libraries that are reachable from the root library, when we
- * work backward we are guaranteed to only get libraries in the cycle.
- *
- * @param library the library currently being added to the dependency map
- */
- HashMap<Library, List<Library>> _computeDependencyMap(Library library) {
- HashMap<Library, List<Library>> dependencyMap =
- new HashMap<Library, List<Library>>();
- _addToDependencyMap(library, dependencyMap, new HashSet<Library>());
- return dependencyMap;
- }
-
- /**
- * Recursively traverse the libraries reachable from the given library, creating instances of the
- * class [Library] to represent them, and record the references in the library objects.
- *
- * @param library the library to be processed to find libraries that have not yet been traversed
- * @throws AnalysisException if some portion of the library graph could not be traversed
- */
- void _computeEmbeddedLibraryDependencies(
- Library library, CompilationUnit unit) {
- Source librarySource = library.librarySource;
- HashSet<Source> exportedSources = new HashSet<Source>();
- HashSet<Source> importedSources = new HashSet<Source>();
- for (Directive directive in unit.directives) {
- if (directive is ExportDirective) {
- Source exportSource = _resolveSource(librarySource, directive);
- if (exportSource != null) {
- exportedSources.add(exportSource);
- }
- } else if (directive is ImportDirective) {
- Source importSource = _resolveSource(librarySource, directive);
- if (importSource != null) {
- importedSources.add(importSource);
- }
- }
- }
- _computeLibraryDependenciesFromDirectives(library,
- new List.from(importedSources), new List.from(exportedSources));
- }
-
- /**
- * Return a collection containing all of the libraries reachable from the given library that are
- * contained in a cycle that includes the given library.
- *
- * @param library the library that must be included in any cycles whose members are to be returned
- * @return all of the libraries referenced by the given library that have a circular reference
- * back to the given library
- */
- Set<Library> _computeLibrariesInCycles(Library library) {
- HashMap<Library, List<Library>> dependencyMap =
- _computeDependencyMap(library);
- Set<Library> librariesInCycle = new HashSet<Library>();
- _addLibrariesInCycle(library, librariesInCycle, dependencyMap);
- return librariesInCycle;
- }
-
- /**
- * Recursively traverse the libraries reachable from the given library, creating instances of the
- * class [Library] to represent them, and record the references in the library objects.
- *
- * @param library the library to be processed to find libraries that have not yet been traversed
- * @throws AnalysisException if some portion of the library graph could not be traversed
- */
- void _computeLibraryDependencies(Library library) {
- Source librarySource = library.librarySource;
- _computeLibraryDependenciesFromDirectives(
- library,
- analysisContext.computeImportedLibraries(librarySource),
- analysisContext.computeExportedLibraries(librarySource));
- }
-
- /**
- * Recursively traverse the libraries reachable from the given library, creating instances of the
- * class [Library] to represent them, and record the references in the library objects.
- *
- * @param library the library to be processed to find libraries that have not yet been traversed
- * @param importedSources an array containing the sources that are imported into the given library
- * @param exportedSources an array containing the sources that are exported from the given library
- * @throws AnalysisException if some portion of the library graph could not be traversed
- */
- void _computeLibraryDependenciesFromDirectives(Library library,
- List<Source> importedSources, List<Source> exportedSources) {
- List<Library> importedLibraries = new List<Library>();
- bool explicitlyImportsCore = false;
- bool importsAsync = false;
- for (Source importedSource in importedSources) {
- if (importedSource == _coreLibrarySource) {
- explicitlyImportsCore = true;
- }
- if (importedSource == _asyncLibrarySource) {
- importsAsync = true;
- }
- Library importedLibrary = _libraryMap[importedSource];
- if (importedLibrary == null) {
- importedLibrary = _createLibraryOrNull(importedSource);
- if (importedLibrary != null) {
- _computeLibraryDependencies(importedLibrary);
- }
- }
- if (importedLibrary != null) {
- importedLibraries.add(importedLibrary);
- }
- }
- library.importedLibraries = importedLibraries;
- List<Library> exportedLibraries = new List<Library>();
- for (Source exportedSource in exportedSources) {
- Library exportedLibrary = _libraryMap[exportedSource];
- if (exportedLibrary == null) {
- exportedLibrary = _createLibraryOrNull(exportedSource);
- if (exportedLibrary != null) {
- _computeLibraryDependencies(exportedLibrary);
- }
- }
- if (exportedLibrary != null) {
- exportedLibraries.add(exportedLibrary);
- }
- }
- library.exportedLibraries = exportedLibraries;
- library.explicitlyImportsCore = explicitlyImportsCore;
- if (!explicitlyImportsCore && _coreLibrarySource != library.librarySource) {
- Library importedLibrary = _libraryMap[_coreLibrarySource];
- if (importedLibrary == null) {
- importedLibrary = _createLibraryOrNull(_coreLibrarySource);
- if (importedLibrary != null) {
- _computeLibraryDependencies(importedLibrary);
- }
- }
- }
- if (!importsAsync && _asyncLibrarySource != library.librarySource) {
- Library importedLibrary = _libraryMap[_asyncLibrarySource];
- if (importedLibrary == null) {
- importedLibrary = _createLibraryOrNull(_asyncLibrarySource);
- if (importedLibrary != null) {
- _computeLibraryDependencies(importedLibrary);
- }
- }
- }
- }
-
- /**
- * Create an object to represent the information about the library defined by the compilation unit
- * with the given source. Return the library object that was created, or `null` if the
- * source is not valid.
- *
- * @param librarySource the source of the library's defining compilation unit
- * @return the library object that was created
- */
- Library _createLibraryOrNull(Source librarySource) {
- if (!analysisContext.exists(librarySource)) {
- return null;
- }
- Library library =
- new Library(analysisContext, _errorListener, librarySource);
- _libraryMap[librarySource] = library;
- return library;
- }
-
- /**
- * Create an object to represent the information about the library defined by the compilation unit
- * with the given source.
- *
- * @param librarySource the source of the library's defining compilation unit
- * @param unit the compilation unit that defines the library
- * @return the library object that was created
- * @throws AnalysisException if the library source is not valid
- */
- Library _createLibraryWithUnit(Source librarySource, CompilationUnit unit) {
- Library library =
- new Library(analysisContext, _errorListener, librarySource);
- library.setDefiningCompilationUnit(unit);
- _libraryMap[librarySource] = library;
- return library;
- }
-
- /**
- * Return an array containing the lexical identifiers associated with the nodes in the given list.
- *
- * @param names the AST nodes representing the identifiers
- * @return the lexical identifiers associated with the nodes in the list
- */
- List<String> _getIdentifiers(NodeList<SimpleIdentifier> names) {
- int count = names.length;
- List<String> identifiers = new List<String>(count);
- for (int i = 0; i < count; i++) {
- identifiers[i] = names[i].name;
- }
- return identifiers;
- }
-
- /**
- * Compute a value for all of the constants in the libraries being analyzed.
- */
- void _performConstantEvaluation() {
- PerformanceStatistics.resolve.makeCurrentWhile(() {
- ConstantValueComputer computer = new ConstantValueComputer(
- analysisContext,
- _typeProvider,
- analysisContext.declaredVariables,
- null,
- _typeSystem);
- for (Library library in _librariesInCycles) {
- for (Source source in library.compilationUnitSources) {
- try {
- CompilationUnit unit = library.getAST(source);
- if (unit != null) {
- computer.add(unit, source, library.librarySource);
- }
- } on AnalysisException catch (exception, stackTrace) {
- AnalysisEngine.instance.logger.logError(
- "Internal Error: Could not access AST for ${source.fullName} during constant evaluation",
- new CaughtException(exception, stackTrace));
- }
- }
- }
- computer.computeValues();
- // As a temporary workaround for issue 21572, run ConstantVerifier now.
- // TODO(paulberry): remove this workaround once issue 21572 is fixed.
- for (Library library in _librariesInCycles) {
- for (Source source in library.compilationUnitSources) {
- try {
- CompilationUnit unit = library.getAST(source);
- ErrorReporter errorReporter =
- new ErrorReporter(_errorListener, source);
- ConstantVerifier constantVerifier = new ConstantVerifier(
- errorReporter,
- library.libraryElement,
- _typeProvider,
- analysisContext.declaredVariables);
- unit.accept(constantVerifier);
- } on AnalysisException catch (exception, stackTrace) {
- AnalysisEngine.instance.logger.logError(
- "Internal Error: Could not access AST for ${source.fullName} "
- "during constant verification",
- new CaughtException(exception, stackTrace));
- }
- }
- }
- });
- }
-
- /**
- * Resolve the identifiers and perform type analysis in the given library.
- *
- * @param library the library to be resolved
- * @throws AnalysisException if any of the identifiers could not be resolved or if the types in
- * the library cannot be analyzed
- */
- void _resolveReferencesAndTypesInLibrary(Library library) {
- PerformanceStatistics.resolve.makeCurrentWhile(() {
- for (Source source in library.compilationUnitSources) {
- CompilationUnit ast = library.getAST(source);
- ast.accept(new VariableResolverVisitor(library.libraryElement, source,
- _typeProvider, library.errorListener,
- nameScope: library.libraryScope));
- ResolverVisitorFactory visitorFactory =
- analysisContext.resolverVisitorFactory;
- ResolverVisitor visitor = visitorFactory != null
- ? visitorFactory(library, source, _typeProvider)
- : new ResolverVisitor(library.libraryElement, source, _typeProvider,
- library.errorListener,
- nameScope: library.libraryScope,
- inheritanceManager: library.inheritanceManager);
- ast.accept(visitor);
- }
- });
- }
-
- /**
- * Return the result of resolving the URI of the given URI-based directive against the URI of the
- * given library, or `null` if the URI is not valid.
- *
- * @param librarySource the source representing the library containing the directive
- * @param directive the directive which URI should be resolved
- * @return the result of resolving the URI against the URI of the library
- */
- Source _resolveSource(Source librarySource, UriBasedDirective directive) {
- StringLiteral uriLiteral = directive.uri;
- if (uriLiteral is StringInterpolation) {
- return null;
- }
- String uriContent = uriLiteral.stringValue.trim();
- if (uriContent == null || uriContent.isEmpty) {
- return null;
- }
- uriContent = Uri.encodeFull(uriContent);
- return analysisContext.sourceFactory.resolveUri(librarySource, uriContent);
- }
-}
/**
* Instances of the class `LibraryResolver` are used to resolve one or more mutually dependent
* libraries within a single context.
*/
-class LibraryResolver2 {
- /**
- * The analysis context in which the libraries are being analyzed.
- */
- final InternalAnalysisContext analysisContext;
-
- /**
- * The listener to which analysis errors will be reported, this error listener is either
- * references [recordingErrorListener], or it unions the passed
- * [AnalysisErrorListener] with the [recordingErrorListener].
- */
- RecordingErrorListener _errorListener;
-
- /**
- * A source object representing the core library (dart:core).
- */
- Source _coreLibrarySource;
-
- /**
- * A source object representing the async library (dart:async).
- */
- Source _asyncLibrarySource;
-
- /**
- * The object representing the core library.
- */
- ResolvableLibrary _coreLibrary;
-
- /**
- * The object representing the async library.
- */
- ResolvableLibrary _asyncLibrary;
-
- /**
- * The object used to access the types from the core library.
- */
- TypeProvider _typeProvider;
-
- /**
- * The type system in use for the library
- */
- TypeSystem _typeSystem;
-
- /**
- * A table mapping library sources to the information being maintained for those libraries.
- */
- HashMap<Source, ResolvableLibrary> _libraryMap =
- new HashMap<Source, ResolvableLibrary>();
-
- /**
- * A collection containing the libraries that are being resolved together.
- */
- List<ResolvableLibrary> _librariesInCycle;
-
- /**
- * Initialize a newly created library resolver to resolve libraries within the given context.
- *
- * @param analysisContext the analysis context in which the library is being analyzed
- */
- LibraryResolver2(this.analysisContext) {
- this._errorListener = new RecordingErrorListener();
- _coreLibrarySource =
- analysisContext.sourceFactory.forUri(DartSdk.DART_CORE);
- _asyncLibrarySource =
- analysisContext.sourceFactory.forUri(DartSdk.DART_ASYNC);
- }
-
- /**
- * Return the listener to which analysis errors will be reported.
- *
- * @return the listener to which analysis errors will be reported
- */
- RecordingErrorListener get errorListener => _errorListener;
-
- /**
- * Return an array containing information about all of the libraries that were resolved.
- *
- * @return an array containing the libraries that were resolved
- */
- List<ResolvableLibrary> get resolvedLibraries => _librariesInCycle;
-
- /**
- * Resolve the library specified by the given source in the given context.
- *
- * Note that because Dart allows circular imports between libraries, it is possible that more than
- * one library will need to be resolved. In such cases the error listener can receive errors from
- * multiple libraries.
- *
- * @param librarySource the source specifying the defining compilation unit of the library to be
- * resolved
- * @param fullAnalysis `true` if a full analysis should be performed
- * @return the element representing the resolved library
- * @throws AnalysisException if the library could not be resolved for some reason
- */
- LibraryElement resolveLibrary(
- Source librarySource, List<ResolvableLibrary> librariesInCycle) {
- //
- // Build the map of libraries that are known.
- //
- this._librariesInCycle = librariesInCycle;
- _libraryMap = _buildLibraryMap();
- ResolvableLibrary targetLibrary = _libraryMap[librarySource];
- _coreLibrary = _libraryMap[_coreLibrarySource];
- _asyncLibrary = _libraryMap[_asyncLibrarySource];
- //
- // Build the element models representing the libraries being resolved.
- // This is done in three steps:
- //
- // 1. Build the basic element models without making any connections
- // between elements other than the basic parent/child relationships.
- // This includes building the elements representing the libraries, but
- // excludes members defined in enums.
- // 2. Build the elements for the import and export directives. This
- // requires that we have the elements built for the referenced
- // libraries, but because of the possibility of circular references
- // needs to happen after all of the library elements have been created.
- // 3. Build the members in enum declarations.
- // 4. Build the rest of the type model by connecting superclasses, mixins,
- // and interfaces. This requires that we be able to compute the names
- // visible in the libraries being resolved, which in turn requires that
- // we have resolved the import directives.
- //
- _buildElementModels();
- LibraryElement coreElement = _coreLibrary.libraryElement;
- if (coreElement == null) {
- missingCoreLibrary(analysisContext, _coreLibrarySource);
- }
- LibraryElement asyncElement = _asyncLibrary.libraryElement;
- if (asyncElement == null) {
- missingAsyncLibrary(analysisContext, _asyncLibrarySource);
- }
- _buildDirectiveModels();
- _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
- _typeSystem = TypeSystem.create(analysisContext);
- _buildEnumMembers();
- _buildTypeHierarchies();
- //
- // Perform resolution and type analysis.
- //
- // TODO(brianwilkerson) Decide whether we want to resolve all of the
- // libraries or whether we want to only resolve the target library. The
- // advantage to resolving everything is that we have already done part of
- // the work so we'll avoid duplicated effort. The disadvantage of
- // resolving everything is that we might do extra work that we don't
- // really care about. Another possibility is to add a parameter to this
- // method and punt the decision to the clients.
- //
- //if (analyzeAll) {
- _resolveReferencesAndTypes();
- //} else {
- // resolveReferencesAndTypes(targetLibrary);
- //}
- _performConstantEvaluation();
- return targetLibrary.libraryElement;
- }
-
- /**
- * Build the element model representing the combinators declared by the given directive.
- *
- * @param directive the directive that declares the combinators
- * @return an array containing the import combinators that were built
- */
- List<NamespaceCombinator> _buildCombinators(NamespaceDirective directive) {
- List<NamespaceCombinator> combinators = new List<NamespaceCombinator>();
- for (Combinator combinator in directive.combinators) {
- if (combinator is HideCombinator) {
- HideElementCombinatorImpl hide = new HideElementCombinatorImpl();
- hide.hiddenNames = _getIdentifiers(combinator.hiddenNames);
- combinators.add(hide);
- } else {
- ShowElementCombinatorImpl show = new ShowElementCombinatorImpl();
- show.offset = combinator.offset;
- show.end = combinator.end;
- show.shownNames =
- _getIdentifiers((combinator as ShowCombinator).shownNames);
- combinators.add(show);
- }
- }
- return combinators;
- }
-
- /**
- * Every library now has a corresponding [LibraryElement], so it is now possible to resolve
- * the import and export directives.
- *
- * @throws AnalysisException if the defining compilation unit for any of the libraries could not
- * be accessed
- */
- void _buildDirectiveModels() {
- for (ResolvableLibrary library in _librariesInCycle) {
- HashMap<String, PrefixElementImpl> nameToPrefixMap =
- new HashMap<String, PrefixElementImpl>();
- List<ImportElement> imports = new List<ImportElement>();
- List<ExportElement> exports = new List<ExportElement>();
- for (Directive directive in library.definingCompilationUnit.directives) {
- if (directive is ImportDirective) {
- ImportDirective importDirective = directive;
- String uriContent = importDirective.uriContent;
- if (DartUriResolver.isDartExtUri(uriContent)) {
- library.libraryElement.hasExtUri = true;
- }
- Source importedSource = importDirective.source;
- if (importedSource != null &&
- analysisContext.exists(importedSource)) {
- // The imported source will be null if the URI in the import
- // directive was invalid.
- ResolvableLibrary importedLibrary = _libraryMap[importedSource];
- if (importedLibrary != null) {
- ImportElementImpl importElement =
- new ImportElementImpl(directive.offset);
- StringLiteral uriLiteral = importDirective.uri;
- if (uriLiteral != null) {
- importElement.uriOffset = uriLiteral.offset;
- importElement.uriEnd = uriLiteral.end;
- }
- importElement.uri = uriContent;
- importElement.deferred = importDirective.deferredKeyword != null;
- importElement.combinators = _buildCombinators(importDirective);
- LibraryElement importedLibraryElement =
- importedLibrary.libraryElement;
- if (importedLibraryElement != null) {
- importElement.importedLibrary = importedLibraryElement;
- }
- SimpleIdentifier prefixNode = directive.prefix;
- if (prefixNode != null) {
- importElement.prefixOffset = prefixNode.offset;
- String prefixName = prefixNode.name;
- PrefixElementImpl prefix = nameToPrefixMap[prefixName];
- if (prefix == null) {
- prefix = new PrefixElementImpl.forNode(prefixNode);
- nameToPrefixMap[prefixName] = prefix;
- }
- importElement.prefix = prefix;
- prefixNode.staticElement = prefix;
- }
- directive.element = importElement;
- imports.add(importElement);
- if (analysisContext.computeKindOf(importedSource) !=
- SourceKind.LIBRARY) {
- ErrorCode errorCode = (importElement.isDeferred
- ? StaticWarningCode.IMPORT_OF_NON_LIBRARY
- : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY);
- _errorListener.onError(new AnalysisError(
- library.librarySource,
- uriLiteral.offset,
- uriLiteral.length,
- errorCode,
- [uriLiteral.toSource()]));
- }
- }
- }
- } else if (directive is ExportDirective) {
- ExportDirective exportDirective = directive;
- Source exportedSource = exportDirective.source;
- if (exportedSource != null &&
- analysisContext.exists(exportedSource)) {
- // The exported source will be null if the URI in the export
- // directive was invalid.
- ResolvableLibrary exportedLibrary = _libraryMap[exportedSource];
- if (exportedLibrary != null) {
- ExportElementImpl exportElement =
- new ExportElementImpl(directive.offset);
- StringLiteral uriLiteral = exportDirective.uri;
- if (uriLiteral != null) {
- exportElement.uriOffset = uriLiteral.offset;
- exportElement.uriEnd = uriLiteral.end;
- }
- exportElement.uri = exportDirective.uriContent;
- exportElement.combinators = _buildCombinators(exportDirective);
- LibraryElement exportedLibraryElement =
- exportedLibrary.libraryElement;
- if (exportedLibraryElement != null) {
- exportElement.exportedLibrary = exportedLibraryElement;
- }
- directive.element = exportElement;
- exports.add(exportElement);
- if (analysisContext.computeKindOf(exportedSource) !=
- SourceKind.LIBRARY) {
- _errorListener.onError(new AnalysisError(
- library.librarySource,
- uriLiteral.offset,
- uriLiteral.length,
- CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
- [uriLiteral.toSource()]));
- }
- }
- }
- }
- }
- Source librarySource = library.librarySource;
- if (!library.explicitlyImportsCore &&
- _coreLibrarySource != librarySource) {
- ImportElementImpl importElement = new ImportElementImpl(-1);
- importElement.importedLibrary = _coreLibrary.libraryElement;
- importElement.synthetic = true;
- imports.add(importElement);
- }
- LibraryElementImpl libraryElement = library.libraryElement;
- libraryElement.imports = imports;
- libraryElement.exports = exports;
- if (libraryElement.entryPoint == null) {
- Namespace namespace = new NamespaceBuilder()
- .createExportNamespaceForLibrary(libraryElement);
- Element element = namespace.get(FunctionElement.MAIN_FUNCTION_NAME);
- if (element is FunctionElement) {
- libraryElement.entryPoint = element;
- }
- }
- }
- }
-
- /**
- * Build element models for all of the libraries in the current cycle.
- *
- * @throws AnalysisException if any of the element models cannot be built
- */
- void _buildElementModels() {
- for (ResolvableLibrary library in _librariesInCycle) {
- LibraryElementBuilder builder =
- new LibraryElementBuilder(analysisContext, errorListener);
- builder.buildLibrary2(library);
- }
- }
-
- /**
- * Build the members in enum declarations. This cannot be done while building the rest of the
- * element model because it depends on being able to access core types, which cannot happen until
- * the rest of the element model has been built (when resolving the core library).
- *
- * @throws AnalysisException if any of the enum members could not be built
- */
- void _buildEnumMembers() {
- PerformanceStatistics.resolve.makeCurrentWhile(() {
- for (ResolvableLibrary library in _librariesInCycle) {
- for (Source source in library.compilationUnitSources) {
- EnumMemberBuilder builder = new EnumMemberBuilder(_typeProvider);
- library.getAST(source).accept(builder);
- }
- }
- });
- }
-
- HashMap<Source, ResolvableLibrary> _buildLibraryMap() {
- HashMap<Source, ResolvableLibrary> libraryMap =
- new HashMap<Source, ResolvableLibrary>();
- int libraryCount = _librariesInCycle.length;
- for (int i = 0; i < libraryCount; i++) {
- ResolvableLibrary library = _librariesInCycle[i];
- library.errorListener = _errorListener;
- libraryMap[library.librarySource] = library;
- List<ResolvableLibrary> dependencies = library.importsAndExports;
- int dependencyCount = dependencies.length;
- for (int j = 0; j < dependencyCount; j++) {
- ResolvableLibrary dependency = dependencies[j];
- //dependency.setErrorListener(errorListener);
- libraryMap[dependency.librarySource] = dependency;
- }
- }
- return libraryMap;
- }
-
- /**
- * Resolve the type hierarchy across all of the types declared in the libraries in the current
- * cycle.
- *
- * @throws AnalysisException if any of the type hierarchies could not be resolved
- */
- void _buildTypeHierarchies() {
- PerformanceStatistics.resolve.makeCurrentWhile(() {
- for (ResolvableLibrary library in _librariesInCycle) {
- for (ResolvableCompilationUnit unit
- in library.resolvableCompilationUnits) {
- Source source = unit.source;
- CompilationUnit ast = unit.compilationUnit;
- TypeResolverVisitor visitor = new TypeResolverVisitor(
- library.libraryElement,
- source,
- _typeProvider,
- library.libraryScope.errorListener,
- nameScope: library.libraryScope);
- ast.accept(visitor);
- }
- library.libraryElement.createLoadLibraryFunction(_typeProvider);
- }
- });
- }
-
- /**
- * Return an array containing the lexical identifiers associated with the nodes in the given list.
- *
- * @param names the AST nodes representing the identifiers
- * @return the lexical identifiers associated with the nodes in the list
- */
- List<String> _getIdentifiers(NodeList<SimpleIdentifier> names) {
- int count = names.length;
- List<String> identifiers = new List<String>(count);
- for (int i = 0; i < count; i++) {
- identifiers[i] = names[i].name;
- }
- return identifiers;
- }
-
- /**
- * Compute a value for all of the constants in the libraries being analyzed.
- */
- void _performConstantEvaluation() {
- PerformanceStatistics.resolve.makeCurrentWhile(() {
- ConstantValueComputer computer = new ConstantValueComputer(
- analysisContext,
- _typeProvider,
- analysisContext.declaredVariables,
- null,
- _typeSystem);
- for (ResolvableLibrary library in _librariesInCycle) {
- for (ResolvableCompilationUnit unit
- in library.resolvableCompilationUnits) {
- CompilationUnit ast = unit.compilationUnit;
- if (ast != null) {
- computer.add(ast, unit.source, library.librarySource);
- }
- }
- }
- computer.computeValues();
- // As a temporary workaround for issue 21572, run ConstantVerifier now.
- // TODO(paulberry): remove this workaround once issue 21572 is fixed.
- for (ResolvableLibrary library in _librariesInCycle) {
- for (ResolvableCompilationUnit unit
- in library.resolvableCompilationUnits) {
- CompilationUnit ast = unit.compilationUnit;
- ErrorReporter errorReporter =
- new ErrorReporter(_errorListener, unit.source);
- ConstantVerifier constantVerifier = new ConstantVerifier(
- errorReporter,
- library.libraryElement,
- _typeProvider,
- analysisContext.declaredVariables);
- ast.accept(constantVerifier);
- }
- }
- });
- }
-
- /**
- * Resolve the identifiers and perform type analysis in the libraries in the current cycle.
- *
- * @throws AnalysisException if any of the identifiers could not be resolved or if any of the
- * libraries could not have their types analyzed
- */
- void _resolveReferencesAndTypes() {
- for (ResolvableLibrary library in _librariesInCycle) {
- _resolveReferencesAndTypesInLibrary(library);
- }
- }
-
- /**
- * Resolve the identifiers and perform type analysis in the given library.
- *
- * @param library the library to be resolved
- * @throws AnalysisException if any of the identifiers could not be resolved or if the types in
- * the library cannot be analyzed
- */
- void _resolveReferencesAndTypesInLibrary(ResolvableLibrary library) {
- PerformanceStatistics.resolve.makeCurrentWhile(() {
- for (ResolvableCompilationUnit unit
- in library.resolvableCompilationUnits) {
- Source source = unit.source;
- CompilationUnit ast = unit.compilationUnit;
- ast.accept(new VariableResolverVisitor(library.libraryElement, source,
- _typeProvider, library.libraryScope.errorListener,
- nameScope: library.libraryScope));
- ResolverVisitor visitor = new ResolverVisitor(library.libraryElement,
- source, _typeProvider, library._libraryScope.errorListener,
- nameScope: library._libraryScope,
- inheritanceManager: library.inheritanceManager);
- ast.accept(visitor);
- }
- });
- }
-
- /**
- * Report that the async library could not be resolved in the given
- * [analysisContext] and throw an exception. [asyncLibrarySource] is the source
- * representing the async library.
- */
- static void missingAsyncLibrary(
- AnalysisContext analysisContext, Source asyncLibrarySource) {
- throw new AnalysisException("Could not resolve dart:async");
- }
-
- /**
- * Report that the core library could not be resolved in the given analysis context and throw an
- * exception.
- *
- * @param analysisContext the analysis context in which the failure occurred
- * @param coreLibrarySource the source representing the core library
- * @throws AnalysisException always
- */
- static void missingCoreLibrary(
- AnalysisContext analysisContext, Source coreLibrarySource) {
- throw new AnalysisException("Could not resolve dart:core");
- }
-}
/**
* Instances of the class `LibraryScope` implement a scope containing all of the names defined
@@ -9431,29 +7010,6 @@
}
/**
- * This constructor takes an initial capacity of the map.
- *
- * @param initialCapacity the initial capacity
- */
- @deprecated // Use new MemberMap(initialCapacity)
- MemberMap.con1(int initialCapacity) {
- _initArrays(initialCapacity);
- }
-
- /**
- * Copy constructor.
- */
- @deprecated // Use new MemberMap.from(memberMap)
- MemberMap.con2(MemberMap memberMap) {
- _initArrays(memberMap._size + 5);
- for (int i = 0; i < memberMap._size; i++) {
- _keys[i] = memberMap._keys[i];
- _values[i] = memberMap._values[i];
- }
- _size = memberMap._size;
- }
-
- /**
* Initialize a newly created member map to contain the same members as the
* given [memberMap].
*/
@@ -9990,10 +7546,9 @@
*/
PartialResolverVisitor(LibraryElement definingLibrary, Source source,
TypeProvider typeProvider, AnalysisErrorListener errorListener,
- {Scope nameScope,
- InheritanceManager inheritanceManager,
- StaticTypeAnalyzerFactory typeAnalyzerFactory})
- : super(definingLibrary, source, typeProvider, errorListener);
+ {Scope nameScope})
+ : super(definingLibrary, source, typeProvider, errorListener,
+ nameScope: nameScope);
@override
Object visitBlockFunctionBody(BlockFunctionBody node) {
@@ -10295,273 +7850,6 @@
}
/**
- * A `ResolvableLibrary` represents a single library during the resolution of
- * some (possibly different) library. They are not intended to be used except
- * during the resolution process.
- */
-class ResolvableLibrary {
- /**
- * An empty array that can be used to initialize lists of libraries.
- */
- static List<ResolvableLibrary> _EMPTY_ARRAY = new List<ResolvableLibrary>(0);
-
- /**
- * The next artificial hash code.
- */
- static int _NEXT_HASH_CODE = 0;
-
- /**
- * The artifitial hash code for this object.
- */
- final int _hashCode = _nextHashCode();
-
- /**
- * The source specifying the defining compilation unit of this library.
- */
- final Source librarySource;
-
- /**
- * A list containing all of the libraries that are imported into this library.
- */
- List<ResolvableLibrary> _importedLibraries = _EMPTY_ARRAY;
-
- /**
- * A flag indicating whether this library explicitly imports core.
- */
- bool explicitlyImportsCore = false;
-
- /**
- * An array containing all of the libraries that are exported from this library.
- */
- List<ResolvableLibrary> _exportedLibraries = _EMPTY_ARRAY;
-
- /**
- * An array containing the compilation units that comprise this library. The
- * defining compilation unit is always first.
- */
- List<ResolvableCompilationUnit> _compilationUnits;
-
- /**
- * The library element representing this library.
- */
- LibraryElementImpl _libraryElement;
-
- /**
- * The listener to which analysis errors will be reported.
- */
- AnalysisErrorListener _errorListener;
-
- /**
- * The inheritance manager which is used for member lookups in this library.
- */
- InheritanceManager _inheritanceManager;
-
- /**
- * The library scope used when resolving elements within this library's compilation units.
- */
- LibraryScope _libraryScope;
-
- /**
- * Initialize a newly created data holder that can maintain the data associated with a library.
- *
- * @param librarySource the source specifying the defining compilation unit of this library
- * @param errorListener the listener to which analysis errors will be reported
- */
- ResolvableLibrary(this.librarySource);
-
- /**
- * Return an array of the [CompilationUnit]s that make up the library. The first unit is
- * always the defining unit.
- *
- * @return an array of the [CompilationUnit]s that make up the library. The first unit is
- * always the defining unit
- */
- List<CompilationUnit> get compilationUnits {
- int count = _compilationUnits.length;
- List<CompilationUnit> units = new List<CompilationUnit>(count);
- for (int i = 0; i < count; i++) {
- units[i] = _compilationUnits[i].compilationUnit;
- }
- return units;
- }
-
- /**
- * Return an array containing the sources for the compilation units in this library, including the
- * defining compilation unit.
- *
- * @return the sources for the compilation units in this library
- */
- List<Source> get compilationUnitSources {
- int count = _compilationUnits.length;
- List<Source> sources = new List<Source>(count);
- for (int i = 0; i < count; i++) {
- sources[i] = _compilationUnits[i].source;
- }
- return sources;
- }
-
- /**
- * Return the AST structure associated with the defining compilation unit for this library.
- *
- * @return the AST structure associated with the defining compilation unit for this library
- * @throws AnalysisException if an AST structure could not be created for the defining compilation
- * unit
- */
- CompilationUnit get definingCompilationUnit =>
- _compilationUnits[0].compilationUnit;
-
- /**
- * Set the listener to which analysis errors will be reported to be the given listener.
- *
- * @param errorListener the listener to which analysis errors will be reported
- */
- void set errorListener(AnalysisErrorListener errorListener) {
- this._errorListener = errorListener;
- }
-
- /**
- * Set the libraries that are exported by this library to be those in the given array.
- *
- * @param exportedLibraries the libraries that are exported by this library
- */
- void set exportedLibraries(List<ResolvableLibrary> exportedLibraries) {
- this._exportedLibraries = exportedLibraries;
- }
-
- /**
- * Return an array containing the libraries that are exported from this library.
- *
- * @return an array containing the libraries that are exported from this library
- */
- List<ResolvableLibrary> get exports => _exportedLibraries;
-
- @override
- int get hashCode => _hashCode;
-
- /**
- * Set the libraries that are imported into this library to be those in the given array.
- *
- * @param importedLibraries the libraries that are imported into this library
- */
- void set importedLibraries(List<ResolvableLibrary> importedLibraries) {
- this._importedLibraries = importedLibraries;
- }
-
- /**
- * Return an array containing the libraries that are imported into this library.
- *
- * @return an array containing the libraries that are imported into this library
- */
- List<ResolvableLibrary> get imports => _importedLibraries;
-
- /**
- * Return an array containing the libraries that are either imported or exported from this
- * library.
- *
- * @return the libraries that are either imported or exported from this library
- */
- List<ResolvableLibrary> get importsAndExports {
- HashSet<ResolvableLibrary> libraries = new HashSet<ResolvableLibrary>();
- for (ResolvableLibrary library in _importedLibraries) {
- libraries.add(library);
- }
- for (ResolvableLibrary library in _exportedLibraries) {
- libraries.add(library);
- }
- return new List.from(libraries);
- }
-
- /**
- * Return the inheritance manager for this library.
- *
- * @return the inheritance manager for this library
- */
- InheritanceManager get inheritanceManager {
- if (_inheritanceManager == null) {
- return _inheritanceManager = new InheritanceManager(_libraryElement);
- }
- return _inheritanceManager;
- }
-
- /**
- * Return the library element representing this library, creating it if necessary.
- *
- * @return the library element representing this library
- */
- LibraryElementImpl get libraryElement => _libraryElement;
-
- /**
- * Set the library element representing this library to the given library element.
- *
- * @param libraryElement the library element representing this library
- */
- void set libraryElement(LibraryElementImpl libraryElement) {
- this._libraryElement = libraryElement;
- if (_inheritanceManager != null) {
- _inheritanceManager.libraryElement = libraryElement;
- }
- }
-
- /**
- * Return the library scope used when resolving elements within this library's compilation units.
- *
- * @return the library scope used when resolving elements within this library's compilation units
- */
- LibraryScope get libraryScope {
- if (_libraryScope == null) {
- _libraryScope = new LibraryScope(_libraryElement, _errorListener);
- }
- return _libraryScope;
- }
-
- /**
- * Return an array containing the compilation units that comprise this library. The defining
- * compilation unit is always first.
- *
- * @return the compilation units that comprise this library
- */
- List<ResolvableCompilationUnit> get resolvableCompilationUnits =>
- _compilationUnits;
-
- /**
- * Set the compilation unit in this library to the given compilation units. The defining
- * compilation unit must be the first element of the array.
- *
- * @param units the compilation units in this library
- */
- void set resolvableCompilationUnits(List<ResolvableCompilationUnit> units) {
- _compilationUnits = units;
- }
-
- /**
- * Return the AST structure associated with the given source, or `null` if the source does
- * not represent a compilation unit that is included in this library.
- *
- * @param source the source representing the compilation unit whose AST is to be returned
- * @return the AST structure associated with the given source
- * @throws AnalysisException if an AST structure could not be created for the compilation unit
- */
- CompilationUnit getAST(Source source) {
- int count = _compilationUnits.length;
- for (int i = 0; i < count; i++) {
- if (_compilationUnits[i].source == source) {
- return _compilationUnits[i].compilationUnit;
- }
- }
- return null;
- }
-
- @override
- String toString() => librarySource.shortName;
-
- static int _nextHashCode() {
- int next = (_NEXT_HASH_CODE + 1) & 0xFFFFFF;
- _NEXT_HASH_CODE = next;
- return next;
- }
-}
-
-/**
* The enumeration `ResolverErrorCode` defines the error codes used for errors
* detected by the resolver. The convention for this class is for the name of
* the error code to indicate the problem that caused the error to be generated
@@ -10603,11 +7891,6 @@
*/
class ResolverVisitor extends ScopedVisitor {
/**
- * The manager for the inheritance mappings.
- */
- InheritanceManager _inheritanceManager;
-
- /**
* The object used to resolve the element associated with the current node.
*/
ElementResolver elementResolver;
@@ -10693,16 +7976,9 @@
*/
ResolverVisitor(LibraryElement definingLibrary, Source source,
TypeProvider typeProvider, AnalysisErrorListener errorListener,
- {Scope nameScope,
- InheritanceManager inheritanceManager,
- StaticTypeAnalyzerFactory typeAnalyzerFactory})
+ {Scope nameScope})
: super(definingLibrary, source, typeProvider, errorListener,
nameScope: nameScope) {
- if (inheritanceManager == null) {
- this._inheritanceManager = new InheritanceManager(definingLibrary);
- } else {
- this._inheritanceManager = inheritanceManager;
- }
this.elementResolver = new ElementResolver(this);
this.typeSystem = definingLibrary.context.typeSystem;
bool strongModeHints = false;
@@ -10712,33 +7988,10 @@
}
this.inferenceContext = new InferenceContext._(
errorListener, typeProvider, typeSystem, strongModeHints);
- if (typeAnalyzerFactory == null) {
- this.typeAnalyzer = new StaticTypeAnalyzer(this);
- } else {
- this.typeAnalyzer = typeAnalyzerFactory(this);
- }
+ this.typeAnalyzer = new StaticTypeAnalyzer(this);
}
/**
- * Initialize a newly created visitor to resolve the nodes in a compilation unit.
- *
- * @param library the library containing the compilation unit being resolved
- * @param source the source representing the compilation unit being visited
- * @param typeProvider the object used to access the types from the core library
- *
- * Deprecated. Please use unnamed constructor instead.
- */
- @deprecated
- ResolverVisitor.con1(
- Library library, Source source, TypeProvider typeProvider,
- {StaticTypeAnalyzerFactory typeAnalyzerFactory})
- : this(
- library.libraryElement, source, typeProvider, library.errorListener,
- nameScope: library.libraryScope,
- inheritanceManager: library.inheritanceManager,
- typeAnalyzerFactory: typeAnalyzerFactory);
-
- /**
* Return the element representing the function containing the current node, or `null` if
* the current node is not contained in a function.
*
@@ -11061,9 +8314,9 @@
@override
Object visitAssignmentExpression(AssignmentExpression node) {
safelyVisit(node.leftHandSide);
- sc.TokenType operator = node.operator.type;
- if (operator == sc.TokenType.EQ ||
- operator == sc.TokenType.QUESTION_QUESTION_EQ) {
+ TokenType operator = node.operator.type;
+ if (operator == TokenType.EQ ||
+ operator == TokenType.QUESTION_QUESTION_EQ) {
InferenceContext.setType(
node.rightHandSide, node.leftHandSide.staticType);
}
@@ -11087,10 +8340,10 @@
@override
Object visitBinaryExpression(BinaryExpression node) {
- sc.TokenType operatorType = node.operator.type;
+ TokenType operatorType = node.operator.type;
Expression leftOperand = node.leftOperand;
Expression rightOperand = node.rightOperand;
- if (operatorType == sc.TokenType.AMPERSAND_AMPERSAND) {
+ if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
safelyVisit(leftOperand);
if (rightOperand != null) {
_overrideManager.enterScope();
@@ -11113,7 +8366,7 @@
_overrideManager.exitScope();
}
}
- } else if (operatorType == sc.TokenType.BAR_BAR) {
+ } else if (operatorType == TokenType.BAR_BAR) {
safelyVisit(leftOperand);
if (rightOperand != null) {
_overrideManager.enterScope();
@@ -11754,22 +9007,23 @@
@override
Object visitListLiteral(ListLiteral node) {
DartType contextType = InferenceContext.getType(node);
- if (node.typeArguments == null && contextType is InterfaceType) {
+ List<DartType> targs = null;
+ if (node.typeArguments != null) {
+ targs = node.typeArguments.arguments.map((t) => t.type).toList();
+ } else if (contextType is InterfaceType) {
InterfaceType listD =
typeProvider.listType.substitute4([typeProvider.dynamicType]);
- List<DartType> targs = inferenceContext.matchTypes(listD, contextType);
- if (targs != null &&
- targs.length == 1 &&
- targs.any((t) => !t.isDynamic)) {
- DartType eType = targs[0];
- InterfaceType listT = typeProvider.listType.substitute4([eType]);
- for (Expression child in node.elements) {
- InferenceContext.setType(child, eType);
- }
- InferenceContext.setType(node, listT);
- } else {
- InferenceContext.clearType(node);
+ targs = inferenceContext.matchTypes(listD, contextType);
+ }
+ if (targs != null && targs.length == 1 && !targs[0].isDynamic) {
+ DartType eType = targs[0];
+ InterfaceType listT = typeProvider.listType.substitute4([eType]);
+ for (Expression child in node.elements) {
+ InferenceContext.setType(child, eType);
}
+ InferenceContext.setType(node, listT);
+ } else {
+ InferenceContext.clearType(node);
}
super.visitListLiteral(node);
return null;
@@ -11778,24 +9032,25 @@
@override
Object visitMapLiteral(MapLiteral node) {
DartType contextType = InferenceContext.getType(node);
- if (node.typeArguments == null && contextType is InterfaceType) {
+ List<DartType> targs = null;
+ if (node.typeArguments != null) {
+ targs = node.typeArguments.arguments.map((t) => t.type).toList();
+ } else if (contextType is InterfaceType) {
InterfaceType mapD = typeProvider.mapType
.substitute4([typeProvider.dynamicType, typeProvider.dynamicType]);
- List<DartType> targs = inferenceContext.matchTypes(mapD, contextType);
- if (targs != null &&
- targs.length == 2 &&
- targs.any((t) => !t.isDynamic)) {
- DartType kType = targs[0];
- DartType vType = targs[1];
- InterfaceType mapT = typeProvider.mapType.substitute4([kType, vType]);
- for (MapLiteralEntry entry in node.entries) {
- InferenceContext.setType(entry.key, kType);
- InferenceContext.setType(entry.value, vType);
- }
- InferenceContext.setType(node, mapT);
- } else {
- InferenceContext.clearType(node);
+ targs = inferenceContext.matchTypes(mapD, contextType);
+ }
+ if (targs != null && targs.length == 2 && targs.any((t) => !t.isDynamic)) {
+ DartType kType = targs[0];
+ DartType vType = targs[1];
+ InterfaceType mapT = typeProvider.mapType.substitute4([kType, vType]);
+ for (MapLiteralEntry entry in node.entries) {
+ InferenceContext.setType(entry.key, kType);
+ InferenceContext.setType(entry.value, vType);
}
+ InferenceContext.setType(node, mapT);
+ } else {
+ InferenceContext.clearType(node);
}
super.visitMapLiteral(node);
return null;
@@ -11821,11 +9076,20 @@
// because it needs to be visited in the context of the invocation.
//
safelyVisit(node.target);
+ safelyVisit(node.typeArguments);
node.accept(elementResolver);
_inferFunctionExpressionsParametersTypes(node.argumentList);
Element methodElement = node.methodName.staticElement;
- if (methodElement is ExecutableElement) {
- InferenceContext.setType(node.argumentList, methodElement.type);
+ DartType contextType = null;
+ if (methodElement is PropertyAccessorElement && methodElement.isGetter) {
+ contextType = methodElement.returnType;
+ } else if (methodElement is VariableElement) {
+ contextType = methodElement.type;
+ } else if (methodElement is ExecutableElement) {
+ contextType = methodElement.type;
+ }
+ if (contextType is FunctionType) {
+ InferenceContext.setType(node.argumentList, contextType);
}
safelyVisit(node.argumentList);
node.accept(typeAnalyzer);
@@ -12345,7 +9609,7 @@
void _promoteTypes(Expression condition) {
if (condition is BinaryExpression) {
BinaryExpression binary = condition;
- if (binary.operator.type == sc.TokenType.AMPERSAND_AMPERSAND) {
+ if (binary.operator.type == TokenType.AMPERSAND_AMPERSAND) {
Expression left = binary.leftOperand;
Expression right = binary.rightOperand;
_promoteTypes(left);
@@ -12371,7 +9635,7 @@
void _propagateFalseState(Expression condition) {
if (condition is BinaryExpression) {
BinaryExpression binary = condition;
- if (binary.operator.type == sc.TokenType.BAR_BAR) {
+ if (binary.operator.type == TokenType.BAR_BAR) {
_propagateFalseState(binary.leftOperand);
_propagateFalseState(binary.rightOperand);
}
@@ -12385,7 +9649,7 @@
}
} else if (condition is PrefixExpression) {
PrefixExpression prefix = condition;
- if (prefix.operator.type == sc.TokenType.BANG) {
+ if (prefix.operator.type == TokenType.BANG) {
_propagateTrueState(prefix.operand);
}
} else if (condition is ParenthesizedExpression) {
@@ -12412,7 +9676,7 @@
void _propagateTrueState(Expression condition) {
if (condition is BinaryExpression) {
BinaryExpression binary = condition;
- if (binary.operator.type == sc.TokenType.AMPERSAND_AMPERSAND) {
+ if (binary.operator.type == TokenType.AMPERSAND_AMPERSAND) {
_propagateTrueState(binary.leftOperand);
_propagateTrueState(binary.rightOperand);
}
@@ -12426,7 +9690,7 @@
}
} else if (condition is PrefixExpression) {
PrefixExpression prefix = condition;
- if (prefix.operator.type == sc.TokenType.BANG) {
+ if (prefix.operator.type == TokenType.BANG) {
_propagateFalseState(prefix.operand);
}
} else if (condition is ParenthesizedExpression) {
@@ -12762,7 +10026,7 @@
* @param token the token specifying the location of the error
* @param arguments the arguments to the error, used to compose the error message
*/
- void reportErrorForToken(ErrorCode errorCode, sc.Token token,
+ void reportErrorForToken(ErrorCode errorCode, Token token,
[List<Object> arguments]) {
errorListener.onError(new AnalysisError(
source, token.offset, token.length, errorCode, arguments));
@@ -13505,12 +10769,12 @@
*
* @param token the head of the list of tokens being searched
*/
- void _gatherTodoComments(sc.Token token) {
- while (token != null && token.type != sc.TokenType.EOF) {
- sc.Token commentToken = token.precedingComments;
+ void _gatherTodoComments(Token token) {
+ while (token != null && token.type != TokenType.EOF) {
+ Token commentToken = token.precedingComments;
while (commentToken != null) {
- if (commentToken.type == sc.TokenType.SINGLE_LINE_COMMENT ||
- commentToken.type == sc.TokenType.MULTI_LINE_COMMENT) {
+ if (commentToken.type == TokenType.SINGLE_LINE_COMMENT ||
+ commentToken.type == TokenType.MULTI_LINE_COMMENT) {
_scrapeTodoComment(commentToken);
}
commentToken = commentToken.next;
@@ -13524,7 +10788,7 @@
*
* @param commentToken the comment token to analyze
*/
- void _scrapeTodoComment(sc.Token commentToken) {
+ void _scrapeTodoComment(Token commentToken) {
JavaPatternMatcher matcher =
new JavaPatternMatcher(TodoCode.TODO_REGEX, commentToken.lexeme);
if (matcher.find()) {
@@ -14481,6 +11745,8 @@
super.visitClassDeclaration(node);
ClassElementImpl classElement = _getClassElement(node.name);
if (classElement != null) {
+ // Clear this flag, as we just invalidated any inferred member types.
+ classElement.hasBeenInferred = false;
classElement.hasReferenceToSuper = _hasReferenceToSuper;
}
return null;
@@ -15399,7 +12665,7 @@
// If the type is not an InterfaceType, then visitTypeName() sets the type
// to be a DynamicTypeImpl
Identifier name = typeName.name;
- if (name.name == sc.Keyword.DYNAMIC.syntax) {
+ if (name.name == Keyword.DYNAMIC.syntax) {
reportErrorForNode(dynamicTypeError, name, [name.name]);
} else {
reportErrorForNode(nonTypeError, name, [name.name]);
@@ -15472,8 +12738,8 @@
* @return `true` if the name of the given [TypeName] is an built-in identifier.
*/
static bool _isBuiltInIdentifier(TypeName node) {
- sc.Token token = node.name.beginToken;
- return token.type == sc.TokenType.KEYWORD;
+ Token token = node.name.beginToken;
+ return token.type == TokenType.KEYWORD;
}
/**
@@ -15769,22 +13035,6 @@
: super(definingLibrary, source, typeProvider, errorListener,
nameScope: nameScope);
- /**
- * Initialize a newly created visitor to resolve the nodes in a compilation unit.
- *
- * @param library the library containing the compilation unit being resolved
- * @param source the source representing the compilation unit being visited
- * @param typeProvider the object used to access the types from the core library
- *
- * Deprecated. Please use unnamed constructor instead.
- */
- @deprecated
- VariableResolverVisitor.con1(
- Library library, Source source, TypeProvider typeProvider)
- : this(
- library.libraryElement, source, typeProvider, library.errorListener,
- nameScope: library.libraryScope);
-
@override
Object visitExportDirective(ExportDirective node) => null;
diff --git a/pkg/analyzer/lib/src/generated/scanner.dart b/pkg/analyzer/lib/src/generated/scanner.dart
index a99997a..49ea3ba 100644
--- a/pkg/analyzer/lib/src/generated/scanner.dart
+++ b/pkg/analyzer/lib/src/generated/scanner.dart
@@ -2,13 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.scanner;
+library analyzer.src.generated.scanner;
import 'dart:collection';
-import 'error.dart';
-import 'java_engine.dart';
-import 'source.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/source.dart';
/**
* The opening half of a grouping pair of tokens. This is used for curly
@@ -246,7 +246,6 @@
CommentToken copy() => new CommentToken(type, _value, offset);
}
-
/**
* A documentation comment token.
*/
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index c4f034f..4c756e2 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -2,13 +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.
-library engine.sdk;
+library analyzer.src.generated.sdk;
import 'dart:collection';
-import 'ast.dart';
-import 'engine.dart' show AnalysisContext;
-import 'source.dart' show ContentCache, Source, UriKind;
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
+import 'package:analyzer/src/generated/source.dart'
+ show ContentCache, Source, UriKind;
/**
* A Dart SDK installed in a specified location.
diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
index b155b9a..1f98ba3 100644
--- a/pkg/analyzer/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.dart
@@ -2,23 +2,22 @@
// for 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 engine.sdk.io;
+library analyzer.src.generated.sdk_io;
import 'dart:io';
-import 'package:analyzer/src/context/context.dart' as newContext;
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/java_engine.dart';
-
-import 'ast.dart';
-import 'engine.dart';
-import 'error.dart';
-import 'java_core.dart';
-import 'java_engine_io.dart';
-import 'java_io.dart';
-import 'parser.dart';
-import 'scanner.dart';
-import 'sdk.dart';
-import 'source_io.dart';
+import 'package:analyzer/src/generated/java_engine_io.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source_io.dart';
/**
* A Dart SDK installed in a specified directory. Typical Dart SDK layout is
@@ -242,11 +241,7 @@
@override
AnalysisContext get context {
if (_analysisContext == null) {
- if (AnalysisEngine.instance.useTaskModel) {
- _analysisContext = new newContext.SdkAnalysisContext();
- } else {
- _analysisContext = new SdkAnalysisContext();
- }
+ _analysisContext = new SdkAnalysisContext();
SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
_analysisContext.sourceFactory = factory;
List<String> uris = this.uris;
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 79cd48f..3c25f11 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.source;
+library analyzer.src.generated.source;
import 'dart:collection';
import "dart:math" as math;
@@ -10,18 +10,17 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
+import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
+import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
import 'package:analyzer/src/generated/utilities_dart.dart' as utils;
import 'package:analyzer/task/model.dart';
import 'package:package_config/packages.dart';
import 'package:path/path.dart' as pathos;
-import 'engine.dart';
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'java_io.dart' show JavaFile;
-import 'sdk.dart' show DartSdk;
-import 'source_io.dart' show FileBasedSource;
-
/**
* A function that is used to visit [ContentCache] entries.
*/
@@ -411,12 +410,6 @@
/**
* An empty list of sources.
*/
- @deprecated // Use Source.EMPTY_LIST
- static const List<Source> EMPTY_ARRAY = EMPTY_LIST;
-
- /**
- * An empty list of sources.
- */
static const List<Source> EMPTY_LIST = const <Source>[];
/**
@@ -668,6 +661,17 @@
}
/**
+ * Return a source factory that will resolve URI's in the same way that this
+ * source factory does.
+ */
+ SourceFactory clone() {
+ SourceFactory factory =
+ new SourceFactory(_resolvers, _packages, _resourceProvider);
+ factory.localSourcePredicate = _localSourcePredicate;
+ return factory;
+ }
+
+ /**
* Return a source object representing the given absolute URI, or `null` if the URI is not a
* valid URI or if it is not an absolute URI.
*
@@ -734,14 +738,11 @@
bool isLocalSource(Source source) => _localSourcePredicate.isLocal(source);
/**
- * Return a source object representing the URI that results from resolving the given (possibly
- * relative) contained URI against the URI associated with an existing source object, whether or
- * not the resulting source exists, or `null` if either the contained URI is invalid or if
- * it cannot be resolved against the source object's URI.
- *
- * @param containingSource the source containing the given URI
- * @param containedUri the (possibly relative) URI to be resolved against the containing source
- * @return the source representing the contained URI
+ * Return a source representing the URI that results from resolving the given
+ * (possibly relative) [containedUri] against the URI associated with the
+ * [containingSource], whether or not the resulting source exists, or `null`
+ * if either the [containedUri] is invalid or if it cannot be resolved against
+ * the [containingSource]'s URI.
*/
Source resolveUri(Source containingSource, String containedUri) {
if (containedUri == null || containedUri.isEmpty) {
@@ -751,6 +752,8 @@
// Force the creation of an escaped URI to deal with spaces, etc.
return _internalResolveUri(
containingSource, parseUriWithException(containedUri));
+ } on URISyntaxException {
+ return null;
} catch (exception, stackTrace) {
String containingFullName =
containingSource != null ? containingSource.fullName : '<null>';
diff --git a/pkg/analyzer/lib/src/generated/source_io.dart b/pkg/analyzer/lib/src/generated/source_io.dart
index 0c5d9e8..4847d9a 100644
--- a/pkg/analyzer/lib/src/generated/source_io.dart
+++ b/pkg/analyzer/lib/src/generated/source_io.dart
@@ -2,17 +2,17 @@
// for 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 engine.source.io;
+library analyzer.src.generated.source_io;
import 'dart:collection';
-import 'engine.dart';
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'java_io.dart';
-import 'source.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/source.dart';
-export 'source.dart';
+export 'package:analyzer/src/generated/source.dart';
/**
* Instances of the class [DirectoryBasedSourceContainer] represent a source container that
@@ -136,27 +136,6 @@
'${uri == null ? file.toURI() : uri}@${file.getPath()}',
() => _idTable.length);
- /**
- * Initialize a newly created source object.
- *
- * @param file the file represented by this source
- */
- @deprecated // Use new FileBasedSource(file)
- FileBasedSource.con1(JavaFile file) : this(file);
-
- /**
- * Initialize a newly created source object.
- *
- * @param file the file represented by this source
- * @param uri the URI from which this source was originally derived
- */
- @deprecated // Use new FileBasedSource(file, uri)
- FileBasedSource.con2(Uri uri, JavaFile file)
- : uri = uri,
- file = file,
- id = _idTable.putIfAbsent(
- '$uri@${file.getPath()}', () => _idTable.length);
-
@override
TimestampedData<String> get contents {
return PerformanceStatistics.io.makeCurrentWhile(() {
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index a746a1e..96971cb 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -2,18 +2,17 @@
// for 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 engine.resolver.static_type_analyzer;
+library analyzer.src.generated.static_type_analyzer;
import 'dart:collection';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/scanner.dart';
-
-import 'ast.dart';
-import 'element.dart';
-import 'java_engine.dart';
-import 'resolver.dart';
-import 'scanner.dart' as sc;
-import 'utilities_dart.dart';
+import 'package:analyzer/src/generated/scanner.dart' as sc;
+import 'package:analyzer/src/generated/utilities_dart.dart';
/**
* Instances of the class `StaticTypeAnalyzer` perform two type-related tasks. First, they
@@ -1823,31 +1822,51 @@
Element element = node.methodName.staticElement;
DartType fnType = node.methodName.staticType;
TypeSystem ts = _typeSystem;
- // TODO(jmesserly): once we allow explicitly passed typeArguments, we need
- // to only do this if node.typeArguments == null.
- if (element is ExecutableElement &&
+ if (node.typeArguments == null &&
+ element is ExecutableElement &&
fnType is FunctionTypeImpl &&
ts is StrongTypeSystemImpl) {
- // We may have too many (or too few) arguments. Only use arguments
- // which have been matched up with a static parameter.
- Iterable<Expression> arguments = node.argumentList.arguments
- .where((e) => e.staticParameterElement != null);
- List<DartType> argTypes = arguments.map((e) => e.staticType).toList();
- List<DartType> paramTypes =
- arguments.map((e) => e.staticParameterElement.type).toList();
+ FunctionTypeImpl genericFunction = fnType.originalFunction;
+ if (element is PropertyAccessorElement) {
+ genericFunction = element.type.returnType;
+ }
+ if (genericFunction.boundTypeParameters.isEmpty) {
+ return false;
+ }
+ for (DartType typeArg in fnType.instantiatedTypeArguments) {
+ if (!typeArg.isDynamic) {
+ return false;
+ }
+ }
+
+ List<ParameterElement> genericParameters = genericFunction.parameters;
+ List<DartType> argTypes = new List<DartType>();
+ List<DartType> paramTypes = new List<DartType>();
+ for (Expression arg in node.argumentList.arguments) {
+ // We may have too many (or too few) arguments. Only use arguments
+ // which have been matched up with a static parameter.
+ ParameterElement p = arg.staticParameterElement;
+ if (p != null) {
+ int i = element.parameters.indexOf(p);
+ argTypes.add(arg.staticType);
+ paramTypes.add(genericParameters[i].type);
+ }
+ }
FunctionType inferred = ts.inferCallFromArguments(
- _typeProvider, fnType, paramTypes, argTypes);
+ _typeProvider, genericFunction, paramTypes, argTypes);
if (inferred != fnType) {
- // TODO(jmesserly): inference should be happening earlier, which would
- // allow these parameters to be correct from the get-go.
-
+ // TODO(jmesserly): we need to fix up the parameter elements based on
+ // inferred method.
List<ParameterElement> inferredParameters = inferred.parameters;
List<ParameterElement> correspondingParams =
new List<ParameterElement>();
- for (Expression arg in arguments) {
- int i = element.parameters.indexOf(arg.staticParameterElement);
- correspondingParams.add(inferredParameters[i]);
+ for (Expression arg in node.argumentList.arguments) {
+ ParameterElement p = arg.staticParameterElement;
+ if (p != null) {
+ int i = element.parameters.indexOf(p);
+ correspondingParams.add(inferredParameters[i]);
+ }
}
node.argumentList.correspondingStaticParameters = correspondingParams;
_recordStaticType(node.methodName, inferred);
@@ -1956,7 +1975,8 @@
* Return `true` if the given [Type] is the `Future` form the 'dart:async'
* library.
*/
- bool _isAsyncFutureType(DartType type) => type is InterfaceType &&
+ bool _isAsyncFutureType(DartType type) =>
+ type is InterfaceType &&
type.name == "Future" &&
_isAsyncLibrary(type.element.library);
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
index bb758b3..bfb87b6 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.testing.ast_factory;
+library analyzer.src.generated.testing.ast_factory;
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
@@ -46,11 +46,14 @@
new AsExpression(
expression, TokenFactory.tokenFromKeyword(Keyword.AS), type);
- static AssertStatement assertStatement(Expression condition) =>
+ static AssertStatement assertStatement(Expression condition,
+ [Expression message]) =>
new AssertStatement(
TokenFactory.tokenFromKeyword(Keyword.ASSERT),
TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
condition,
+ message == null ? null : TokenFactory.tokenFromType(TokenType.COMMA),
+ message,
TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
TokenFactory.tokenFromType(TokenType.SEMICOLON));
@@ -431,6 +434,7 @@
metadata,
TokenFactory.tokenFromKeyword(Keyword.EXPORT),
string2(uri),
+ null,
combinators,
TokenFactory.tokenFromType(TokenType.SEMICOLON));
@@ -657,6 +661,7 @@
metadata,
TokenFactory.tokenFromKeyword(Keyword.IMPORT),
string2(uri),
+ null,
!isDeferred ? null : TokenFactory.tokenFromKeyword(Keyword.DEFERRED),
prefix == null ? null : TokenFactory.tokenFromKeyword(Keyword.AS),
prefix == null ? null : identifier3(prefix),
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 4414103..4932e92 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.testing.element_factory;
+library analyzer.src.generated.testing.element_factory;
import 'dart:collection';
@@ -409,15 +409,6 @@
return getter;
}
- @deprecated
- static HtmlElementImpl htmlUnit(AnalysisContext context, String fileName) {
- Source source =
- new NonExistingSource(fileName, toUri(fileName), UriKind.FILE_URI);
- HtmlElementImpl unit = new HtmlElementImpl(context, fileName);
- unit.source = source;
- return unit;
- }
-
static ImportElementImpl importFor(
LibraryElement importedLibrary, PrefixElement prefix,
[List<NamespaceCombinator> combinators =
diff --git a/pkg/analyzer/lib/src/generated/testing/html_factory.dart b/pkg/analyzer/lib/src/generated/testing/html_factory.dart
deleted file mode 100644
index a9ac412..0000000
--- a/pkg/analyzer/lib/src/generated/testing/html_factory.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library engine.testing.html_factory;
-
-import 'package:analyzer/src/generated/html.dart';
-
-/**
- * Utility methods to create HTML nodes.
- */
-@deprecated
-class HtmlFactory {
- static XmlAttributeNode attribute(String name, String value) {
- Token nameToken = stringToken(name);
- Token equalsToken = new Token.con1(TokenType.EQ, 0);
- Token valueToken = stringToken(value);
- return new XmlAttributeNode(nameToken, equalsToken, valueToken);
- }
-
- static Token gtToken() {
- return new Token.con1(TokenType.GT, 0);
- }
-
- static Token ltsToken() {
- return new Token.con1(TokenType.LT_SLASH, 0);
- }
-
- static Token ltToken() {
- return new Token.con1(TokenType.LT, 0);
- }
-
- static HtmlScriptTagNode scriptTag(
- [List<XmlAttributeNode> attributes = XmlAttributeNode.EMPTY_LIST]) {
- return new HtmlScriptTagNode(ltToken(), stringToken("script"), attributes,
- sgtToken(), null, null, null, null);
- }
-
- static HtmlScriptTagNode scriptTagWithContent(String contents,
- [List<XmlAttributeNode> attributes = XmlAttributeNode.EMPTY_LIST]) {
- Token attributeEnd = gtToken();
- Token contentToken = stringToken(contents);
- attributeEnd.setNext(contentToken);
- Token contentEnd = ltsToken();
- contentToken.setNext(contentEnd);
- return new HtmlScriptTagNode(ltToken(), stringToken("script"), attributes,
- attributeEnd, null, contentEnd, stringToken("script"), gtToken());
- }
-
- static Token sgtToken() {
- return new Token.con1(TokenType.SLASH_GT, 0);
- }
-
- static Token stringToken(String value) {
- return new Token.con2(TokenType.STRING, 0, value);
- }
-
- static XmlTagNode tagNode(String name,
- [List<XmlAttributeNode> attributes = XmlAttributeNode.EMPTY_LIST]) {
- return new XmlTagNode(ltToken(), stringToken(name), attributes, sgtToken(),
- null, null, null, null);
- }
-}
diff --git a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
index a183a6f..e44e2a3 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.testing.test_type_provider;
+library analyzer.src.generated.testing.test_type_provider;
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/constant.dart';
diff --git a/pkg/analyzer/lib/src/generated/testing/token_factory.dart b/pkg/analyzer/lib/src/generated/testing/token_factory.dart
index 1b9a828..a293842 100644
--- a/pkg/analyzer/lib/src/generated/testing/token_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/token_factory.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.testing.token_factory;
+library analyzer.src.generated.testing.token_factory;
import 'package:analyzer/src/generated/scanner.dart';
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index f731360..e520222 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -6,9 +6,9 @@
import 'dart:collection';
-import 'element.dart';
-import 'engine.dart' show AnalysisContext;
-import 'resolver.dart' show TypeProvider;
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
+import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<Element> visited);
typedef bool _SubtypeChecker<T>(T t1, T t2);
@@ -22,6 +22,22 @@
StrongTypeSystemImpl();
+ bool anyParameterType(FunctionType ft, bool predicate(DartType t)) {
+ return ft.parameters.any((p) => predicate(p.type));
+ }
+
+ /**
+ * Given a type t, if t is an interface type with a call method
+ * defined, return the function type for the call method, otherwise
+ * return null.
+ */
+ FunctionType getCallMethodType(DartType t) {
+ if (t is InterfaceType) {
+ return t.lookUpInheritedMethod("call")?.type;
+ }
+ return null;
+ }
+
@override
DartType getLeastUpperBound(
TypeProvider typeProvider, DartType type1, DartType type2) {
@@ -128,9 +144,45 @@
return fnType.instantiate(inferredTypes);
}
- // TODO(leafp): Document the rules in play here
+ /**
+ * Given a [FunctionType] [function], of the form
+ * <T0 extends B0, ... Tn extends Bn>.F (where Bi is implicitly
+ * dynamic if absent, and F is a non-generic function type)
+ * compute {I0/T0, ..., In/Tn}F
+ * where I_(i+1) = {I0/T0, ..., Ii/Ti, dynamic/T_(i+1)}B_(i+1).
+ * That is, we instantiate the generic with its bounds, replacing
+ * each Ti in Bi with dynamic to get Ii, and then replacing Ti with
+ * Ii in all of the remaining bounds.
+ */
+ DartType instantiateToBounds(FunctionType function) {
+ int count = function.boundTypeParameters.length;
+ if (count == 0) {
+ return function;
+ }
+ // We build up a substitution replacing bound parameters with
+ // their instantiated bounds, {substituted/variables}
+ List<DartType> substituted = new List<DartType>();
+ List<DartType> variables = new List<DartType>();
+ for (int i = 0; i < count; i++) {
+ TypeParameterElement param = function.boundTypeParameters[i];
+ DartType bound = param.bound ?? DynamicTypeImpl.instance;
+ DartType variable = param.type;
+ // For each Ti extends Bi, first compute Ii by replacing
+ // Ti in Bi with dynamic (simultaneously replacing all
+ // of the previous Tj (j < i) with their instantiated bounds.
+ substituted.add(DynamicTypeImpl.instance);
+ variables.add(variable);
+ // Now update the substitution to replace Ti with Ii instead
+ // of dynamic in subsequent rounds.
+ substituted[i] = bound.substitute2(substituted, variables);
+ }
+ return function.instantiate(substituted);
+ }
+
@override
bool isAssignableTo(DartType fromType, DartType toType) {
+ // TODO(leafp): Document the rules in play here
+
// An actual subtype
if (isSubtypeOf(fromType, toType)) {
return true;
@@ -138,8 +190,8 @@
// Don't allow implicit downcasts between function types
// and call method objects, as these will almost always fail.
- if ((fromType is FunctionType && _getCallMethodType(toType) != null) ||
- (toType is FunctionType && _getCallMethodType(fromType) != null)) {
+ if ((fromType is FunctionType && getCallMethodType(toType) != null) ||
+ (toType is FunctionType && getCallMethodType(fromType) != null)) {
return false;
}
@@ -160,21 +212,40 @@
return false;
}
+ bool isGroundType(DartType t) {
+ // TODO(leafp): Revisit this.
+ if (t is TypeParameterType) return false;
+ if (_isTop(t)) return true;
+
+ if (t is FunctionType) {
+ if (!_isTop(t.returnType) ||
+ anyParameterType(t, (pt) => !_isBottom(pt, dynamicIsBottom: true))) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ if (t is InterfaceType) {
+ var typeArguments = t.typeArguments;
+ for (var typeArgument in typeArguments) {
+ if (!_isTop(typeArgument)) return false;
+ }
+ return true;
+ }
+
+ // We should not see any other type aside from malformed code.
+ return false;
+ }
+
@override
bool isSubtypeOf(DartType leftType, DartType rightType) {
return _isSubtypeOf(leftType, rightType, null);
}
- // Given a type t, if t is an interface type with a call method
- // defined, return the function type for the call method, otherwise
- // return null.
- FunctionType _getCallMethodType(DartType t) {
- if (t is InterfaceType) {
- return t.lookUpInheritedMethod("call")?.type;
- }
- return null;
- }
-
+ /**
+ * Guard against loops in the class hierarchy
+ */
_GuardedSubtypeChecker<DartType> _guard(
_GuardedSubtypeChecker<DartType> check) {
return (DartType t1, DartType t2, Set<Element> visited) {
@@ -205,7 +276,6 @@
return (t.isDynamic && dynamicIsBottom) || t.isBottom;
}
- // Guard against loops in the class hierarchy
/**
* Check that [f1] is a subtype of [f2].
* [fuzzyArrows] indicates whether or not the f1 and f2 should be
@@ -214,14 +284,22 @@
*/
bool _isFunctionSubtypeOf(FunctionType f1, FunctionType f2,
{bool fuzzyArrows: true}) {
- final r1s = f1.normalParameterTypes;
- final o1s = f1.optionalParameterTypes;
- final n1s = f1.namedParameterTypes;
- final r2s = f2.normalParameterTypes;
- final o2s = f2.optionalParameterTypes;
- final n2s = f2.namedParameterTypes;
- final ret1 = f1.returnType;
- final ret2 = f2.returnType;
+ if (!f1.boundTypeParameters.isEmpty) {
+ if (f2.boundTypeParameters.isEmpty) {
+ f1 = instantiateToBounds(f1);
+ return _isFunctionSubtypeOf(f1, f2);
+ } else {
+ return _isGenericFunctionSubtypeOf(f1, f2, fuzzyArrows: fuzzyArrows);
+ }
+ }
+ final List<DartType> r1s = f1.normalParameterTypes;
+ final List<DartType> r2s = f2.normalParameterTypes;
+ final List<DartType> o1s = f1.optionalParameterTypes;
+ final List<DartType> o2s = f2.optionalParameterTypes;
+ final Map<String, DartType> n1s = f1.namedParameterTypes;
+ final Map<String, DartType> n2s = f2.namedParameterTypes;
+ final DartType ret1 = f1.returnType;
+ final DartType ret2 = f2.returnType;
// A -> B <: C -> D if C <: A and
// either D is void or B <: D
@@ -293,6 +371,54 @@
return true;
}
+ /**
+ * Check that [f1] is a subtype of [f2] where f1 and f2 are known
+ * to be generic function types (both have type parameters)
+ * [fuzzyArrows] indicates whether or not the f1 and f2 should be
+ * treated as fuzzy arrow types (and hence dynamic parameters to f2 treated
+ * as bottom).
+ */
+ bool _isGenericFunctionSubtypeOf(FunctionType f1, FunctionType f2,
+ {bool fuzzyArrows: true}) {
+ List<TypeParameterElement> params1 = f1.boundTypeParameters;
+ List<TypeParameterElement> params2 = f2.boundTypeParameters;
+ int count = params1.length;
+ if (params2.length != count) {
+ return false;
+ }
+ // We build up a substitution matching up the type parameters
+ // from the two types, {variablesFresh/variables1} and
+ // {variablesFresh/variables2}
+ List<DartType> variables1 = new List<DartType>();
+ List<DartType> variables2 = new List<DartType>();
+ List<DartType> variablesFresh = new List<DartType>();
+ for (int i = 0; i < count; i++) {
+ TypeParameterElement p1 = params1[i];
+ TypeParameterElement p2 = params2[i];
+ TypeParameterElementImpl pFresh =
+ new TypeParameterElementImpl(p2.name, -1);
+
+ DartType variable1 = p1.type;
+ DartType variable2 = p2.type;
+ DartType variableFresh = new TypeParameterTypeImpl(pFresh);
+
+ variables1.add(variable1);
+ variables2.add(variable2);
+ variablesFresh.add(variableFresh);
+ DartType bound1 = p1.bound ?? DynamicTypeImpl.instance;
+ DartType bound2 = p2.bound ?? DynamicTypeImpl.instance;
+ bound1 = bound1.substitute2(variablesFresh, variables1);
+ bound2 = bound2.substitute2(variablesFresh, variables2);
+ pFresh.bound = bound2;
+ if (!isSubtypeOf(bound2, bound1)) {
+ return false;
+ }
+ }
+ return _isFunctionSubtypeOf(
+ f1.instantiate(variablesFresh), f2.instantiate(variablesFresh),
+ fuzzyArrows: fuzzyArrows);
+ }
+
bool _isInterfaceSubtypeOf(
InterfaceType i1, InterfaceType i2, Set<Element> visited) {
// Guard recursive calls
@@ -407,7 +533,7 @@
// the interface type declares a call method with a type
// which is a super type of the function type.
if (t1 is InterfaceType && t2 is FunctionType) {
- var callType = _getCallMethodType(t1);
+ var callType = getCallMethodType(t1);
return (callType != null) && _isFunctionSubtypeOf(callType, t2);
}
@@ -440,6 +566,15 @@
TypeProvider typeProvider, DartType type1, DartType type2);
/**
+ * Given a [function] type, instantiate it with its bounds.
+ *
+ * The behavior of this method depends on the type system, for example, in
+ * classic Dart `dynamic` will be used for all type arguments, whereas
+ * strong mode prefers the actual bound type if it was specified.
+ */
+ FunctionType instantiateToBounds(FunctionType function);
+
+ /**
* Return `true` if the [leftType] is assignable to the [rightType] (that is,
* if leftType <==> rightType).
*/
@@ -547,6 +682,18 @@
}
}
+ /**
+ * Instantiate the function type using `dynamic` for all generic parameters.
+ */
+ FunctionType instantiateToBounds(FunctionType function) {
+ int count = function.boundTypeParameters.length;
+ if (count == 0) {
+ return function;
+ }
+ return function.instantiate(
+ new List<DartType>.filled(count, DynamicTypeImpl.instance));
+ }
+
@override
bool isAssignableTo(DartType leftType, DartType rightType) {
return leftType.isAssignableTo(rightType);
diff --git a/pkg/analyzer/lib/src/generated/utilities_collection.dart b/pkg/analyzer/lib/src/generated/utilities_collection.dart
index 0d2afe8..6a71b97 100644
--- a/pkg/analyzer/lib/src/generated/utilities_collection.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_collection.dart
@@ -2,13 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.utilities.collection;
+library analyzer.src.generated.utilities_collection;
-import "dart:math" as math;
import 'dart:collection';
+import "dart:math" as math;
-import 'java_core.dart';
-import 'scanner.dart' show Token;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/scanner.dart' show Token;
/**
* The class `BooleanArray` defines methods for operating on integers as if they were arrays
diff --git a/pkg/analyzer/lib/src/generated/utilities_dart.dart b/pkg/analyzer/lib/src/generated/utilities_dart.dart
index 882d182..5fe5e72 100644
--- a/pkg/analyzer/lib/src/generated/utilities_dart.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_dart.dart
@@ -2,9 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.utilities.dart;
+library analyzer.src.generated.utilities_dart;
-import 'java_core.dart';
+import 'package:analyzer/src/generated/java_core.dart';
/**
* Check whether [uri1] starts with (or 'is prefixed by') [uri2] by checking
diff --git a/pkg/analyzer/lib/src/generated/utilities_general.dart b/pkg/analyzer/lib/src/generated/utilities_general.dart
index c1a3446..004433c 100644
--- a/pkg/analyzer/lib/src/generated/utilities_general.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_general.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.utilities.general;
+library analyzer.src.generated.utilities_general;
import 'dart:collection';
import 'dart:developer' show UserTag;
diff --git a/pkg/analyzer/lib/src/generated/visitors.dart b/pkg/analyzer/lib/src/generated/visitors.dart
index 59e644f..46e2a41 100644
--- a/pkg/analyzer/lib/src/generated/visitors.dart
+++ b/pkg/analyzer/lib/src/generated/visitors.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.ast.visitors;
+library analyzer.src.generated.visitors;
import 'package:analyzer/src/generated/ast.dart';
@@ -153,6 +153,13 @@
}
@override
+ T visitConfiguration(Configuration node) {
+ _delegates.forEach((delegate) => delegate.visitConfiguration(node));
+ node.visitChildren(this);
+ return null;
+ }
+
+ @override
T visitConstructorDeclaration(ConstructorDeclaration node) {
_delegates
.forEach((delegate) => delegate.visitConstructorDeclaration(node));
@@ -205,6 +212,13 @@
}
@override
+ T visitDottedName(DottedName node) {
+ _delegates.forEach((delegate) => delegate.visitDottedName(node));
+ node.visitChildren(this);
+ return null;
+ }
+
+ @override
T visitDoubleLiteral(DoubleLiteral node) {
_delegates.forEach((delegate) => delegate.visitDoubleLiteral(node));
node.visitChildren(this);
@@ -291,15 +305,15 @@
}
@override
- T visitForStatement(ForStatement node) {
- _delegates.forEach((delegate) => delegate.visitForStatement(node));
+ T visitFormalParameterList(FormalParameterList node) {
+ _delegates.forEach((delegate) => delegate.visitFormalParameterList(node));
node.visitChildren(this);
return null;
}
@override
- T visitFormalParameterList(FormalParameterList node) {
- _delegates.forEach((delegate) => delegate.visitFormalParameterList(node));
+ T visitForStatement(ForStatement node) {
+ _delegates.forEach((delegate) => delegate.visitForStatement(node));
node.visitChildren(this);
return null;
}
@@ -542,15 +556,15 @@
}
@override
- T visitPrefixExpression(PrefixExpression node) {
- _delegates.forEach((delegate) => delegate.visitPrefixExpression(node));
+ T visitPrefixedIdentifier(PrefixedIdentifier node) {
+ _delegates.forEach((delegate) => delegate.visitPrefixedIdentifier(node));
node.visitChildren(this);
return null;
}
@override
- T visitPrefixedIdentifier(PrefixedIdentifier node) {
- _delegates.forEach((delegate) => delegate.visitPrefixedIdentifier(node));
+ T visitPrefixExpression(PrefixExpression node) {
+ _delegates.forEach((delegate) => delegate.visitPrefixExpression(node));
node.visitChildren(this);
return null;
}
diff --git a/pkg/analyzer/lib/src/plugin/options_plugin.dart b/pkg/analyzer/lib/src/plugin/options_plugin.dart
index 6e0ebd6..6fba649 100644
--- a/pkg/analyzer/lib/src/plugin/options_plugin.dart
+++ b/pkg/analyzer/lib/src/plugin/options_plugin.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.plugin.options;
+library analyzer.src.plugin.options_plugin;
import 'package:analyzer/plugin/options.dart';
import 'package:analyzer/plugin/task.dart';
diff --git a/pkg/analyzer/lib/src/plugin/plugin_configuration.dart b/pkg/analyzer/lib/src/plugin/plugin_configuration.dart
index 9365a3c..222e376 100644
--- a/pkg/analyzer/lib/src/plugin/plugin_configuration.dart
+++ b/pkg/analyzer/lib/src/plugin/plugin_configuration.dart
@@ -84,10 +84,11 @@
PluginConfig(this.plugins);
/// Create a plugin configuration from an options map.
- factory PluginConfig.fromOptions(Map<String, YamlNode> options) {
+ factory PluginConfig.fromOptions(Map<String, Object> options) {
List<PluginInfo> plugins = [];
var analyzerOptions = options[_analyzerOptionScope];
if (analyzerOptions != null) {
+ //TODO(pq): handle "raw" maps (https://github.com/dart-lang/sdk/issues/25126)
if (analyzerOptions is YamlMap) {
var pluginConfig = analyzerOptions[_pluginOptionScope];
if (pluginConfig is YamlMap) {
@@ -143,7 +144,7 @@
@override
void optionsProcessed(
- AnalysisContext context, Map<String, YamlNode> options) {
+ AnalysisContext context, Map<String, Object> options) {
_config = new PluginConfig.fromOptions(options);
}
}
diff --git a/pkg/analyzer/lib/src/services/lint.dart b/pkg/analyzer/lib/src/services/lint.dart
index a6b55cc..91d72a2 100644
--- a/pkg/analyzer/lib/src/services/lint.dart
+++ b/pkg/analyzer/lib/src/services/lint.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library lint;
+library analyzer.src.services.lint;
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
diff --git a/pkg/analyzer/lib/src/string_source.dart b/pkg/analyzer/lib/src/string_source.dart
index 5ffb332..0c99e69 100644
--- a/pkg/analyzer/lib/src/string_source.dart
+++ b/pkg/analyzer/lib/src/string_source.dart
@@ -2,10 +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.
-library analyzer.string_source;
+library analyzer.src.string_source;
-import 'generated/engine.dart' show TimestampedData;
-import 'generated/source.dart';
+import 'package:analyzer/src/generated/engine.dart' show TimestampedData;
+import 'package:analyzer/src/generated/source.dart';
/// An implementation of [Source] that's based on an in-memory Dart string.
class StringSource extends Source {
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 1a5046d..773515c 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -10,8 +10,7 @@
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart'
- hide AnalysisCache, AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/error_verifier.dart';
import 'package:analyzer/src/generated/incremental_resolver.dart';
@@ -30,7 +29,6 @@
import 'package:analyzer/src/task/inputs.dart';
import 'package:analyzer/src/task/model.dart';
import 'package:analyzer/src/task/strong/checker.dart';
-import 'package:analyzer/src/task/strong/rules.dart';
import 'package:analyzer/src/task/strong_mode.dart';
import 'package:analyzer/task/dart.dart';
import 'package:analyzer/task/general.dart';
@@ -2299,19 +2297,11 @@
String inputName = result.name + '_input';
errorLists.add(getRequiredInput(inputName));
}
-
- //
- // Gather error filters.
- //
- List<ErrorFilter> filters =
- context.getConfigurationData(CONFIGURED_ERROR_FILTERS);
for (ResultDescriptor result in enginePlugin.dartErrorsForUnit) {
String inputName = result.name + '_input';
Map<Source, List<AnalysisError>> errorMap = getRequiredInput(inputName);
for (List<AnalysisError> errors in errorMap.values) {
- errorLists.add(errors.where((AnalysisError error) {
- return !filters.any((ErrorFilter filter) => filter(error));
- }).toList());
+ errorLists.add(errors);
}
}
//
@@ -3597,11 +3587,8 @@
//
// Resolve references and record outputs.
//
- InheritanceManager inheritanceManager =
- new InheritanceManager(libraryElement);
PartialResolverVisitor visitor = new PartialResolverVisitor(libraryElement,
- unitElement.source, typeProvider, AnalysisErrorListener.NULL_LISTENER,
- inheritanceManager: inheritanceManager);
+ unitElement.source, typeProvider, AnalysisErrorListener.NULL_LISTENER);
unit.accept(visitor);
//
// Record outputs.
@@ -4387,14 +4374,11 @@
// the size of the enclosing class, and hence incrementally resolving each
// field was quadratic. We may wish to revisit this if we can resolve
// this performance issue.
- InheritanceManager inheritanceManager =
- new InheritanceManager(libraryElement);
PartialResolverVisitor visitor = new PartialResolverVisitor(
libraryElement,
unitElement.source,
typeProvider,
- AnalysisErrorListener.NULL_LISTENER,
- inheritanceManager: inheritanceManager);
+ AnalysisErrorListener.NULL_LISTENER);
unit.accept(visitor);
}
//
@@ -5007,7 +4991,8 @@
TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
CompilationUnit unit = getRequiredInput(UNIT_INPUT);
if (context.analysisOptions.strongMode) {
- unit.accept(new CodeChecker(new TypeRules(typeProvider), errorListener));
+ unit.accept(new CodeChecker(
+ typeProvider, new StrongTypeSystemImpl(), errorListener));
}
//
@@ -5102,7 +5087,8 @@
libraryElement,
typeProvider,
new InheritanceManager(libraryElement),
- context.analysisOptions.enableSuperMixins);
+ context.analysisOptions.enableSuperMixins,
+ context.analysisOptions.enableAssertMessage);
unit.accept(errorVerifier);
//
diff --git a/pkg/analyzer/lib/src/task/dart_work_manager.dart b/pkg/analyzer/lib/src/task/dart_work_manager.dart
index 793d9ce..a586b3b 100644
--- a/pkg/analyzer/lib/src/task/dart_work_manager.dart
+++ b/pkg/analyzer/lib/src/task/dart_work_manager.dart
@@ -474,7 +474,7 @@
}
bool _shouldErrorsBeComputed(Source source) =>
- context.shouldErrorsBeAnalyzed(source, null);
+ context.shouldErrorsBeAnalyzed(source);
static bool _isDartSource(AnalysisTarget target) {
return target is Source && AnalysisEngine.isDartFileName(target.fullName);
diff --git a/pkg/analyzer/lib/src/task/driver.dart b/pkg/analyzer/lib/src/task/driver.dart
index 43565f3..c5bc076 100644
--- a/pkg/analyzer/lib/src/task/driver.dart
+++ b/pkg/analyzer/lib/src/task/driver.dart
@@ -8,8 +8,7 @@
import 'dart:collection';
import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/generated/engine.dart'
- hide AnalysisTask, AnalysisContextImpl, WorkManager;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
diff --git a/pkg/analyzer/lib/src/task/general.dart b/pkg/analyzer/lib/src/task/general.dart
index 72f80fd..38d67df 100644
--- a/pkg/analyzer/lib/src/task/general.dart
+++ b/pkg/analyzer/lib/src/task/general.dart
@@ -4,7 +4,7 @@
library analyzer.src.task.general;
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/task/general.dart';
import 'package:analyzer/task/model.dart';
diff --git a/pkg/analyzer/lib/src/task/html.dart b/pkg/analyzer/lib/src/task/html.dart
index 219e1ee..b6a771a 100644
--- a/pkg/analyzer/lib/src/task/html.dart
+++ b/pkg/analyzer/lib/src/task/html.dart
@@ -7,7 +7,7 @@
import 'dart:collection';
import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/scanner.dart';
@@ -313,7 +313,8 @@
];
outputs[LINE_INFO] = new LineInfo(<int>[0]);
} else {
- HtmlParser parser = new HtmlParser(content, generateSpans: true);
+ HtmlParser parser = new HtmlParser(content,
+ generateSpans: true, lowercaseAttrName: false);
parser.compatMode = 'quirks';
Document document = parser.parse();
//
diff --git a/pkg/analyzer/lib/src/task/inputs.dart b/pkg/analyzer/lib/src/task/inputs.dart
index 2236ca0..1134a58 100644
--- a/pkg/analyzer/lib/src/task/inputs.dart
+++ b/pkg/analyzer/lib/src/task/inputs.dart
@@ -89,26 +89,28 @@
*/
abstract class ListTaskInputMixin<E> implements ListTaskInput<E> {
@override
- ListTaskInput /*<V>*/ toFlattenListOf(
+ ListTaskInput /*<V>*/ toFlattenListOf /*<V>*/ (
ListResultDescriptor /*<V>*/ subListResult) {
- return new ListToFlattenListTaskInput<E, dynamic /*V*/ >(
+ return new ListToFlattenListTaskInput<E, dynamic /*=V*/ >(
this, subListResult.of as dynamic);
}
- ListTaskInput /*<V>*/ toList(UnaryFunction<E, dynamic /*<V>*/ > mapper) {
- return new ListToListTaskInput<E, dynamic /*V*/ >(this, mapper);
+ ListTaskInput /*<V>*/ toList /*<V>*/ (
+ UnaryFunction<E, dynamic /*<=V>*/ > mapper) {
+ return new ListToListTaskInput<E, dynamic /*=V*/ >(this, mapper);
}
- ListTaskInput /*<V>*/ toListOf(ResultDescriptor /*<V>*/ valueResult) {
+ ListTaskInput /*<V>*/ toListOf /*<V>*/ (
+ ResultDescriptor /*<V>*/ valueResult) {
return (this as ListTaskInput<AnalysisTarget>).toList(valueResult.of);
}
- MapTaskInput<E, dynamic /*V*/ > toMap(
- UnaryFunction<E, dynamic /*<V>*/ > mapper) {
- return new ListToMapTaskInput<E, dynamic /*V*/ >(this, mapper);
+ MapTaskInput<E, dynamic /*=V*/ > toMap /*<V>*/ (
+ UnaryFunction<E, dynamic /*<=V>*/ > mapper) {
+ return new ListToMapTaskInput<E, dynamic /*=V*/ >(this, mapper);
}
- MapTaskInput<AnalysisTarget, dynamic /*V*/ > toMapOf(
+ MapTaskInput<AnalysisTarget, dynamic /*=V*/ > toMapOf /*<V>*/ (
ResultDescriptor /*<V>*/ valueResult) {
return (this as ListTaskInputImpl<AnalysisTarget>).toMap(valueResult.of);
}
@@ -277,11 +279,10 @@
* A mixin-ready implementation of [MapTaskInput].
*/
abstract class MapTaskInputMixin<K, V> implements MapTaskInput<K, V> {
- TaskInput<List /*<E>*/ > toFlattenList(
- BinaryFunction<K, dynamic /*element of V*/, dynamic /*<E>*/ > mapper) {
+ TaskInput<List /*<E>*/ > toFlattenList /*<E>*/ (
+ BinaryFunction<K, dynamic /*element of V*/, dynamic /*<=E>*/ > mapper) {
return new MapToFlattenListTaskInput<K, dynamic /*element of V*/,
- dynamic /*E*/ >(
- this as MapTaskInput<K, List /*<element of V>*/ >, mapper);
+ dynamic /*=E*/ >(this as MapTaskInput<K, List /*<element of V>*/ >, mapper);
}
}
@@ -440,22 +441,23 @@
new ObjectToListTaskInputBuilder<E>(this);
@override
- ListTaskInput /*<V>*/ toFlattenListOf(
+ ListTaskInput /*<V>*/ toFlattenListOf /*<V>*/ (
ListResultDescriptor /*<V>*/ subListResult) {
- return new ListToFlattenListTaskInput<E, dynamic /*V*/ >(
+ return new ListToFlattenListTaskInput<E, dynamic /*=V*/ >(
this, subListResult.of as dynamic);
}
@override
- ListTaskInput /*<V>*/ toListOf(ResultDescriptor /*<V>*/ valueResult) {
- return new ListToListTaskInput<E, dynamic /*V*/ >(
+ ListTaskInput /*<V>*/ toListOf /*<V>*/ (
+ ResultDescriptor /*<V>*/ valueResult) {
+ return new ListToListTaskInput<E, dynamic /*=V*/ >(
this, valueResult.of as dynamic);
}
@override
- MapTaskInput<AnalysisTarget, dynamic /*V*/ > toMapOf(
+ MapTaskInput<AnalysisTarget, dynamic /*=V*/ > toMapOf /*<V>*/ (
ResultDescriptor /*<V>*/ valueResult) {
- return new ListToMapTaskInput<AnalysisTarget, dynamic /*V*/ >(
+ return new ListToMapTaskInput<AnalysisTarget, dynamic /*=V*/ >(
this as dynamic, valueResult.of);
}
}
@@ -694,7 +696,7 @@
abstract class TaskInputImpl<V> implements TaskInput<V> {
@override
- ListTaskInput /*<E>*/ mappedToList(List /*<E>*/ mapper(V value)) {
+ ListTaskInput /*<E>*/ mappedToList /*<E>*/ (List /*<E>*/ mapper(V value)) {
return new ObjectToListTaskInput(this, mapper);
}
}
diff --git a/pkg/analyzer/lib/src/task/model.dart b/pkg/analyzer/lib/src/task/model.dart
index 50c05ee..8eaa838 100644
--- a/pkg/analyzer/lib/src/task/model.dart
+++ b/pkg/analyzer/lib/src/task/model.dart
@@ -4,7 +4,7 @@
library analyzer.src.task.model;
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/task/inputs.dart';
import 'package:analyzer/task/model.dart';
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 0596490..5b9acfe 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -4,9 +4,12 @@
library analyzer.src.task.options;
+import 'dart:collection';
+
import 'package:analyzer/analyzer.dart';
import 'package:analyzer/plugin/options.dart';
import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -28,9 +31,9 @@
final _OptionsProcessor _processor = new _OptionsProcessor();
/// Configure this [context] based on configuration details specified in
-/// the given [options].
+/// the given [options]. If [options] is `null`, default values are applied.
void configureContextOptions(
- AnalysisContext context, Map<String, YamlNode> options) =>
+ AnalysisContext context, Map<String, Object> options) =>
_processor.configure(context, options);
/// `analyzer` analysis options constants.
@@ -47,6 +50,10 @@
/// Ways to say `ignore`.
static const List<String> ignoreSynonyms = const ['ignore', 'false'];
+ /// Valid error `severity`s.
+ static final List<String> severities =
+ ErrorSeverity.values.map((s) => s.name).toList();
+
/// Ways to say `include`.
static const List<String> includeSynonyms = const ['include', 'true'];
@@ -126,9 +133,20 @@
new List.from(AnalyzerOptions.ignoreSynonyms)
..addAll(AnalyzerOptions.includeSynonyms));
- bool recognizedErrorCode(String name) =>
- ErrorCode.values.any((ErrorCode code) => code.name == name) ||
- StaticInfo.names.contains(name);
+ /// Lazily populated set of error codes (hashed for speedy lookup).
+ static HashSet<String> _errorCodes;
+
+ /// Legal error code names.
+ static Set<String> get errorCodes {
+ if (_errorCodes == null) {
+ _errorCodes = new HashSet<String>();
+ // Engine codes.
+ _errorCodes.addAll(ErrorCode.values.map((ErrorCode code) => code.name));
+ // Strong-mode codes.
+ _errorCodes.addAll(StaticInfo.names);
+ }
+ return _errorCodes;
+ }
@override
void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
@@ -143,7 +161,7 @@
filters.nodes.forEach((k, v) {
if (k is YamlScalar) {
value = toUpperCase(k.value);
- if (!recognizedErrorCode(value)) {
+ if (!errorCodes.contains(value)) {
reporter.reportErrorForSpan(
AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE,
k.span,
@@ -371,9 +389,13 @@
}
class _OptionsProcessor {
- void configure(AnalysisContext context, Map<String, YamlNode> options) {
+ static final Map<String, Object> defaults = {'analyzer': {}};
+
+ /// Configure [context] based on the given [options] (which can be `null`
+ /// to restore [defaults]).
+ void configure(AnalysisContext context, Map<String, Object> options) {
if (options == null) {
- return;
+ options = defaults;
}
var analyzer = options[AnalyzerOptions.analyzer];
@@ -387,33 +409,13 @@
// Set filters.
var filters = analyzer[AnalyzerOptions.errors];
- setFilters(context, filters);
+ setProcessors(context, filters);
// Process language options.
var language = analyzer[AnalyzerOptions.language];
setLanguageOptions(context, language);
}
- void setFilters(AnalysisContext context, Object codes) {
- List<ErrorFilter> filters = <ErrorFilter>[];
- // If codes are enumerated, collect them as filters; else leave filters
- // empty to overwrite previous value.
- if (codes is YamlMap) {
- String value;
- codes.nodes.forEach((k, v) {
- if (k is YamlScalar && v is YamlScalar) {
- value = toLowerCase(v.value);
- if (AnalyzerOptions.ignoreSynonyms.contains(value)) {
- // Case-insensitive.
- String code = toUpperCase(k.value);
- filters.add((AnalysisError error) => error.errorCode.name == code);
- }
- }
- });
- }
- context.setConfigurationData(CONFIGURED_ERROR_FILTERS, filters);
- }
-
void setLanguageOption(
AnalysisContext context, Object feature, Object value) {
if (feature == AnalyzerOptions.enableSuperMixins) {
@@ -447,6 +449,11 @@
}
}
+ void setProcessors(AnalysisContext context, Object codes) {
+ ErrorConfig config = new ErrorConfig(codes);
+ context.setConfigurationData(CONFIGURED_ERROR_PROCESSORS, config.processors);
+ }
+
void setStrongMode(AnalysisContext context, Object strongMode) {
bool strong = strongMode is bool ? strongMode : false;
if (context.analysisOptions.strongMode != strong) {
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index d557eb2..5004368 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -9,20 +9,21 @@
import 'package:analyzer/analyzer.dart';
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType;
+import 'package:analyzer/src/generated/type_system.dart';
import 'info.dart';
-import 'rules.dart';
/// Checks for overriding declarations of fields and methods. This is used to
/// check overrides between classes and superclasses, interfaces, and mixin
/// applications.
class _OverrideChecker {
bool _failure = false;
- final TypeRules _rules;
+ final StrongTypeSystemImpl rules;
final AnalysisErrorListener _reporter;
- _OverrideChecker(this._rules, this._reporter);
+ _OverrideChecker(this.rules, this._reporter);
void check(ClassDeclaration node) {
if (node.element.type.isObject) return;
@@ -299,7 +300,7 @@
AstNode node, AstNode errorLocation, bool isSubclass) {
assert(!element.isStatic);
- FunctionType subType = _rules.elementType(element);
+ FunctionType subType = _elementType(element);
// TODO(vsm): Test for generic
FunctionType baseType = _getMemberType(type, element);
if (baseType == null) return false;
@@ -313,8 +314,8 @@
errorLocation, element, type, subType, baseType));
}
}
- if (!_rules.isAssignable(subType, baseType)) {
- // See whether non-assignable cases fit one of our common patterns:
+ if (!rules.isSubtypeOf(subType, baseType)) {
+ // See whether non-subtype cases fit one of our common patterns:
//
// Common pattern 1: Inferable return type (on getters and methods)
// class A {
@@ -341,7 +342,8 @@
/// Checks the body of functions and properties.
class CodeChecker extends RecursiveAstVisitor {
- final TypeRules rules;
+ final StrongTypeSystemImpl rules;
+ final TypeProvider typeProvider;
final AnalysisErrorListener reporter;
final _OverrideChecker _overrideChecker;
final bool _hints;
@@ -354,7 +356,7 @@
_overrideChecker._failure = false;
}
- CodeChecker(TypeRules rules, AnalysisErrorListener reporter,
+ CodeChecker(this.typeProvider, StrongTypeSystemImpl rules, AnalysisErrorListener reporter,
{bool hints: false})
: rules = rules,
reporter = reporter,
@@ -403,7 +405,7 @@
void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
var field = node.fieldName;
var element = field.staticElement;
- DartType staticType = rules.elementType(element);
+ DartType staticType = _elementType(element);
checkAssignment(node.expression, staticType);
node.visitChildren(this);
}
@@ -413,8 +415,8 @@
// Check that the expression is an Iterable.
var expr = node.iterable;
var iterableType = node.awaitKeyword != null
- ? rules.provider.streamType
- : rules.provider.iterableType;
+ ? typeProvider.streamType
+ : typeProvider.iterableType;
var loopVariable = node.identifier != null
? node.identifier
: node.loopVariable?.identifier;
@@ -463,7 +465,7 @@
@override
void visitListLiteral(ListLiteral node) {
- var type = rules.provider.dynamicType;
+ var type = DynamicTypeImpl.instance;
if (node.typeArguments != null) {
var targs = node.typeArguments.arguments;
if (targs.length > 0) type = targs[0].type;
@@ -481,8 +483,8 @@
@override
void visitMapLiteral(MapLiteral node) {
- var ktype = rules.provider.dynamicType;
- var vtype = rules.provider.dynamicType;
+ var ktype = DynamicTypeImpl.instance;
+ var vtype = DynamicTypeImpl.instance;
if (node.typeArguments != null) {
var targs = node.typeArguments.arguments;
if (targs.length > 0) ktype = targs[0].type;
@@ -521,8 +523,8 @@
// TODO(vsm): When can this happen?
assert(element != null);
}
- DartType expectedType = rules.elementType(element);
- if (expectedType == null) expectedType = rules.provider.dynamicType;
+ DartType expectedType = _elementType(element);
+ if (expectedType == null) expectedType = DynamicTypeImpl.instance;
checkArgument(arg, expectedType);
}
}
@@ -538,19 +540,19 @@
void checkFunctionApplication(
Expression node, Expression f, ArgumentList list) {
- if (rules.isDynamicCall(f)) {
+ if (_isDynamicCall(f)) {
// If f is Function and this is a method invocation, we should have
// gotten an analyzer error, so no need to issue another error.
_recordDynamicInvoke(node, f);
} else {
- checkArgumentList(list, rules.getTypeAsCaller(f));
+ checkArgumentList(list, _getTypeAsCaller(f));
}
}
@override
visitMethodInvocation(MethodInvocation node) {
var target = node.realTarget;
- if (rules.isDynamicTarget(target) &&
+ if (_isDynamicTarget(target) &&
!_isObjectMethod(node, node.methodName)) {
_recordDynamicInvoke(node, target);
@@ -606,15 +608,15 @@
void _checkReturnOrYield(Expression expression, AstNode node,
{bool yieldStar: false}) {
var body = node.getAncestor((n) => n is FunctionBody);
- var type = rules.getExpectedReturnType(body, yieldStar: yieldStar);
+ var type = _getExpectedReturnType(body, yieldStar: yieldStar);
if (type == null) {
// We have a type mismatch: the async/async*/sync* modifier does
// not match the return or yield type. We should have already gotten an
// analyzer error in this case.
return;
}
- InterfaceType futureType = rules.provider.futureType;
- DartType actualType = expression.staticType;
+ InterfaceType futureType = typeProvider.futureType;
+ DartType actualType = expression?.staticType;
if (body.isAsynchronous &&
!body.isGenerator &&
actualType is InterfaceType &&
@@ -625,6 +627,59 @@
if (expression != null) checkAssignment(expression, type);
}
+ /// Gets the expected return type of the given function [body], either from
+ /// a normal return/yield, or from a yield*.
+ DartType _getExpectedReturnType(FunctionBody body, {bool yieldStar: false}) {
+ FunctionType functionType;
+ var parent = body.parent;
+ if (parent is Declaration) {
+ functionType = _elementType(parent.element);
+ } else {
+ assert(parent is FunctionExpression);
+ functionType = parent.staticType ?? DynamicTypeImpl.instance;
+ }
+
+ var type = functionType.returnType;
+
+ InterfaceType expectedType = null;
+ if (body.isAsynchronous) {
+ if (body.isGenerator) {
+ // Stream<T> -> T
+ expectedType = typeProvider.streamType;
+ } else {
+ // Future<T> -> T
+ // TODO(vsm): Revisit with issue #228.
+ expectedType = typeProvider.futureType;
+ }
+ } else {
+ if (body.isGenerator) {
+ // Iterable<T> -> T
+ expectedType = typeProvider.iterableType;
+ } else {
+ // T -> T
+ return type;
+ }
+ }
+ if (yieldStar) {
+ if (type.isDynamic) {
+ // Ensure it's at least a Stream / Iterable.
+ return expectedType.substitute4([typeProvider.dynamicType]);
+ } else {
+ // Analyzer will provide a separate error if expected type
+ // is not compatible with type.
+ return type;
+ }
+ }
+ if (type.isDynamic) {
+ return type;
+ } else if (type is InterfaceType && type.element == expectedType.element) {
+ return type.typeArguments[0];
+ } else {
+ // Malformed type - fallback on analyzer error.
+ return null;
+ }
+ }
+
@override
void visitExpressionFunctionBody(ExpressionFunctionBody node) {
_checkReturnOrYield(node.expression, node);
@@ -644,7 +699,7 @@
}
void _checkFieldAccess(AstNode node, AstNode target, SimpleIdentifier field) {
- if ((rules.isDynamicTarget(target) || field.staticElement == null) &&
+ if ((_isDynamicTarget(target) || field.staticElement == null) &&
!_isObjectProperty(target, field)) {
_recordDynamicInvoke(node, target);
}
@@ -665,7 +720,7 @@
void visitDefaultFormalParameter(DefaultFormalParameter node) {
// Check that defaults have the proper subtype.
var parameter = node.parameter;
- var parameterType = rules.elementType(parameter.element);
+ var parameterType = _elementType(parameter.element);
assert(parameterType != null);
var defaultValue = node.defaultValue;
if (defaultValue != null) {
@@ -680,11 +735,11 @@
var element = node.element;
var typeName = node.type;
if (typeName != null) {
- var type = rules.elementType(element);
+ var type = _elementType(element);
var fieldElement =
node.identifier.staticElement as FieldFormalParameterElement;
- var fieldType = rules.elementType(fieldElement.field);
- if (!rules.isSubTypeOf(type, fieldType)) {
+ var fieldType = _elementType(fieldElement.field);
+ if (!rules.isSubtypeOf(type, fieldType)) {
var staticInfo =
new InvalidParameterDeclaration(rules, node, fieldType);
_recordMessage(staticInfo);
@@ -698,7 +753,7 @@
var arguments = node.argumentList;
var element = node.staticElement;
if (element != null) {
- var type = rules.elementType(node.staticElement);
+ var type = _elementType(node.staticElement);
checkArgumentList(arguments, type);
}
node.visitChildren(this);
@@ -765,7 +820,7 @@
if (op.isUserDefinableOperator ||
op.type == TokenType.PLUS_PLUS ||
op.type == TokenType.MINUS_MINUS) {
- if (rules.isDynamicTarget(node.operand)) {
+ if (_isDynamicTarget(node.operand)) {
_recordDynamicInvoke(node, node.operand);
}
// For ++ and --, even if it is not dynamic, we still need to check
@@ -778,7 +833,7 @@
void visitBinaryExpression(BinaryExpression node) {
var op = node.operator;
if (op.isUserDefinableOperator) {
- if (rules.isDynamicTarget(node.leftOperand)) {
+ if (_isDynamicTarget(node.leftOperand)) {
// Dynamic invocation
// TODO(vsm): Move this logic to the resolver?
if (op.type != TokenType.EQ_EQ && op.type != TokenType.BANG_EQ) {
@@ -826,7 +881,7 @@
@override
void visitIndexExpression(IndexExpression node) {
var target = node.realTarget;
- if (rules.isDynamicTarget(target)) {
+ if (_isDynamicTarget(target)) {
_recordDynamicInvoke(node, target);
} else {
var element = node.staticElement;
@@ -845,23 +900,94 @@
}
DartType getType(TypeName name) {
- return (name == null) ? rules.provider.dynamicType : name.type;
+ return (name == null) ? DynamicTypeImpl.instance : name.type;
}
/// Analyzer checks boolean conversions, but we need to check too, because
/// it uses the default assignability rules that allow `dynamic` and `Object`
/// to be assigned to bool with no message.
void checkBoolean(Expression expr) =>
- checkAssignment(expr, rules.provider.boolType);
+ checkAssignment(expr, typeProvider.boolType);
void checkAssignment(Expression expr, DartType type) {
if (expr is ParenthesizedExpression) {
checkAssignment(expr.expression, type);
} else {
- _recordMessage(rules.checkAssignment(expr, type));
+ _recordMessage(_checkAssignment(expr, type));
}
}
+ StaticInfo _checkAssignment(Expression expr, DartType toT) {
+ final fromT = expr.staticType ?? DynamicTypeImpl.instance;
+ final Coercion c = _coerceTo(fromT, toT);
+ if (c is Identity) return null;
+ if (c is CoercionError) return new StaticTypeError(rules, expr, toT);
+ var reason = null;
+
+ var errors = <String>[];
+
+ var ok = _inferExpression(expr, toT, errors);
+ if (ok) return InferredType.create(rules, expr, toT);
+ reason = (errors.isNotEmpty) ? errors.first : null;
+
+ if (c is Cast) return DownCast.create(rules, expr, c, reason: reason);
+ assert(false);
+ return null;
+ }
+
+ /// Checks if we can perform downwards inference on [e] tp get type [t].
+ /// If it is not possible, this will add a message to [errors].
+ bool _inferExpression(Expression e, DartType t, List<String> errors) {
+ DartType staticType = e.staticType ?? DynamicTypeImpl.instance;
+ if (rules.isSubtypeOf(staticType, t)) {
+ return true;
+ }
+ errors.add("$e cannot be typed as $t");
+ return false;
+ }
+
+ // Produce a coercion which coerces something of type fromT
+ // to something of type toT.
+ // Returns the error coercion if the types cannot be coerced
+ // according to our current criteria.
+ Coercion _coerceTo(DartType fromT, DartType toT) {
+ // We can use anything as void
+ if (toT.isVoid) return Coercion.identity(toT);
+
+ // fromT <: toT, no coercion needed
+ if (rules.isSubtypeOf(fromT, toT)) return Coercion.identity(toT);
+
+ // TODO(vsm): We can get rid of the second clause if we disallow
+ // all sideways casts - see TODO below.
+ // -------
+ // Note: a function type is never assignable to a class per the Dart
+ // spec - even if it has a compatible call method. We disallow as
+ // well for consistency.
+ if ((fromT is FunctionType && rules.getCallMethodType(toT) != null) ||
+ (toT is FunctionType && rules.getCallMethodType(fromT) != null)) {
+ return Coercion.error();
+ }
+
+ // Downcast if toT <: fromT
+ if (rules.isSubtypeOf(toT, fromT)) return Coercion.cast(fromT, toT);
+
+ // TODO(vsm): Once we have generic methods, we should delete this
+ // workaround. These sideways casts are always ones we warn about
+ // - i.e., we think they are likely to fail at runtime.
+ // -------
+ // Downcast if toT <===> fromT
+ // The intention here is to allow casts that are sideways in the restricted
+ // type system, but allowed in the regular dart type system, since these
+ // are likely to succeed. The canonical example is List<dynamic> and
+ // Iterable<T> for some concrete T (e.g. Object). These are unrelated
+ // in the restricted system, but List<dynamic> <: Iterable<T> in dart.
+ if (fromT.isAssignableTo(toT)) {
+ return Coercion.cast(fromT, toT);
+ }
+
+ return Coercion.error();
+ }
+
DartType _specializedBinaryReturnType(
TokenType op, DartType t1, DartType t2, DartType normalReturnType) {
// This special cases binary return types as per 16.26 and 16.27 of the
@@ -877,14 +1003,14 @@
case TokenType.STAR_EQ:
case TokenType.TILDE_SLASH_EQ:
case TokenType.PERCENT_EQ:
- if (t1 == rules.provider.intType &&
- t2 == rules.provider.intType) return t1;
- if (t1 == rules.provider.doubleType &&
- t2 == rules.provider.doubleType) return t1;
+ if (t1 == typeProvider.intType &&
+ t2 == typeProvider.intType) return t1;
+ if (t1 == typeProvider.doubleType &&
+ t2 == typeProvider.doubleType) return t1;
// This particular combo is not spelled out in the spec, but all
// implementations and analyzer seem to follow this.
- if (t1 == rules.provider.doubleType &&
- t2 == rules.provider.intType) return t1;
+ if (t1 == typeProvider.doubleType &&
+ t2 == typeProvider.intType) return t1;
}
return normalReturnType;
}
@@ -912,11 +1038,11 @@
var returnType = _specializedBinaryReturnType(
op, lhsType, rhsType, functionType.returnType);
- if (!rules.isSubTypeOf(returnType, lhsType)) {
- final numType = rules.provider.numType;
+ if (!rules.isSubtypeOf(returnType, lhsType)) {
+ final numType = typeProvider.numType;
// Try to fix up the numerical case if possible.
- if (rules.isSubTypeOf(lhsType, numType) &&
- rules.isSubTypeOf(lhsType, rhsType)) {
+ if (rules.isSubtypeOf(lhsType, numType) &&
+ rules.isSubtypeOf(lhsType, rhsType)) {
// This is also slightly different from spec, but allows us to keep
// compound operators in the int += num and num += dynamic cases.
staticInfo = DownCast.create(
@@ -932,7 +1058,7 @@
// Check the rhs type
if (staticInfo is! CoercionInfo) {
var paramType = paramTypes.first;
- staticInfo = rules.checkAssignment(expr.rightHandSide, paramType);
+ staticInfo = _checkAssignment(expr.rightHandSide, paramType);
_recordMessage(staticInfo);
}
}
@@ -940,13 +1066,13 @@
bool _isObjectGetter(Expression target, SimpleIdentifier id) {
PropertyAccessorElement element =
- rules.provider.objectType.element.getGetter(id.name);
+ typeProvider.objectType.element.getGetter(id.name);
return (element != null && !element.isStatic);
}
bool _isObjectMethod(Expression target, SimpleIdentifier id) {
MethodElement element =
- rules.provider.objectType.element.getMethod(id.name);
+ typeProvider.objectType.element.getMethod(id.name);
return (element != null && !element.isStatic);
}
@@ -955,7 +1081,7 @@
}
DartType _getStaticType(Expression expr) {
- return expr.staticType ?? rules.provider.dynamicType;
+ return expr.staticType ?? DynamicTypeImpl.instance;
}
void _recordDynamicInvoke(AstNode node, AstNode target) {
@@ -986,6 +1112,58 @@
CoercionInfo.set(info.node, info);
}
}
+
+ bool _isLibraryPrefix(Expression node) =>
+ node is SimpleIdentifier && node.staticElement is PrefixElement;
+
+ /// Returns `true` if the target expression is dynamic.
+ bool _isDynamicTarget(Expression node) {
+ if (node == null) return false;
+
+ if (_isLibraryPrefix(node)) return false;
+
+ // Null type happens when we have unknown identifiers, like a dart: import
+ // that doesn't resolve.
+ var type = node.staticType;
+ return type == null || type.isDynamic;
+ }
+
+ /// Returns `true` if the expression is a dynamic function call or method
+ /// invocation.
+ bool _isDynamicCall(Expression call) {
+ var ft = _getTypeAsCaller(call);
+ // TODO(leafp): This will currently return true if t is Function
+ // This is probably the most correct thing to do for now, since
+ // this code is also used by the back end. Maybe revisit at some
+ // point?
+ if (ft == null) return true;
+ // Dynamic as the parameter type is treated as bottom. A function with
+ // a dynamic parameter type requires a dynamic call in general.
+ // However, as an optimization, if we have an original definition, we know
+ // dynamic is reified as Object - in this case a regular call is fine.
+ if (call is SimpleIdentifier) {
+ var element = call.staticElement;
+ if (element is FunctionElement || element is MethodElement) {
+ // An original declaration.
+ return false;
+ }
+ }
+
+ return rules.anyParameterType(ft, (pt) => pt.isDynamic);
+ }
+
+ /// Given an expression, return its type assuming it is
+ /// in the caller position of a call (that is, accounting
+ /// for the possibility of a call method). Returns null
+ /// if expression is not statically callable.
+ FunctionType _getTypeAsCaller(Expression applicand) {
+ var t = applicand.staticType ?? DynamicTypeImpl.instance;
+ if (t is InterfaceType) {
+ return rules.getCallMethodType(t);
+ }
+ if (t is FunctionType) return t;
+ return null;
+ }
}
// Return the field on type corresponding to member, or null if none
@@ -1054,6 +1232,14 @@
if (baseMethod == null || baseMethod.isStatic) return null;
return baseMethod.type;
}
- ;
return f;
}
+
+
+DartType _elementType(Element e) {
+ if (e == null) {
+ // Malformed code - just return dynamic.
+ return DynamicTypeImpl.instance;
+ }
+ return (e as dynamic).type;
+}
diff --git a/pkg/analyzer/lib/src/task/strong/info.dart b/pkg/analyzer/lib/src/task/strong/info.dart
index dbdc4e0..8b37962 100644
--- a/pkg/analyzer/lib/src/task/strong/info.dart
+++ b/pkg/analyzer/lib/src/task/strong/info.dart
@@ -11,15 +11,14 @@
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/error.dart';
-
-import 'rules.dart';
+import 'package:analyzer/src/generated/type_system.dart';
// A down cast due to a variable declaration to a ground type. E.g.,
// T x = expr;
// where T is ground. We exclude non-ground types as these behave differently
// compared to standard Dart.
class AssignmentCast extends DownCast {
- AssignmentCast(TypeRules rules, Expression expression, Cast cast)
+ AssignmentCast(TypeSystem rules, Expression expression, Cast cast)
: super._internal(rules, expression, cast);
@override
@@ -56,13 +55,13 @@
abstract class CoercionInfo extends StaticInfo {
static const String _propertyName = 'dev_compiler.src.info.CoercionInfo';
- final TypeRules rules;
+ final TypeSystem rules;
final Expression node;
CoercionInfo(this.rules, this.node);
- DartType get baseType => rules.getStaticType(node);
+ DartType get baseType => node.staticType ?? DynamicTypeImpl.instance;
DartType get convertedType;
String get message;
@@ -84,7 +83,8 @@
abstract class DownCast extends CoercionInfo {
Cast _cast;
- DownCast._internal(TypeRules rules, Expression expression, this._cast)
+ DownCast._internal(
+ TypeSystem rules, Expression expression, this._cast)
: super(rules, expression) {
assert(_cast.toType != baseType &&
_cast.fromType == baseType &&
@@ -103,7 +103,8 @@
'to cast to type {2}';
// Factory to create correct DownCast variant.
- static StaticInfo create(TypeRules rules, Expression expression, Cast cast,
+ static StaticInfo create(
+ StrongTypeSystemImpl rules, Expression expression, Cast cast,
{String reason}) {
final fromT = cast.fromType;
final toT = cast.toType;
@@ -138,7 +139,7 @@
// TODO(vsm): Change this to an assert when we have generic methods and
// fix TypeRules._coerceTo to disallow implicit sideways casts.
- if (!rules.isSubTypeOf(toT, fromT)) {
+ if (!rules.isSubtypeOf(toT, fromT)) {
assert(toT.isSubtypeOf(fromT) || fromT.isAssignableTo(toT));
return new DownCastComposite(rules, expression, cast);
}
@@ -182,7 +183,8 @@
// A down cast to a non-ground type. These behave differently from standard
// Dart and may be more likely to fail at runtime.
class DownCastComposite extends DownCast {
- DownCastComposite(TypeRules rules, Expression expression, Cast cast)
+ DownCastComposite(
+ TypeSystem rules, Expression expression, Cast cast)
: super._internal(rules, expression, cast);
@override
@@ -194,7 +196,7 @@
// A down cast to a non-ground type. These behave differently from standard
// Dart and may be more likely to fail at runtime.
class DownCastImplicit extends DownCast {
- DownCastImplicit(TypeRules rules, Expression expression, Cast cast)
+ DownCastImplicit(TypeSystem rules, Expression expression, Cast cast)
: super._internal(rules, expression, cast);
@override
@@ -205,7 +207,7 @@
// A down cast from dynamic to T.
class DynamicCast extends DownCast {
- DynamicCast(TypeRules rules, Expression expression, Cast cast)
+ DynamicCast(TypeSystem rules, Expression expression, Cast cast)
: super._internal(rules, expression, cast);
@override
@@ -217,9 +219,9 @@
class DynamicInvoke extends CoercionInfo {
static const String _propertyName = 'dev_compiler.src.info.DynamicInvoke';
- DynamicInvoke(TypeRules rules, Expression expression)
+ DynamicInvoke(TypeSystem rules, Expression expression)
: super(rules, expression);
- DartType get convertedType => rules.provider.dynamicType;
+ DartType get convertedType => DynamicTypeImpl.instance;
String get message => '{0} requires dynamic invoke';
@override
@@ -249,7 +251,7 @@
// Standard / unspecialized inferred type
class InferredType extends InferredTypeBase {
- InferredType(TypeRules rules, Expression expression, DartType type)
+ InferredType(TypeSystem rules, Expression expression, DartType type)
: super._internal(rules, expression, type);
@override
@@ -257,7 +259,7 @@
// Factory to create correct InferredType variant.
static InferredTypeBase create(
- TypeRules rules, Expression expression, DartType type) {
+ TypeSystem rules, Expression expression, DartType type) {
// Specialized inference:
if (expression is Literal) {
return new InferredTypeLiteral(rules, expression, type);
@@ -274,7 +276,8 @@
// An inferred type for a non-literal allocation site.
class InferredTypeAllocation extends InferredTypeBase {
- InferredTypeAllocation(TypeRules rules, Expression expression, DartType type)
+ InferredTypeAllocation(
+ TypeSystem rules, Expression expression, DartType type)
: super._internal(rules, expression, type);
@override
@@ -286,7 +289,8 @@
abstract class InferredTypeBase extends CoercionInfo {
final DartType _type;
- InferredTypeBase._internal(TypeRules rules, Expression expression, this._type)
+ InferredTypeBase._internal(
+ TypeSystem rules, Expression expression, this._type)
: super(rules, expression);
@override List get arguments => [node, type];
@@ -299,7 +303,8 @@
// An inferred type for a closure expression
class InferredTypeClosure extends InferredTypeBase {
- InferredTypeClosure(TypeRules rules, Expression expression, DartType type)
+ InferredTypeClosure(
+ TypeSystem rules, Expression expression, DartType type)
: super._internal(rules, expression, type);
@override
@@ -308,7 +313,8 @@
// An inferred type for a literal expression.
class InferredTypeLiteral extends InferredTypeBase {
- InferredTypeLiteral(TypeRules rules, Expression expression, DartType type)
+ InferredTypeLiteral(
+ TypeSystem rules, Expression expression, DartType type)
: super._internal(rules, expression, type);
@override
@@ -385,8 +391,8 @@
class InvalidParameterDeclaration extends StaticError {
final DartType expectedType;
- InvalidParameterDeclaration(
- TypeRules rules, FormalParameter declaration, this.expectedType)
+ InvalidParameterDeclaration(TypeSystem rules,
+ FormalParameter declaration, this.expectedType)
: super(declaration);
@override List<Object> get arguments => [node, expectedType];
@@ -438,7 +444,7 @@
final DartType expectedType;
InvalidVariableDeclaration(
- TypeRules rules, AstNode declaration, this.expectedType)
+ TypeSystem rules, AstNode declaration, this.expectedType)
: super(declaration);
@override List<Object> get arguments => [expectedType];
@@ -533,9 +539,10 @@
final DartType expectedType;
String reason = null;
- StaticTypeError(TypeRules rules, Expression expression, this.expectedType,
+ StaticTypeError(
+ TypeSystem rules, Expression expression, this.expectedType,
{this.reason})
- : baseType = rules.getStaticType(expression),
+ : baseType = expression.staticType ?? DynamicTypeImpl.instance,
super(expression);
@override List<Object> get arguments => [node, baseType, expectedType];
@@ -558,7 +565,8 @@
//
// TODO(vsm,leafp): Remove this.
class UninferredClosure extends DownCast {
- UninferredClosure(TypeRules rules, FunctionExpression expression, Cast cast)
+ UninferredClosure(
+ TypeSystem rules, FunctionExpression expression, Cast cast)
: super._internal(rules, expression, cast);
@override
diff --git a/pkg/analyzer/lib/src/task/strong/rules.dart b/pkg/analyzer/lib/src/task/strong/rules.dart
deleted file mode 100644
index 909a6fb..0000000
--- a/pkg/analyzer/lib/src/task/strong/rules.dart
+++ /dev/null
@@ -1,524 +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.
-
-// TODO(jmesserly): this was ported from package:dev_compiler, and needs to be
-// refactored to fit into analyzer.
-library analyzer.src.task.strong.rules;
-
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-
-import 'info.dart';
-
-// TODO(jmesserly): this entire file needs to be removed in favor of TypeSystem.
-
-final _objectMap = new Expando('providerToObjectMap');
-Map<String, DartType> getObjectMemberMap(TypeProvider typeProvider) {
- var map = _objectMap[typeProvider] as Map<String, DartType>;
- if (map == null) {
- map = <String, DartType>{};
- _objectMap[typeProvider] = map;
- var objectType = typeProvider.objectType;
- var element = objectType.element;
- // Only record methods (including getters) with no parameters. As parameters are contravariant wrt
- // type, using Object's version may be too strict.
- // Add instance methods.
- element.methods.where((method) => !method.isStatic).forEach((method) {
- map[method.name] = method.type;
- });
- // Add getters.
- element.accessors
- .where((member) => !member.isStatic && member.isGetter)
- .forEach((member) {
- map[member.name] = member.type.returnType;
- });
- }
- return map;
-}
-
-class TypeRules {
- final TypeProvider provider;
-
- /// Map of fields / properties / methods on Object.
- final Map<String, DartType> objectMembers;
-
- DownwardsInference inferrer;
-
- TypeRules(TypeProvider provider)
- : provider = provider,
- objectMembers = getObjectMemberMap(provider) {
- inferrer = new DownwardsInference(this);
- }
-
- /// Given a type t, if t is an interface type with a call method
- /// defined, return the function type for the call method, otherwise
- /// return null.
- FunctionType getCallMethodType(DartType t) {
- if (t is InterfaceType) {
- return t.lookUpMethod("call", null)?.type;
- }
- return null;
- }
-
- /// Given an expression, return its type assuming it is
- /// in the caller position of a call (that is, accounting
- /// for the possibility of a call method). Returns null
- /// if expression is not statically callable.
- FunctionType getTypeAsCaller(Expression applicand) {
- var t = getStaticType(applicand);
- if (t is InterfaceType) {
- return getCallMethodType(t);
- }
- if (t is FunctionType) return t;
- return null;
- }
-
- /// Gets the expected return type of the given function [body], either from
- /// a normal return/yield, or from a yield*.
- DartType getExpectedReturnType(FunctionBody body, {bool yieldStar: false}) {
- FunctionType functionType;
- var parent = body.parent;
- if (parent is Declaration) {
- functionType = elementType(parent.element);
- } else {
- assert(parent is FunctionExpression);
- functionType = getStaticType(parent);
- }
-
- var type = functionType.returnType;
-
- InterfaceType expectedType = null;
- if (body.isAsynchronous) {
- if (body.isGenerator) {
- // Stream<T> -> T
- expectedType = provider.streamType;
- } else {
- // Future<T> -> T
- // TODO(vsm): Revisit with issue #228.
- expectedType = provider.futureType;
- }
- } else {
- if (body.isGenerator) {
- // Iterable<T> -> T
- expectedType = provider.iterableType;
- } else {
- // T -> T
- return type;
- }
- }
- if (yieldStar) {
- if (type.isDynamic) {
- // Ensure it's at least a Stream / Iterable.
- return expectedType.substitute4([provider.dynamicType]);
- } else {
- // Analyzer will provide a separate error if expected type
- // is not compatible with type.
- return type;
- }
- }
- if (type.isDynamic) {
- return type;
- } else if (type is InterfaceType && type.element == expectedType.element) {
- return type.typeArguments[0];
- } else {
- // Malformed type - fallback on analyzer error.
- return null;
- }
- }
-
- DartType getStaticType(Expression expr) {
- return expr.staticType ?? provider.dynamicType;
- }
-
- bool _isBottom(DartType t, {bool dynamicIsBottom: false}) {
- if (t.isDynamic && dynamicIsBottom) return true;
- // TODO(vsm): We need direct support for non-nullability in DartType.
- // This should check on "true/nonnullable" Bottom
- if (t.isBottom) return true;
- return false;
- }
-
- bool _isTop(DartType t, {bool dynamicIsBottom: false}) {
- if (t.isDynamic && !dynamicIsBottom) return true;
- if (t.isObject) return true;
- return false;
- }
-
- bool _anyParameterType(FunctionType ft, bool predicate(DartType t)) {
- return ft.normalParameterTypes.any(predicate) ||
- ft.optionalParameterTypes.any(predicate) ||
- ft.namedParameterTypes.values.any(predicate);
- }
-
- // TODO(leafp): Revisit this.
- bool isGroundType(DartType t) {
- if (t is TypeParameterType) return false;
- if (_isTop(t)) return true;
-
- if (t is FunctionType) {
- if (!_isTop(t.returnType) ||
- _anyParameterType(t, (pt) => !_isBottom(pt, dynamicIsBottom: true))) {
- return false;
- } else {
- return true;
- }
- }
-
- if (t is InterfaceType) {
- var typeArguments = t.typeArguments;
- for (var typeArgument in typeArguments) {
- if (!_isTop(typeArgument)) return false;
- }
- return true;
- }
-
- // We should not see any other type aside from malformed code.
- return false;
- }
-
- /// Check that f1 is a subtype of f2. [ignoreReturn] is used in the DDC
- /// checker to determine whether f1 would be a subtype of f2 if the return
- /// type of f1 is set to match f2's return type.
- // [fuzzyArrows] indicates whether or not the f1 and f2 should be
- // treated as fuzzy arrow types (and hence dynamic parameters to f2 treated as
- // bottom).
- bool isFunctionSubTypeOf(FunctionType f1, FunctionType f2,
- {bool fuzzyArrows: true, bool ignoreReturn: false}) {
- final r1s = f1.normalParameterTypes;
- final o1s = f1.optionalParameterTypes;
- final n1s = f1.namedParameterTypes;
- final r2s = f2.normalParameterTypes;
- final o2s = f2.optionalParameterTypes;
- final n2s = f2.namedParameterTypes;
- final ret1 = ignoreReturn ? f2.returnType : f1.returnType;
- final ret2 = f2.returnType;
-
- // A -> B <: C -> D if C <: A and
- // either D is void or B <: D
- if (!ret2.isVoid && !isSubTypeOf(ret1, ret2)) return false;
-
- // Reject if one has named and the other has optional
- if (n1s.length > 0 && o2s.length > 0) return false;
- if (n2s.length > 0 && o1s.length > 0) return false;
-
- // f2 has named parameters
- if (n2s.length > 0) {
- // Check that every named parameter in f2 has a match in f1
- for (String k2 in n2s.keys) {
- if (!n1s.containsKey(k2)) return false;
- if (!isSubTypeOf(n2s[k2], n1s[k2],
- dynamicIsBottom: fuzzyArrows)) return false;
- }
- }
- // If we get here, we either have no named parameters,
- // or else the named parameters match and we have no optional
- // parameters
-
- // If f1 has more required parameters, reject
- if (r1s.length > r2s.length) return false;
-
- // If f2 has more required + optional parameters, reject
- if (r2s.length + o2s.length > r1s.length + o1s.length) return false;
-
- // The parameter lists must look like the following at this point
- // where rrr is a region of required, and ooo is a region of optionals.
- // f1: rrr ooo ooo ooo
- // f2: rrr rrr ooo
- int rr = r1s.length; // required in both
- int or = r2s.length - r1s.length; // optional in f1, required in f2
- int oo = o2s.length; // optional in both
-
- for (int i = 0; i < rr; ++i) {
- if (!isSubTypeOf(r2s[i], r1s[i],
- dynamicIsBottom: fuzzyArrows)) return false;
- }
- for (int i = 0, j = rr; i < or; ++i, ++j) {
- if (!isSubTypeOf(r2s[j], o1s[i],
- dynamicIsBottom: fuzzyArrows)) return false;
- }
- for (int i = or, j = 0; i < oo; ++i, ++j) {
- if (!isSubTypeOf(o2s[j], o1s[i],
- dynamicIsBottom: fuzzyArrows)) return false;
- }
- return true;
- }
-
- bool _isInterfaceSubTypeOf(InterfaceType i1, InterfaceType i2) {
- if (i1 == i2) return true;
-
- if (i1.element == i2.element) {
- List<DartType> tArgs1 = i1.typeArguments;
- List<DartType> tArgs2 = i2.typeArguments;
-
- // TODO(leafp): Verify that this is always true
- // Do raw types get filled in?
- assert(tArgs1.length == tArgs2.length);
-
- for (int i = 0; i < tArgs1.length; i++) {
- DartType t1 = tArgs1[i];
- DartType t2 = tArgs2[i];
- if (!isSubTypeOf(t1, t2)) return false;
- }
- return true;
- }
-
- if (i2.isDartCoreFunction) {
- if (i1.element.getMethod("call") != null) return true;
- }
-
- if (i1 == provider.objectType) return false;
-
- if (_isInterfaceSubTypeOf(i1.superclass, i2)) return true;
-
- for (final parent in i1.interfaces) {
- if (_isInterfaceSubTypeOf(parent, i2)) return true;
- }
-
- for (final parent in i1.mixins) {
- if (_isInterfaceSubTypeOf(parent, i2)) return true;
- }
-
- return false;
- }
-
- bool isSubTypeOf(DartType t1, DartType t2, {bool dynamicIsBottom: false}) {
- if (t1 == t2) return true;
-
- // Trivially true.
- if (_isTop(t2, dynamicIsBottom: dynamicIsBottom) ||
- _isBottom(t1, dynamicIsBottom: dynamicIsBottom)) {
- return true;
- }
-
- // Trivially false.
- if (_isTop(t1, dynamicIsBottom: dynamicIsBottom) ||
- _isBottom(t2, dynamicIsBottom: dynamicIsBottom)) {
- return false;
- }
-
- // The null type is a subtype of any nullable type, which is all Dart types.
- // TODO(vsm): Note, t1.isBottom still allows for null confusingly.
- // _isBottom(t1) does not necessarily imply t1.isBottom if there are
- // nonnullable types in the system.
- if (t1.isBottom) {
- return true;
- }
-
- // S <: T where S is a type variable
- // T is not dynamic or object (handled above)
- // S != T (handled above)
- // So only true if bound of S is S' and
- // S' <: T
- if (t1 is TypeParameterType) {
- DartType bound = t1.element.bound;
- if (bound == null) return false;
- return isSubTypeOf(bound, t2);
- }
-
- if (t2 is TypeParameterType) {
- return false;
- }
-
- if (t1.isVoid || t2.isVoid) {
- return false;
- }
-
- if (t2.isDartCoreFunction) {
- if (t1 is FunctionType) return true;
- if (t1.element is ClassElement) {
- if ((t1.element as ClassElement).getMethod("call") != null) return true;
- }
- }
-
- // "Traditional" name-based subtype check.
- if (t1 is InterfaceType && t2 is InterfaceType) {
- return _isInterfaceSubTypeOf(t1, t2);
- }
-
- if (t1 is! FunctionType && t2 is! FunctionType) return false;
-
- if (t1 is InterfaceType && t2 is FunctionType) {
- var callType = getCallMethodType(t1);
- if (callType == null) return false;
- return isFunctionSubTypeOf(callType, t2);
- }
-
- if (t1 is FunctionType && t2 is InterfaceType) {
- return false;
- }
-
- // Functions
- // Note: it appears under the hood all Dart functions map to a class /
- // hidden type that:
- // (a) subtypes Object (an internal _FunctionImpl in the VM)
- // (b) implements Function
- // (c) provides standard Object members (hashCode, toString)
- // (d) contains private members (corresponding to _FunctionImpl?)
- // (e) provides a call method to handle the actual function invocation
- //
- // The standard Dart subtyping rules are structural in nature. I.e.,
- // bivariant on arguments and return type.
- //
- // The below tries for a more traditional subtyping rule:
- // - covariant on return type
- // - contravariant on parameters
- // - 'sensible' (?) rules on optional and/or named params
- // but doesn't properly mix with class subtyping. I suspect Java 8 lambdas
- // essentially map to dynamic (and rely on invokedynamic) due to similar
- // issues.
- return isFunctionSubTypeOf(t1 as FunctionType, t2 as FunctionType);
- }
-
- bool isAssignable(DartType t1, DartType t2) {
- return isSubTypeOf(t1, t2);
- }
-
- // Produce a coercion which coerces something of type fromT
- // to something of type toT.
- // Returns the error coercion if the types cannot be coerced
- // according to our current criteria.
- Coercion _coerceTo(DartType fromT, DartType toT) {
- // We can use anything as void
- if (toT.isVoid) return Coercion.identity(toT);
-
- // fromT <: toT, no coercion needed
- if (isSubTypeOf(fromT, toT)) return Coercion.identity(toT);
-
- // TODO(vsm): We can get rid of the second clause if we disallow
- // all sideways casts - see TODO below.
- // -------
- // Note: a function type is never assignable to a class per the Dart
- // spec - even if it has a compatible call method. We disallow as
- // well for consistency.
- if ((fromT is FunctionType && getCallMethodType(toT) != null) ||
- (toT is FunctionType && getCallMethodType(fromT) != null)) {
- return Coercion.error();
- }
-
- // Downcast if toT <: fromT
- if (isSubTypeOf(toT, fromT)) return Coercion.cast(fromT, toT);
-
- // TODO(vsm): Once we have generic methods, we should delete this
- // workaround. These sideways casts are always ones we warn about
- // - i.e., we think they are likely to fail at runtime.
- // -------
- // Downcast if toT <===> fromT
- // The intention here is to allow casts that are sideways in the restricted
- // type system, but allowed in the regular dart type system, since these
- // are likely to succeed. The canonical example is List<dynamic> and
- // Iterable<T> for some concrete T (e.g. Object). These are unrelated
- // in the restricted system, but List<dynamic> <: Iterable<T> in dart.
- if (fromT.isAssignableTo(toT)) {
- return Coercion.cast(fromT, toT);
- }
-
- return Coercion.error();
- }
-
- StaticInfo checkAssignment(Expression expr, DartType toT) {
- final fromT = getStaticType(expr);
- final Coercion c = _coerceTo(fromT, toT);
- if (c is Identity) return null;
- if (c is CoercionError) return new StaticTypeError(this, expr, toT);
- var reason = null;
-
- var errors = <String>[];
-
- var ok = inferrer.inferExpression(expr, toT, errors);
- if (ok) return InferredType.create(this, expr, toT);
- reason = (errors.isNotEmpty) ? errors.first : null;
-
- if (c is Cast) return DownCast.create(this, expr, c, reason: reason);
- assert(false);
- return null;
- }
-
- DartType elementType(Element e) {
- if (e == null) {
- // Malformed code - just return dynamic.
- return provider.dynamicType;
- }
- return (e as dynamic).type;
- }
-
- bool _isLibraryPrefix(Expression node) =>
- node is SimpleIdentifier && node.staticElement is PrefixElement;
-
- /// Returns `true` if the target expression is dynamic.
- bool isDynamicTarget(Expression node) {
- if (node == null) return false;
-
- if (_isLibraryPrefix(node)) return false;
-
- // Null type happens when we have unknown identifiers, like a dart: import
- // that doesn't resolve.
- var type = node.staticType;
- return type == null || type.isDynamic;
- }
-
- /// Returns `true` if the expression is a dynamic function call or method
- /// invocation.
- bool isDynamicCall(Expression call) {
- var ft = getTypeAsCaller(call);
- // TODO(leafp): This will currently return true if t is Function
- // This is probably the most correct thing to do for now, since
- // this code is also used by the back end. Maybe revisit at some
- // point?
- if (ft == null) return true;
- // Dynamic as the parameter type is treated as bottom. A function with
- // a dynamic parameter type requires a dynamic call in general.
- // However, as an optimization, if we have an original definition, we know
- // dynamic is reified as Object - in this case a regular call is fine.
- if (call is SimpleIdentifier) {
- var element = call.staticElement;
- if (element is FunctionElement || element is MethodElement) {
- // An original declaration.
- return false;
- }
- }
-
- return _anyParameterType(ft, (pt) => pt.isDynamic);
- }
-}
-
-class DownwardsInference {
- final TypeRules rules;
-
- DownwardsInference(this.rules);
-
- /// Called for each list literal which gets inferred
- void annotateListLiteral(ListLiteral e, List<DartType> targs) {}
-
- /// Called for each map literal which gets inferred
- void annotateMapLiteral(MapLiteral e, List<DartType> targs) {}
-
- /// Called for each new/const which gets inferred
- void annotateInstanceCreationExpression(
- InstanceCreationExpression e, List<DartType> targs) {}
-
- /// Called for cast from dynamic required for inference to succeed
- void annotateCastFromDynamic(Expression e, DartType t) {}
-
- /// Called for each function expression return type inferred
- void annotateFunctionExpression(FunctionExpression e, DartType returnType) {}
-
- /// Downward inference
- bool inferExpression(Expression e, DartType t, List<String> errors) {
- // Don't cast top level expressions, only sub-expressions
- return _inferExpression(e, t, errors, cast: false);
- }
-
- /// Downward inference
- bool _inferExpression(Expression e, DartType t, List<String> errors,
- {cast: true}) {
- if (rules.isSubTypeOf(rules.getStaticType(e), t)) return true;
- if (cast && rules.getStaticType(e).isDynamic) {
- annotateCastFromDynamic(e, t);
- return true;
- }
- errors.add("$e cannot be typed as $t");
- return false;
- }
-}
diff --git a/pkg/analyzer/lib/src/util/absolute_path.dart b/pkg/analyzer/lib/src/util/absolute_path.dart
index f31935d..28f5732 100644
--- a/pkg/analyzer/lib/src/util/absolute_path.dart
+++ b/pkg/analyzer/lib/src/util/absolute_path.dart
@@ -4,18 +4,29 @@
library analyzer.src.util.absolute_path;
-/// The class for manipulating absolute paths.
+/// The class for manipulating absolute, normalized paths.
class AbsolutePathContext {
- final String separator;
+ static const int _COLON = 0x3A;
+ static const int _LOWER_A = 0x61;
+ static const int _LOWER_Z = 0x7A;
+ static const int _UPPER_A = 0x41;
+ static const int _UPPER_Z = 0x5A;
+ final bool _isWindows;
+ String separator;
int _separatorChar;
+ String _singlePeriodComponent;
+ String _doublePeriodComponent;
+ String _singlePeriodEnding;
+ String _doublePeriodEnding;
- AbsolutePathContext(this.separator) {
- if (separator.length != 1) {
- throw new ArgumentError.value(
- separator, 'separator', 'must be exactly one character long');
- }
+ AbsolutePathContext(this._isWindows) {
+ separator = _isWindows ? r'\' : '/';
_separatorChar = separator.codeUnitAt(0);
+ _singlePeriodComponent = separator + '.' + separator;
+ _doublePeriodComponent = separator + '..' + separator;
+ _singlePeriodEnding = separator + '.';
+ _doublePeriodEnding = separator + '..';
}
/// Append the given relative [suffix] to the given absolute [parent].
@@ -55,6 +66,14 @@
: path.substring(0, lastIndex);
}
+ /// Return `true` if the given [path] is valid.
+ ///
+ /// context.isNormalized('/foo/bar'); // -> true
+ /// context.isNormalized('/foo/bar/../baz'); // -> false
+ bool isValid(String path) {
+ return _isAbsolute(path) && _isNormalized(path);
+ }
+
/// Return `true` if [child] is a path beneath [parent], and `false`
/// otherwise. Both the [child] and [parent] paths must be absolute paths.
///
@@ -94,6 +113,47 @@
return null;
}
+ /// Return `true` if the given [path] is absolute.
+ ///
+ /// _isAbsolute('/foo/bar'); // -> true
+ /// _isAbsolute('/'); // -> true
+ /// _isAbsolute('foo/bar'); // -> false
+ /// _isAbsolute('C:\foo\bar'); // -> true
+ /// _isAbsolute('C:\'); // -> true
+ /// _isAbsolute('foo\bar'); // -> false
+ bool _isAbsolute(String path) {
+ if (_isWindows) {
+ return path.length >= 3 &&
+ _isAlphabetic(path.codeUnitAt(0)) &&
+ path.codeUnitAt(1) == _COLON &&
+ path.codeUnitAt(2) == _separatorChar;
+ } else {
+ return path.isNotEmpty && path.codeUnitAt(0) == _separatorChar;
+ }
+ }
+
+ /// Return `true` if the given absolute [path] is normalized.
+ ///
+ /// _isNormalized('/foo/bar'); // -> true
+ /// _isNormalized('/foo/..bar'); // -> true
+ /// _isNormalized('/foo/bar..'); // -> true
+ /// _isNormalized('/'); // -> true
+ /// _isNormalized('/foo/bar/../baz'); // -> false
+ /// _isNormalized('/foo/bar/..'); // -> false
+ bool _isNormalized(String path) {
+ return !path.contains(_singlePeriodComponent) &&
+ !path.contains(_doublePeriodComponent) &&
+ !path.endsWith(_singlePeriodEnding) &&
+ !path.endsWith(_doublePeriodEnding);
+ }
+
+ /// Returns whether [char] is the code for an ASCII letter (uppercase or
+ /// lowercase).
+ static bool _isAlphabetic(int char) {
+ return char >= _UPPER_A && char <= _UPPER_Z ||
+ char >= _LOWER_A && char <= _LOWER_Z;
+ }
+
/// Return `true` if [str] starts with the given [prefix].
///
/// The check is done from the end of [prefix], because absolute paths
diff --git a/pkg/analyzer/lib/src/util/asserts.dart b/pkg/analyzer/lib/src/util/asserts.dart
index a53e7e6..402f3bc 100644
--- a/pkg/analyzer/lib/src/util/asserts.dart
+++ b/pkg/analyzer/lib/src/util/asserts.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.utilities.asserts;
+library analyzer.src.util.asserts;
/**
* Ensures that the given [value] is not null.
diff --git a/pkg/analyzer/lib/src/util/lru_map.dart b/pkg/analyzer/lib/src/util/lru_map.dart
index 38ef8ff..716f7ab 100644
--- a/pkg/analyzer/lib/src/util/lru_map.dart
+++ b/pkg/analyzer/lib/src/util/lru_map.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.utilities.lru_cache;
+library analyzer.src.util.lru_cache;
import 'dart:collection';
diff --git a/pkg/analyzer/lib/src/util/utilities_timing.dart b/pkg/analyzer/lib/src/util/utilities_timing.dart
index 7b8e122..ebc42b7 100644
--- a/pkg/analyzer/lib/src/util/utilities_timing.dart
+++ b/pkg/analyzer/lib/src/util/utilities_timing.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.utilities.timing;
+library analyzer.src.util.utilities_timing;
/**
* A `CountedStopwatch` is a [Stopwatch] that counts the number of times the
diff --git a/pkg/analyzer/lib/task/model.dart b/pkg/analyzer/lib/task/model.dart
index c7d0c57..d0ec89d 100644
--- a/pkg/analyzer/lib/task/model.dart
+++ b/pkg/analyzer/lib/task/model.dart
@@ -337,8 +337,8 @@
* values associated with this result will remain in the cache.
*/
factory ListResultDescriptor(String name, List<E> defaultValue,
- {ResultCachingPolicy<List<E>> cachingPolicy}) = ListResultDescriptorImpl<
- E>;
+ {ResultCachingPolicy<List<E>> cachingPolicy}) =
+ ListResultDescriptorImpl<E>;
@override
ListTaskInput<E> of(AnalysisTarget target, {bool flushOnAccess: false});
@@ -355,35 +355,36 @@
* Return a task input that can be used to compute a flatten list whose
* elements are combined [subListResult]'s associated with those elements.
*/
- ListTaskInput /*<V>*/ toFlattenListOf(
+ ListTaskInput /*<V>*/ toFlattenListOf /*<V>*/ (
ListResultDescriptor /*<V>*/ subListResult);
/**
* Return a task input that can be used to compute a list whose elements are
* the result of passing the elements of this input to the [mapper] function.
*/
- ListTaskInput /*<V>*/ toList(UnaryFunction<E, dynamic /*<V>*/ > mapper);
+ ListTaskInput /*<V>*/ toList /*<V>*/ (
+ UnaryFunction<E, dynamic /*<=V>*/ > mapper);
/**
* Return a task input that can be used to compute a list whose elements are
* [valueResult]'s associated with those elements.
*/
- ListTaskInput /*<V>*/ toListOf(ResultDescriptor /*<V>*/ valueResult);
+ ListTaskInput /*<V>*/ toListOf /*<V>*/ (ResultDescriptor /*<V>*/ valueResult);
/**
* Return a task input that can be used to compute a map whose keys are the
* elements of this input and whose values are the result of passing the
* corresponding key to the [mapper] function.
*/
- MapTaskInput<E, dynamic /*V*/ > toMap(
- UnaryFunction<E, dynamic /*<V>*/ > mapper);
+ MapTaskInput<E, dynamic /*=V*/ > toMap /*<V>*/ (
+ UnaryFunction<E, dynamic /*=V*/ > mapper);
/**
* Return a task input that can be used to compute a map whose keys are the
* elements of this input and whose values are the [valueResult]'s associated
* with those elements.
*/
- MapTaskInput<AnalysisTarget, dynamic /*V*/ > toMapOf(
+ MapTaskInput<AnalysisTarget, dynamic /*=V*/ > toMapOf /*<V>*/ (
ResultDescriptor /*<V>*/ valueResult);
}
@@ -399,8 +400,8 @@
* the result of passing keys [K] and the corresponding elements of [V] to
* the [mapper] function.
*/
- TaskInput<List /*<E>*/ > toFlattenList(
- BinaryFunction<K, dynamic /*element of V*/, dynamic /*<E>*/ > mapper);
+ TaskInput<List /*<E>*/ > toFlattenList /*<E>*/ (
+ BinaryFunction<K, dynamic /*element of V*/, dynamic /*=E*/ > mapper);
}
/**
@@ -570,7 +571,7 @@
* Return a task input that can be used to compute a list whose elements are
* the result of passing the result of this input to the [mapper] function.
*/
- ListTaskInput /*<E>*/ mappedToList(List /*<E>*/ mapper(V value));
+ ListTaskInput /*<E>*/ mappedToList /*<E>*/ (List /*<E>*/ mapper(V value));
}
/**
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index a3c4b51..fab059e 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 0.26.3
+version: 0.27.0
author: Dart Team <misc@dartlang.org>
description: Static analyzer for Dart.
homepage: http://www.dartlang.org
diff --git a/pkg/analyzer/test/cancelable_future_test.dart b/pkg/analyzer/test/cancelable_future_test.dart
index b28c0f9..24c84ae 100644
--- a/pkg/analyzer/test/cancelable_future_test.dart
+++ b/pkg/analyzer/test/cancelable_future_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.cancelable_future;
+library analyzer.test.cancelable_future_test;
import 'dart:async';
diff --git a/pkg/analyzer/test/enum_test.dart b/pkg/analyzer/test/enum_test.dart
index 706737f..16d8f45 100644
--- a/pkg/analyzer/test/enum_test.dart
+++ b/pkg/analyzer/test/enum_test.dart
@@ -2,14 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.enums;
+library analyzer.test.enum_test;
import 'dart:mirrors';
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart' as html;
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -69,12 +68,6 @@
..check_explicit_values();
}
- void test_html_TokenType() {
- new EnumTester<html.TokenType>()
- ..check_getters()
- ..check_explicit_values();
- }
-
void test_INIT_STATE() {
new EnumTester<INIT_STATE>()
..check_getters()
@@ -99,24 +92,12 @@
..check_explicit_values();
}
- void test_RetentionPriority() {
- new EnumTester<RetentionPriority>()
- ..check_getters()
- ..check_explicit_values();
- }
-
void test_SourceKind() {
new EnumTester<SourceKind>()
..check_getters()
..check_explicit_values();
}
- void test_SourcePriority() {
- new EnumTester<SourcePriority>()
- ..check_getters()
- ..check_explicit_values();
- }
-
void test_UriKind() {
new EnumTester<UriKind>()
..check_getters()
diff --git a/pkg/analyzer/test/file_system/memory_file_system_test.dart b/pkg/analyzer/test/file_system/memory_file_system_test.dart
index d0d3e55..d00d2d4 100644
--- a/pkg/analyzer/test/file_system/memory_file_system_test.dart
+++ b/pkg/analyzer/test/file_system/memory_file_system_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.memory_file_system;
+library analyzer.test.file_system.memory_file_system_test;
import 'dart:async';
import 'dart:core' hide Resource;
diff --git a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
index 852c7b2c..850bbcf 100644
--- a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
+++ b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.physical_file_system;
+library analyzer.test.file_system.physical_resource_provider_test;
import 'dart:async';
import 'dart:core' hide Resource;
diff --git a/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart b/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
index 8d91d24..53247c1 100644
--- a/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
+++ b/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.resource_uri_resolver;
+library analyzer.test.file_system.resource_uri_resolver_test;
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
diff --git a/pkg/analyzer/test/file_system/test_all.dart b/pkg/analyzer/test/file_system/test_all.dart
index 303df09..1714c0b 100644
--- a/pkg/analyzer/test/file_system/test_all.dart
+++ b/pkg/analyzer/test/file_system/test_all.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.file_system;
+library analyzer.test.file_system.test_all;
import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index a9a7ab1..767f2c3 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.all_the_rest_test;
+library analyzer.test.generated.all_the_rest_test;
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
@@ -10,9 +10,7 @@
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart' as ht;
import 'package:analyzer/src/generated/java_core.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/java_engine_io.dart';
import 'package:analyzer/src/generated/java_io.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -23,7 +21,6 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
-import 'package:analyzer/src/generated/testing/html_factory.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
@@ -62,388 +59,9 @@
runReflectiveTests(ExitDetectorTest2);
runReflectiveTests(FileBasedSourceTest);
runReflectiveTests(FileUriResolverTest);
- if (!AnalysisEngine.instance.useTaskModel) {
- runReflectiveTests(HtmlParserTest);
- runReflectiveTests(HtmlTagInfoBuilderTest);
- runReflectiveTests(HtmlUnitBuilderTest);
- runReflectiveTests(HtmlWarningCodeTest);
- }
runReflectiveTests(ReferenceFinderTest);
runReflectiveTests(SDKLibrariesReaderTest);
- runReflectiveTests(ToSourceVisitorTest);
runReflectiveTests(UriKindTest);
- runReflectiveTests(StringScannerTest);
-}
-
-abstract class AbstractScannerTest {
- ht.AbstractScanner newScanner(String input);
-
- void test_tokenize_attribute() {
- _tokenize("<html bob=\"one two\">", <Object>[
- ht.TokenType.LT,
- "html",
- "bob",
- ht.TokenType.EQ,
- "\"one two\"",
- ht.TokenType.GT
- ]);
- }
-
- void test_tokenize_comment() {
- _tokenize("<!-- foo -->", <Object>["<!-- foo -->"]);
- }
-
- void test_tokenize_comment_incomplete() {
- _tokenize("<!-- foo", <Object>["<!-- foo"]);
- }
-
- void test_tokenize_comment_with_gt() {
- _tokenize("<!-- foo > -> -->", <Object>["<!-- foo > -> -->"]);
- }
-
- void test_tokenize_declaration() {
- _tokenize("<! foo ><html>",
- <Object>["<! foo >", ht.TokenType.LT, "html", ht.TokenType.GT]);
- }
-
- void test_tokenize_declaration_malformed() {
- _tokenize("<! foo /><html>",
- <Object>["<! foo />", ht.TokenType.LT, "html", ht.TokenType.GT]);
- }
-
- void test_tokenize_directive_incomplete() {
- _tokenize2("<? \nfoo", <Object>["<? \nfoo"], <int>[0, 4]);
- }
-
- void test_tokenize_directive_xml() {
- _tokenize("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>",
- <Object>["<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"]);
- }
-
- void test_tokenize_directives_incomplete_with_newline() {
- _tokenize2("<! \nfoo", <Object>["<! \nfoo"], <int>[0, 4]);
- }
-
- void test_tokenize_empty() {
- _tokenize("", <Object>[]);
- }
-
- void test_tokenize_lt() {
- _tokenize("<", <Object>[ht.TokenType.LT]);
- }
-
- void test_tokenize_script_embedded_tags() {
- _tokenize("<script> <p></p></script>", <Object>[
- ht.TokenType.LT,
- "script",
- ht.TokenType.GT,
- " <p></p>",
- ht.TokenType.LT_SLASH,
- "script",
- ht.TokenType.GT
- ]);
- }
-
- void test_tokenize_script_embedded_tags2() {
- _tokenize("<script> <p></p><</script>", <Object>[
- ht.TokenType.LT,
- "script",
- ht.TokenType.GT,
- " <p></p><",
- ht.TokenType.LT_SLASH,
- "script",
- ht.TokenType.GT
- ]);
- }
-
- void test_tokenize_script_embedded_tags3() {
- _tokenize("<script> <p></p></</script>", <Object>[
- ht.TokenType.LT,
- "script",
- ht.TokenType.GT,
- " <p></p></",
- ht.TokenType.LT_SLASH,
- "script",
- ht.TokenType.GT
- ]);
- }
-
- void test_tokenize_script_partial() {
- _tokenize("<script> <p> ",
- <Object>[ht.TokenType.LT, "script", ht.TokenType.GT, " <p> "]);
- }
-
- void test_tokenize_script_partial2() {
- _tokenize("<script> <p> <",
- <Object>[ht.TokenType.LT, "script", ht.TokenType.GT, " <p> <"]);
- }
-
- void test_tokenize_script_partial3() {
- _tokenize("<script> <p> </",
- <Object>[ht.TokenType.LT, "script", ht.TokenType.GT, " <p> </"]);
- }
-
- void test_tokenize_script_ref() {
- _tokenize("<script source='some.dart'/> <p>", <Object>[
- ht.TokenType.LT,
- "script",
- "source",
- ht.TokenType.EQ,
- "'some.dart'",
- ht.TokenType.SLASH_GT,
- " ",
- ht.TokenType.LT,
- "p",
- ht.TokenType.GT
- ]);
- }
-
- void test_tokenize_script_with_newline() {
- _tokenize2("<script> <p>\n </script>", <Object>[
- ht.TokenType.LT,
- "script",
- ht.TokenType.GT,
- " <p>\n ",
- ht.TokenType.LT_SLASH,
- "script",
- ht.TokenType.GT
- ], <int>[
- 0,
- 13
- ]);
- }
-
- void test_tokenize_spaces_and_newlines() {
- ht.Token token = _tokenize2(
- " < html \n bob = 'joe\n' >\n <\np > one \r\n two <!-- \rfoo --> </ p > </ html > ",
- <Object>[
- " ",
- ht.TokenType.LT,
- "html",
- "bob",
- ht.TokenType.EQ,
- "'joe\n'",
- ht.TokenType.GT,
- "\n ",
- ht.TokenType.LT,
- "p",
- ht.TokenType.GT,
- " one \r\n two ",
- "<!-- \rfoo -->",
- " ",
- ht.TokenType.LT_SLASH,
- "p",
- ht.TokenType.GT,
- " ",
- ht.TokenType.LT_SLASH,
- "html",
- ht.TokenType.GT,
- " "
- ],
- <int>[
- 0,
- 9,
- 21,
- 25,
- 28,
- 38,
- 49
- ]);
- token = token.next;
- expect(token.offset, 1);
- token = token.next;
- expect(token.offset, 3);
- token = token.next;
- expect(token.offset, 10);
- }
-
- void test_tokenize_string() {
- _tokenize("<p bob=\"foo\">", <Object>[
- ht.TokenType.LT,
- "p",
- "bob",
- ht.TokenType.EQ,
- "\"foo\"",
- ht.TokenType.GT
- ]);
- }
-
- void test_tokenize_string_partial() {
- _tokenize("<p bob=\"foo",
- <Object>[ht.TokenType.LT, "p", "bob", ht.TokenType.EQ, "\"foo"]);
- }
-
- void test_tokenize_string_single_quote() {
- _tokenize("<p bob='foo'>", <Object>[
- ht.TokenType.LT,
- "p",
- "bob",
- ht.TokenType.EQ,
- "'foo'",
- ht.TokenType.GT
- ]);
- }
-
- void test_tokenize_string_single_quote_partial() {
- _tokenize("<p bob='foo",
- <Object>[ht.TokenType.LT, "p", "bob", ht.TokenType.EQ, "'foo"]);
- }
-
- void test_tokenize_tag_begin_end() {
- _tokenize("<html></html>", <Object>[
- ht.TokenType.LT,
- "html",
- ht.TokenType.GT,
- ht.TokenType.LT_SLASH,
- "html",
- ht.TokenType.GT
- ]);
- }
-
- void test_tokenize_tag_begin_only() {
- ht.Token token =
- _tokenize("<html>", <Object>[ht.TokenType.LT, "html", ht.TokenType.GT]);
- token = token.next;
- expect(token.offset, 1);
- }
-
- void test_tokenize_tag_incomplete_with_special_characters() {
- _tokenize("<br-a_b", <Object>[ht.TokenType.LT, "br-a_b"]);
- }
-
- void test_tokenize_tag_self_contained() {
- _tokenize("<br/>", <Object>[ht.TokenType.LT, "br", ht.TokenType.SLASH_GT]);
- }
-
- void test_tokenize_tags_wellformed() {
- _tokenize("<html><p>one two</p></html>", <Object>[
- ht.TokenType.LT,
- "html",
- ht.TokenType.GT,
- ht.TokenType.LT,
- "p",
- ht.TokenType.GT,
- "one two",
- ht.TokenType.LT_SLASH,
- "p",
- ht.TokenType.GT,
- ht.TokenType.LT_SLASH,
- "html",
- ht.TokenType.GT
- ]);
- }
-
- /**
- * Given an object representing an expected token, answer the expected token type.
- *
- * @param count the token count for error reporting
- * @param expected the object representing an expected token
- * @return the expected token type
- */
- ht.TokenType _getExpectedTokenType(int count, Object expected) {
- if (expected is ht.TokenType) {
- return expected;
- }
- if (expected is String) {
- String lexeme = expected;
- if (lexeme.startsWith("\"") || lexeme.startsWith("'")) {
- return ht.TokenType.STRING;
- }
- if (lexeme.startsWith("<!--")) {
- return ht.TokenType.COMMENT;
- }
- if (lexeme.startsWith("<!")) {
- return ht.TokenType.DECLARATION;
- }
- if (lexeme.startsWith("<?")) {
- return ht.TokenType.DIRECTIVE;
- }
- if (_isTag(lexeme)) {
- return ht.TokenType.TAG;
- }
- return ht.TokenType.TEXT;
- }
- fail(
- "Unknown expected token $count: ${expected != null ? expected.runtimeType : "null"}");
- return null;
- }
-
- bool _isTag(String lexeme) {
- if (lexeme.length == 0 || !Character.isLetter(lexeme.codeUnitAt(0))) {
- return false;
- }
- for (int index = 1; index < lexeme.length; index++) {
- int ch = lexeme.codeUnitAt(index);
- if (!Character.isLetterOrDigit(ch) && ch != 0x2D && ch != 0x5F) {
- return false;
- }
- }
- return true;
- }
-
- ht.Token _tokenize(String input, List<Object> expectedTokens) =>
- _tokenize2(input, expectedTokens, <int>[0]);
- ht.Token _tokenize2(
- String input, List<Object> expectedTokens, List<int> expectedLineStarts) {
- ht.AbstractScanner scanner = newScanner(input);
- scanner.passThroughElements = <String>["script"];
- int count = 0;
- ht.Token firstToken = scanner.tokenize();
- ht.Token token = firstToken;
- ht.Token previousToken = token.previous;
- expect(previousToken.type == ht.TokenType.EOF, isTrue);
- expect(previousToken.previous, same(previousToken));
- expect(previousToken.offset, -1);
- expect(previousToken.next, same(token));
- expect(token.offset, 0);
- while (token.type != ht.TokenType.EOF) {
- if (count == expectedTokens.length) {
- fail("too many parsed tokens");
- }
- Object expected = expectedTokens[count];
- ht.TokenType expectedTokenType = _getExpectedTokenType(count, expected);
- expect(token.type, same(expectedTokenType), reason: "token $count");
- if (expectedTokenType.lexeme != null) {
- expect(token.lexeme, expectedTokenType.lexeme, reason: "token $count");
- } else {
- expect(token.lexeme, expected, reason: "token $count");
- }
- count++;
- previousToken = token;
- token = token.next;
- expect(token.previous, same(previousToken));
- }
- expect(token.next, same(token));
- expect(token.offset, input.length);
- if (count != expectedTokens.length) {
- expect(false, isTrue, reason: "not enough parsed tokens");
- }
- List<int> lineStarts = scanner.lineStarts;
- bool success = expectedLineStarts.length == lineStarts.length;
- if (success) {
- for (int i = 0; i < lineStarts.length; i++) {
- if (expectedLineStarts[i] != lineStarts[i]) {
- success = false;
- break;
- }
- }
- }
- if (!success) {
- StringBuffer buffer = new StringBuffer();
- buffer.write("Expected line starts ");
- for (int start in expectedLineStarts) {
- buffer.write(start);
- buffer.write(", ");
- }
- buffer.write(" but found ");
- for (int start in lineStarts) {
- buffer.write(start);
- buffer.write(", ");
- }
- fail(buffer.toString());
- }
- return firstToken;
- }
}
/**
@@ -877,14 +495,13 @@
}
@reflectiveTest
-class ConstantFinderTest extends EngineTestCase {
+class ConstantFinderTest {
AstNode _node;
TypeProvider _typeProvider;
AnalysisContext _context;
Source _source;
void setUp() {
- super.setUp();
_typeProvider = new TestTypeProvider();
_context = new TestAnalysisContext_ConstantFinderTest();
_source = new TestSource();
@@ -2039,7 +1656,7 @@
expect(evaluationResult.value, isNotNull);
DartObjectImpl value = evaluationResult.value;
expect(value.type, typeProvider.symbolType);
- expect(value.value, "a");
+ expect(value.toSymbolValue(), "a");
}
void test_instanceCreationExpression_withSupertypeParams_explicit() {
@@ -2150,7 +1767,7 @@
(voidSymbol.element as VariableElementImpl).evaluationResult;
DartObjectImpl value = voidSymbolResult.value;
expect(value.type, typeProvider.symbolType);
- expect(value.value, "void");
+ expect(value.toSymbolValue(), "void");
}
Map<String, DartObjectImpl> _assertFieldType(
@@ -2221,7 +1838,7 @@
expect(result.value, isNotNull);
DartObjectImpl value = result.value;
expect(value.type, typeProvider.stringType);
- return value.stringValue;
+ return value.toStringValue();
}
void _assertValidUnknown(EvaluationResultImpl result) {
@@ -2483,8 +2100,7 @@
''');
DartObjectImpl result = _evaluateConstant(compilationUnit, 'a', null);
expect(result.type, typeProvider.typeType);
- ClassElement element = result.value;
- expect(element.name, 'C');
+ expect(result.toTypeValue().name, 'C');
}
void test_visitSimpleIdentifier_dynamic() {
@@ -2493,7 +2109,7 @@
''');
DartObjectImpl result = _evaluateConstant(compilationUnit, 'a', null);
expect(result.type, typeProvider.typeType);
- expect(result.value, typeProvider.dynamicType.element);
+ expect(result.toTypeValue(), typeProvider.dynamicType);
}
void test_visitSimpleIdentifier_inEnvironment() {
@@ -2932,51 +2548,51 @@
}
void test_getValue_bool_false() {
- expect(_boolValue(false).value, false);
+ expect(_boolValue(false).toBoolValue(), false);
}
void test_getValue_bool_true() {
- expect(_boolValue(true).value, true);
+ expect(_boolValue(true).toBoolValue(), true);
}
void test_getValue_bool_unknown() {
- expect(_boolValue(null).value, isNull);
+ expect(_boolValue(null).toBoolValue(), isNull);
}
void test_getValue_double_known() {
double value = 2.3;
- expect(_doubleValue(value).value, value);
+ expect(_doubleValue(value).toDoubleValue(), value);
}
void test_getValue_double_unknown() {
- expect(_doubleValue(null).value, isNull);
+ expect(_doubleValue(null).toDoubleValue(), isNull);
}
void test_getValue_int_known() {
int value = 23;
- expect(_intValue(value).value, value);
+ expect(_intValue(value).toIntValue(), value);
}
void test_getValue_int_unknown() {
- expect(_intValue(null).value, isNull);
+ expect(_intValue(null).toIntValue(), isNull);
}
void test_getValue_list_empty() {
- Object result = _listValue().value;
+ Object result = _listValue().toListValue();
_assertInstanceOfObjectArray(result);
List<Object> array = result as List<Object>;
expect(array, hasLength(0));
}
void test_getValue_list_valid() {
- Object result = _listValue([_intValue(23)]).value;
+ Object result = _listValue([_intValue(23)]).toListValue();
_assertInstanceOfObjectArray(result);
List<Object> array = result as List<Object>;
expect(array, hasLength(1));
}
void test_getValue_map_empty() {
- Object result = _mapValue().value;
+ Object result = _mapValue().toMapValue();
EngineTestCase.assertInstanceOf((obj) => obj is Map, Map, result);
Map map = result as Map;
expect(map, hasLength(0));
@@ -2984,23 +2600,23 @@
void test_getValue_map_valid() {
Object result =
- _mapValue([_stringValue("key"), _stringValue("value")]).value;
+ _mapValue([_stringValue("key"), _stringValue("value")]).toMapValue();
EngineTestCase.assertInstanceOf((obj) => obj is Map, Map, result);
Map map = result as Map;
expect(map, hasLength(1));
}
void test_getValue_null() {
- expect(_nullValue().value, isNull);
+ expect(_nullValue().isNull, isTrue);
}
void test_getValue_string_known() {
String value = "twenty-three";
- expect(_stringValue(value).value, value);
+ expect(_stringValue(value).toStringValue(), value);
}
void test_getValue_string_unknown() {
- expect(_stringValue(null).value, isNull);
+ expect(_stringValue(null).toStringValue(), isNull);
}
void test_greaterThan_knownDouble_knownDouble_false() {
@@ -8402,473 +8018,6 @@
}
}
-@reflectiveTest
-class HtmlParserTest extends EngineTestCase {
- /**
- * The name of the 'script' tag in an HTML file.
- */
- static String _TAG_SCRIPT = "script";
- void fail_parse_scriptWithComment() {
- String scriptBody = r'''
- /**
- * <editable-label bind-value="dartAsignableValue">
- * </editable-label>
- */
- class Foo {}''';
- ht.HtmlUnit htmlUnit = parse("""
-<html>
- <body>
- <script type='application/dart'>
-$scriptBody
- </script>
- </body>
-</html>""");
- _validate(htmlUnit, [
- _t4("html", [
- _t4("body", [
- _t("script", _a(["type", "'application/dart'"]), scriptBody)
- ])
- ])
- ]);
- }
-
- ht.HtmlUnit parse(String contents) {
-// TestSource source =
-// new TestSource.con1(FileUtilities2.createFile("/test.dart"), contents);
- ht.AbstractScanner scanner = new ht.StringScanner(null, contents);
- scanner.passThroughElements = <String>[_TAG_SCRIPT];
- ht.Token token = scanner.tokenize();
- LineInfo lineInfo = new LineInfo(scanner.lineStarts);
- GatheringErrorListener errorListener = new GatheringErrorListener();
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- ht.HtmlUnit unit =
- new ht.HtmlParser(null, errorListener, options).parse(token, lineInfo);
- errorListener.assertNoErrors();
- return unit;
- }
-
- void test_parse_attribute() {
- ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"></body></html>");
- _validate(htmlUnit, [
- _t4("html", [
- _t("body", _a(["foo", "\"sdfsdf\""]), "")
- ])
- ]);
- ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
- ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
- expect(bodyNode.attributes[0].text, "sdfsdf");
- }
-
- void test_parse_attribute_EOF() {
- ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"");
- _validate(htmlUnit, [
- _t4("html", [
- _t("body", _a(["foo", "\"sdfsdf\""]), "")
- ])
- ]);
- }
-
- void test_parse_attribute_EOF_missing_quote() {
- ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsd");
- _validate(htmlUnit, [
- _t4("html", [
- _t("body", _a(["foo", "\"sdfsd"]), "")
- ])
- ]);
- ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
- ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
- expect(bodyNode.attributes[0].text, "sdfsd");
- }
-
- void test_parse_attribute_extra_quote() {
- ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"\"></body></html>");
- _validate(htmlUnit, [
- _t4("html", [
- _t("body", _a(["foo", "\"sdfsdf\""]), "")
- ])
- ]);
- }
-
- void test_parse_attribute_single_quote() {
- ht.HtmlUnit htmlUnit = parse("<html><body foo='sdfsdf'></body></html>");
- _validate(htmlUnit, [
- _t4("html", [
- _t("body", _a(["foo", "'sdfsdf'"]), "")
- ])
- ]);
- ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
- ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
- expect(bodyNode.attributes[0].text, "sdfsdf");
- }
-
- void test_parse_comment_embedded() {
- ht.HtmlUnit htmlUnit = parse("<html <!-- comment -->></html>");
- _validate(htmlUnit, [_t3("html", "")]);
- }
-
- void test_parse_comment_first() {
- ht.HtmlUnit htmlUnit = parse("<!-- comment --><html></html>");
- _validate(htmlUnit, [_t3("html", "")]);
- }
-
- void test_parse_comment_in_content() {
- ht.HtmlUnit htmlUnit = parse("<html><!-- comment --></html>");
- _validate(htmlUnit, [_t3("html", "<!-- comment -->")]);
- }
-
- void test_parse_content() {
- ht.HtmlUnit htmlUnit = parse("<html>\n<p a=\"b\">blat \n </p>\n</html>");
- // ht.XmlTagNode.getContent() does not include whitespace
- // between '<' and '>' at this time
- _validate(htmlUnit, [
- _t3("html", "\n<pa=\"b\">blat \n </p>\n", [
- _t("p", _a(["a", "\"b\""]), "blat \n ")
- ])
- ]);
- }
-
- void test_parse_content_none() {
- ht.HtmlUnit htmlUnit = parse("<html><p/>blat<p/></html>");
- _validate(htmlUnit, [
- _t3("html", "<p/>blat<p/>", [_t3("p", ""), _t3("p", "")])
- ]);
- }
-
- void test_parse_declaration() {
- ht.HtmlUnit htmlUnit = parse("<!DOCTYPE html>\n\n<html><p></p></html>");
- _validate(htmlUnit, [
- _t4("html", [_t3("p", "")])
- ]);
- }
-
- void test_parse_directive() {
- ht.HtmlUnit htmlUnit = parse("<?xml ?>\n\n<html><p></p></html>");
- _validate(htmlUnit, [
- _t4("html", [_t3("p", "")])
- ]);
- }
-
- void test_parse_getAttribute() {
- ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"></body></html>");
- ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
- ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
- expect(bodyNode.getAttribute("foo").text, "sdfsdf");
- expect(bodyNode.getAttribute("bar"), null);
- expect(bodyNode.getAttribute(null), null);
- }
-
- void test_parse_getAttributeText() {
- ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"></body></html>");
- ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
- ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
- expect(bodyNode.getAttributeText("foo"), "sdfsdf");
- expect(bodyNode.getAttributeText("bar"), null);
- expect(bodyNode.getAttributeText(null), null);
- }
-
- void test_parse_headers() {
- String code = r'''
-<html>
- <body>
- <h2>000</h2>
- <div>
- 111
- </div>
- </body>
-</html>''';
- ht.HtmlUnit htmlUnit = parse(code);
- _validate(htmlUnit, [
- _t4("html", [
- _t4("body", [_t3("h2", "000"), _t4("div")])
- ])
- ]);
- }
-
- void test_parse_script() {
- ht.HtmlUnit htmlUnit =
- parse("<html><script >here is <p> some</script></html>");
- _validate(htmlUnit, [
- _t4("html", [_t3("script", "here is <p> some")])
- ]);
- }
-
- void test_parse_self_closing() {
- ht.HtmlUnit htmlUnit = parse("<html>foo<br>bar</html>");
- _validate(htmlUnit, [
- _t3("html", "foo<br>bar", [_t3("br", "")])
- ]);
- }
-
- void test_parse_self_closing_declaration() {
- ht.HtmlUnit htmlUnit = parse("<!DOCTYPE html><html>foo</html>");
- _validate(htmlUnit, [_t3("html", "foo")]);
- }
-
- XmlValidator_Attributes _a(List<String> keyValuePairs) =>
- new XmlValidator_Attributes(keyValuePairs);
- XmlValidator_Tag _t(
- String tag, XmlValidator_Attributes attributes, String content,
- [List<XmlValidator_Tag> children = XmlValidator_Tag.EMPTY_LIST]) =>
- new XmlValidator_Tag(tag, attributes, content, children);
- XmlValidator_Tag _t3(String tag, String content,
- [List<XmlValidator_Tag> children = XmlValidator_Tag.EMPTY_LIST]) =>
- new XmlValidator_Tag(
- tag, new XmlValidator_Attributes(), content, children);
- XmlValidator_Tag _t4(String tag,
- [List<XmlValidator_Tag> children = XmlValidator_Tag.EMPTY_LIST]) =>
- new XmlValidator_Tag(tag, new XmlValidator_Attributes(), null, children);
- void _validate(ht.HtmlUnit htmlUnit, List<XmlValidator_Tag> expectedTags) {
- XmlValidator validator = new XmlValidator();
- validator.expectTags(expectedTags);
- htmlUnit.accept(validator);
- validator.assertValid();
- }
-}
-
-@reflectiveTest
-class HtmlTagInfoBuilderTest extends HtmlParserTest {
- void test_builder() {
- HtmlTagInfoBuilder builder = new HtmlTagInfoBuilder();
- ht.HtmlUnit unit = parse(r'''
-<html>
- <body>
- <div id="x"></div>
- <p class='c'></p>
- <div class='c'></div>
- </body>
-</html>''');
- unit.accept(builder);
- HtmlTagInfo info = builder.getTagInfo();
- expect(info, isNotNull);
- List<String> allTags = info.allTags;
- expect(allTags, hasLength(4));
- expect(info.getTagWithId("x"), "div");
- List<String> tagsWithClass = info.getTagsWithClass("c");
- expect(tagsWithClass, hasLength(2));
- }
-}
-
-@reflectiveTest
-class HtmlUnitBuilderTest extends EngineTestCase {
- InternalAnalysisContext _context;
- @override
- void setUp() {
- _context = AnalysisContextFactory.contextWithCore();
- }
-
- @override
- void tearDown() {
- _context = null;
- super.tearDown();
- }
-
- void test_embedded_script() {
- HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart">foo=2;</script>
-</html>''');
- _validate(element, [
- _s(_l([_v("foo")]))
- ]);
- }
-
- void test_embedded_script_no_content() {
- HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart"></script>
-</html>''');
- _validate(element, [_s(_l())]);
- }
-
- void test_external_script() {
- HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart" src="other.dart"/>
-</html>''');
- _validate(element, [_s2("other.dart")]);
- }
-
- void test_external_script_no_source() {
- HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart"/>
-</html>''');
- _validate(element, [_s2(null)]);
- }
-
- void test_external_script_with_content() {
- HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart" src="other.dart">blat=2;</script>
-</html>''');
- _validate(element, [_s2("other.dart")]);
- }
-
- void test_no_scripts() {
- HtmlElementImpl element = _build(r'''
-<!DOCTYPE html>
-<html><p></p></html>''');
- _validate(element, []);
- }
-
- void test_two_dart_scripts() {
- HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart">bar=2;</script>
-<script type="application/dart" src="other.dart"/>
-<script src="dart.js"/>
-</html>''');
- _validate(element, [
- _s(_l([_v("bar")])),
- _s2("other.dart")
- ]);
- }
-
- HtmlElementImpl _build(String contents) {
- TestSource source = new TestSource(
- FileUtilities2.createFile("/test.html").getAbsolutePath(), contents);
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source);
- _context.applyChanges(changeSet);
- HtmlUnitBuilder builder = new HtmlUnitBuilder(_context);
- return builder.buildHtmlElement(source, _context.parseHtmlUnit(source));
- }
-
- HtmlUnitBuilderTest_ExpectedLibrary _l(
- [List<HtmlUnitBuilderTest_ExpectedVariable> expectedVariables =
- HtmlUnitBuilderTest_ExpectedVariable.EMPTY_LIST]) =>
- new HtmlUnitBuilderTest_ExpectedLibrary(this, expectedVariables);
- _ExpectedScript _s(HtmlUnitBuilderTest_ExpectedLibrary expectedLibrary) =>
- new _ExpectedScript.con1(expectedLibrary);
- _ExpectedScript _s2(String scriptSourcePath) =>
- new _ExpectedScript.con2(scriptSourcePath);
- HtmlUnitBuilderTest_ExpectedVariable _v(String varName) =>
- new HtmlUnitBuilderTest_ExpectedVariable(varName);
- void _validate(
- HtmlElementImpl element, List<_ExpectedScript> expectedScripts) {
- expect(element.context, same(_context));
- List<HtmlScriptElement> scripts = element.scripts;
- expect(scripts, isNotNull);
- expect(scripts, hasLength(expectedScripts.length));
- for (int scriptIndex = 0; scriptIndex < scripts.length; scriptIndex++) {
- expectedScripts[scriptIndex]._validate(scriptIndex, scripts[scriptIndex]);
- }
- }
-}
-
-class HtmlUnitBuilderTest_ExpectedLibrary {
- final HtmlUnitBuilderTest HtmlUnitBuilderTest_this;
- final List<HtmlUnitBuilderTest_ExpectedVariable> _expectedVariables;
- HtmlUnitBuilderTest_ExpectedLibrary(this.HtmlUnitBuilderTest_this,
- [this._expectedVariables =
- HtmlUnitBuilderTest_ExpectedVariable.EMPTY_LIST]);
- void _validate(int scriptIndex, EmbeddedHtmlScriptElementImpl script) {
- LibraryElement library = script.scriptLibrary;
- expect(library, isNotNull, reason: "script $scriptIndex");
- expect(script.context, same(HtmlUnitBuilderTest_this._context),
- reason: "script $scriptIndex");
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull, reason: "script $scriptIndex");
- List<TopLevelVariableElement> variables = unit.topLevelVariables;
- expect(variables, hasLength(_expectedVariables.length));
- for (int index = 0; index < variables.length; index++) {
- _expectedVariables[index].validate(scriptIndex, variables[index]);
- }
- expect(library.enclosingElement, same(script),
- reason: "script $scriptIndex");
- }
-}
-
-class HtmlUnitBuilderTest_ExpectedVariable {
- static const List<HtmlUnitBuilderTest_ExpectedVariable> EMPTY_LIST =
- const <HtmlUnitBuilderTest_ExpectedVariable>[];
- final String _expectedName;
- HtmlUnitBuilderTest_ExpectedVariable(this._expectedName);
- void validate(int scriptIndex, TopLevelVariableElement variable) {
- expect(variable, isNotNull, reason: "script $scriptIndex");
- expect(variable.name, _expectedName, reason: "script $scriptIndex");
- }
-}
-
-/**
- * Instances of the class `HtmlWarningCodeTest` test the generation of HTML warning codes.
- */
-@reflectiveTest
-class HtmlWarningCodeTest extends EngineTestCase {
- /**
- * The analysis context used to resolve the HTML files.
- */
- InternalAnalysisContext _context;
-
- /**
- * The contents of the 'test.html' file.
- */
- String _contents;
-
- /**
- * The list of reported errors.
- */
- List<AnalysisError> _errors;
- @override
- void setUp() {
- _context = AnalysisContextFactory.contextWithCore();
- }
-
- @override
- void tearDown() {
- _context = null;
- _contents = null;
- _errors = null;
- super.tearDown();
- }
-
- void test_invalidUri() {
- _verify(
- r'''
-<html>
-<script type='application/dart' src='ht:'/>
-</html>''',
- [HtmlWarningCode.INVALID_URI]);
- _assertErrorLocation2(_errors[0], "ht:");
- }
-
- void test_uriDoesNotExist() {
- _verify(
- r'''
-<html>
-<script type='application/dart' src='other.dart'/>
-</html>''',
- [HtmlWarningCode.URI_DOES_NOT_EXIST]);
- _assertErrorLocation2(_errors[0], "other.dart");
- }
-
- void _assertErrorLocation(
- AnalysisError error, int expectedOffset, int expectedLength) {
- expect(error.offset, expectedOffset, reason: error.toString());
- expect(error.length, expectedLength, reason: error.toString());
- }
-
- void _assertErrorLocation2(AnalysisError error, String expectedString) {
- _assertErrorLocation(
- error, _contents.indexOf(expectedString), expectedString.length);
- }
-
- void _verify(String contents, List<ErrorCode> expectedErrorCodes) {
- this._contents = contents;
- TestSource source = new TestSource(
- FileUtilities2.createFile("/test.html").getAbsolutePath(), contents);
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source);
- _context.applyChanges(changeSet);
- HtmlUnitBuilder builder = new HtmlUnitBuilder(_context);
- builder.buildHtmlElement(source, _context.parseHtmlUnit(source));
- GatheringErrorListener errorListener = new GatheringErrorListener();
- errorListener.addAll2(builder.errorListener);
- errorListener.assertErrorsWithCodes(expectedErrorCodes);
- _errors = errorListener.errors;
- }
-}
-
/**
* Instances of the class `MockDartSdk` implement a [DartSdk].
*/
@@ -8896,11 +8045,11 @@
}
@reflectiveTest
-class ReferenceFinderTest extends EngineTestCase {
+class ReferenceFinderTest {
DirectedGraph<ConstantEvaluationTarget> _referenceGraph;
VariableElement _head;
Element _tail;
- @override
+
void setUp() {
_referenceGraph = new DirectedGraph<ConstantEvaluationTarget>();
_head = ElementFactory.topLevelVariableElement2("v1");
@@ -9062,14 +8211,6 @@
}
}
-@reflectiveTest
-class StringScannerTest extends AbstractScannerTest {
- @override
- ht.AbstractScanner newScanner(String input) {
- return new ht.StringScanner(null, input);
- }
-}
-
class TestAnalysisContext_ConstantFinderTest extends TestAnalysisContext {
bool invoked = false;
TestAnalysisContext_ConstantFinderTest();
@@ -9080,61 +8221,6 @@
}
}
-/**
- * Instances of the class `ToSourceVisitorTest`
- */
-@reflectiveTest
-class ToSourceVisitorTest extends EngineTestCase {
- void fail_visitHtmlScriptTagNode_attributes_content() {
- _assertSource(
- "<script type='application/dart'>f() {}</script>",
- HtmlFactory.scriptTagWithContent(
- "f() {}", [HtmlFactory.attribute("type", "'application/dart'")]));
- }
-
- void fail_visitHtmlScriptTagNode_noAttributes_content() {
- _assertSource(
- "<script>f() {}</script>", HtmlFactory.scriptTagWithContent("f() {}"));
- }
-
- void test_visitHtmlScriptTagNode_attributes_noContent() {
- _assertSource(
- "<script type='application/dart'/>",
- HtmlFactory
- .scriptTag([HtmlFactory.attribute("type", "'application/dart'")]));
- }
-
- void test_visitHtmlScriptTagNode_noAttributes_noContent() {
- _assertSource("<script/>", HtmlFactory.scriptTag());
- }
-
- void test_visitHtmlUnit_empty() {
- _assertSource("", new ht.HtmlUnit(null, new List<ht.XmlTagNode>(), null));
- }
-
- void test_visitHtmlUnit_nonEmpty() {
- _assertSource(
- "<html/>", new ht.HtmlUnit(null, [HtmlFactory.tagNode("html")], null));
- }
-
- void test_visitXmlAttributeNode() {
- _assertSource("x=y", HtmlFactory.attribute("x", "y"));
- }
-
- /**
- * Assert that a `ToSourceVisitor` will produce the expected source when visiting the given
- * node.
- *
- * @param expectedSource the source string that the visitor is expected to produce
- * @param node the AST node being visited to produce the actual source
- */
- void _assertSource(String expectedSource, ht.XmlNode node) {
- PrintStringWriter writer = new PrintStringWriter();
- node.accept(new ht.ToSourceVisitor(writer));
- expect(writer.toString(), expectedSource);
- }
-}
-
@reflectiveTest
class UriKindTest {
void test_fromEncoding() {
@@ -9150,285 +8236,3 @@
expect(UriKind.PACKAGE_URI.encoding, 0x70);
}
}
-
-/**
- * Instances of `XmlValidator` traverse an [XmlNode] structure and validate the node
- * hierarchy.
- */
-class XmlValidator extends ht.RecursiveXmlVisitor<Object> {
- /**
- * A list containing the errors found while traversing the AST structure.
- */
- List<String> _errors = new List<String>();
- /**
- * The tags to expect when visiting or `null` if tags should not be checked.
- */
- List<XmlValidator_Tag> _expectedTagsInOrderVisited;
- /**
- * The current index into the [expectedTagsInOrderVisited] array.
- */
- int _expectedTagsIndex = 0;
- /**
- * The key/value pairs to expect when visiting or `null` if attributes should not be
- * checked.
- */
- List<String> _expectedAttributeKeyValuePairs;
- /**
- * The current index into the [expectedAttributeKeyValuePairs].
- */
- int _expectedAttributeIndex = 0;
- /**
- * Assert that no errors were found while traversing any of the AST structures that have been
- * visited.
- */
- void assertValid() {
- while (_expectedTagsIndex < _expectedTagsInOrderVisited.length) {
- String expectedTag =
- _expectedTagsInOrderVisited[_expectedTagsIndex++]._tag;
- _errors.add("Expected to visit node with tag: $expectedTag");
- }
- if (!_errors.isEmpty) {
- StringBuffer buffer = new StringBuffer();
- buffer.write("Invalid XML structure:");
- for (String message in _errors) {
- buffer.writeln();
- buffer.write(" ");
- buffer.write(message);
- }
- fail(buffer.toString());
- }
- }
-
- /**
- * Set the tags to be expected when visiting
- *
- * @param expectedTags the expected tags
- */
- void expectTags(List<XmlValidator_Tag> expectedTags) {
- // Flatten the hierarchy into expected order in which the tags are visited
- List<XmlValidator_Tag> expected = new List<XmlValidator_Tag>();
- _expectTags(expected, expectedTags);
- this._expectedTagsInOrderVisited = expected;
- }
-
- @override
- Object visitHtmlUnit(ht.HtmlUnit node) {
- if (node.parent != null) {
- _errors.add("HtmlUnit should not have a parent");
- }
- if (node.endToken.type != ht.TokenType.EOF) {
- _errors.add("HtmlUnit end token should be of type EOF");
- }
- _validateNode(node);
- return super.visitHtmlUnit(node);
- }
-
- @override
- Object visitXmlAttributeNode(ht.XmlAttributeNode actual) {
- if (actual.parent is! ht.XmlTagNode) {
- _errors.add(
- "Expected ${actual.runtimeType} to have parent of type XmlTagNode");
- }
- String actualName = actual.name;
- String actualValue = actual.valueToken.lexeme;
- if (_expectedAttributeIndex < _expectedAttributeKeyValuePairs.length) {
- String expectedName =
- _expectedAttributeKeyValuePairs[_expectedAttributeIndex];
- if (expectedName != actualName) {
- _errors.add(
- "Expected ${_expectedTagsIndex - 1} tag: ${_expectedTagsInOrderVisited[_expectedTagsIndex - 1]._tag} attribute ${_expectedAttributeIndex ~/ 2} to have name: $expectedName but found: $actualName");
- }
- String expectedValue =
- _expectedAttributeKeyValuePairs[_expectedAttributeIndex + 1];
- if (expectedValue != actualValue) {
- _errors.add(
- "Expected ${_expectedTagsIndex - 1} tag: ${_expectedTagsInOrderVisited[_expectedTagsIndex - 1]._tag} attribute ${_expectedAttributeIndex ~/ 2} to have value: $expectedValue but found: $actualValue");
- }
- } else {
- _errors.add(
- "Unexpected ${_expectedTagsIndex - 1} tag: ${_expectedTagsInOrderVisited[_expectedTagsIndex - 1]._tag} attribute ${_expectedAttributeIndex ~/ 2} name: $actualName value: $actualValue");
- }
- _expectedAttributeIndex += 2;
- _validateNode(actual);
- return super.visitXmlAttributeNode(actual);
- }
-
- @override
- Object visitXmlTagNode(ht.XmlTagNode actual) {
- if (!(actual.parent is ht.HtmlUnit || actual.parent is ht.XmlTagNode)) {
- _errors.add(
- "Expected ${actual.runtimeType} to have parent of type HtmlUnit or XmlTagNode");
- }
- if (_expectedTagsInOrderVisited != null) {
- String actualTag = actual.tag;
- if (_expectedTagsIndex < _expectedTagsInOrderVisited.length) {
- XmlValidator_Tag expected =
- _expectedTagsInOrderVisited[_expectedTagsIndex];
- if (expected._tag != actualTag) {
- _errors.add(
- "Expected $_expectedTagsIndex tag: ${expected._tag} but found: $actualTag");
- }
- _expectedAttributeKeyValuePairs = expected._attributes._keyValuePairs;
- int expectedAttributeCount =
- _expectedAttributeKeyValuePairs.length ~/ 2;
- int actualAttributeCount = actual.attributes.length;
- if (expectedAttributeCount != actualAttributeCount) {
- _errors.add(
- "Expected $_expectedTagsIndex tag: ${expected._tag} to have $expectedAttributeCount attributes but found $actualAttributeCount");
- }
- _expectedAttributeIndex = 0;
- _expectedTagsIndex++;
- expect(actual.attributeEnd, isNotNull);
- expect(actual.contentEnd, isNotNull);
- int count = 0;
- ht.Token token = actual.attributeEnd.next;
- ht.Token lastToken = actual.contentEnd;
- while (!identical(token, lastToken)) {
- token = token.next;
- if (++count > 1000) {
- fail(
- "Expected $_expectedTagsIndex tag: ${expected._tag} to have a sequence of tokens from getAttributeEnd() to getContentEnd()");
- break;
- }
- }
- if (actual.attributeEnd.type == ht.TokenType.GT) {
- if (ht.HtmlParser.SELF_CLOSING.contains(actual.tag)) {
- expect(actual.closingTag, isNull);
- } else {
- expect(actual.closingTag, isNotNull);
- }
- } else if (actual.attributeEnd.type == ht.TokenType.SLASH_GT) {
- expect(actual.closingTag, isNull);
- } else {
- fail("Unexpected attribute end token: ${actual.attributeEnd.lexeme}");
- }
- if (expected._content != null && expected._content != actual.content) {
- _errors.add(
- "Expected $_expectedTagsIndex tag: ${expected._tag} to have content '${expected._content}' but found '${actual.content}'");
- }
- if (expected._children.length != actual.tagNodes.length) {
- _errors.add(
- "Expected $_expectedTagsIndex tag: ${expected._tag} to have ${expected._children.length} children but found ${actual.tagNodes.length}");
- } else {
- for (int index = 0; index < expected._children.length; index++) {
- String expectedChildTag = expected._children[index]._tag;
- String actualChildTag = actual.tagNodes[index].tag;
- if (expectedChildTag != actualChildTag) {
- _errors.add(
- "Expected $_expectedTagsIndex tag: ${expected._tag} child $index to have tag: $expectedChildTag but found: $actualChildTag");
- }
- }
- }
- } else {
- _errors.add("Visited unexpected tag: $actualTag");
- }
- }
- _validateNode(actual);
- return super.visitXmlTagNode(actual);
- }
-
- /**
- * Append the specified tags to the array in depth first order
- *
- * @param expected the array to which the tags are added (not `null`)
- * @param expectedTags the expected tags to be added (not `null`, contains no `null`s)
- */
- void _expectTags(
- List<XmlValidator_Tag> expected, List<XmlValidator_Tag> expectedTags) {
- for (XmlValidator_Tag tag in expectedTags) {
- expected.add(tag);
- _expectTags(expected, tag._children);
- }
- }
-
- void _validateNode(ht.XmlNode node) {
- if (node.beginToken == null) {
- _errors.add("No begin token for ${node.runtimeType}");
- }
- if (node.endToken == null) {
- _errors.add("No end token for ${node.runtimeType}");
- }
- int nodeStart = node.offset;
- int nodeLength = node.length;
- if (nodeStart < 0 || nodeLength < 0) {
- _errors.add("No source info for ${node.runtimeType}");
- }
- ht.XmlNode parent = node.parent;
- if (parent != null) {
- int nodeEnd = nodeStart + nodeLength;
- int parentStart = parent.offset;
- int parentEnd = parentStart + parent.length;
- if (nodeStart < parentStart) {
- _errors.add(
- "Invalid source start ($nodeStart) for ${node.runtimeType} inside ${parent.runtimeType} ($parentStart)");
- }
- if (nodeEnd > parentEnd) {
- _errors.add(
- "Invalid source end ($nodeEnd) for ${node.runtimeType} inside ${parent.runtimeType} ($parentStart)");
- }
- }
- }
-}
-
-class XmlValidator_Attributes {
- final List<String> _keyValuePairs;
- XmlValidator_Attributes([this._keyValuePairs = StringUtilities.EMPTY_ARRAY]);
-}
-
-class XmlValidator_Tag {
- static const List<XmlValidator_Tag> EMPTY_LIST = const <XmlValidator_Tag>[];
- final String _tag;
- final XmlValidator_Attributes _attributes;
- final String _content;
- final List<XmlValidator_Tag> _children;
- XmlValidator_Tag(this._tag, this._attributes, this._content,
- [this._children = EMPTY_LIST]);
-}
-
-class _ExpectedScript {
- String _expectedExternalScriptName;
- HtmlUnitBuilderTest_ExpectedLibrary _expectedLibrary;
- _ExpectedScript.con1(HtmlUnitBuilderTest_ExpectedLibrary expectedLibrary) {
- this._expectedExternalScriptName = null;
- this._expectedLibrary = expectedLibrary;
- }
- _ExpectedScript.con2(String expectedExternalScriptPath) {
- this._expectedExternalScriptName = expectedExternalScriptPath;
- this._expectedLibrary = null;
- }
- void _validate(int scriptIndex, HtmlScriptElement script) {
- if (_expectedLibrary != null) {
- _validateEmbedded(scriptIndex, script);
- } else {
- _validateExternal(scriptIndex, script);
- }
- }
-
- void _validateEmbedded(int scriptIndex, HtmlScriptElement script) {
- if (script is! EmbeddedHtmlScriptElementImpl) {
- fail(
- "Expected script $scriptIndex to be embedded, but found ${script != null ? script.runtimeType : "null"}");
- }
- EmbeddedHtmlScriptElementImpl embeddedScript =
- script as EmbeddedHtmlScriptElementImpl;
- _expectedLibrary._validate(scriptIndex, embeddedScript);
- }
-
- void _validateExternal(int scriptIndex, HtmlScriptElement script) {
- if (script is! ExternalHtmlScriptElementImpl) {
- fail(
- "Expected script $scriptIndex to be external with src=$_expectedExternalScriptName but found ${script != null ? script.runtimeType : "null"}");
- }
- ExternalHtmlScriptElementImpl externalScript =
- script as ExternalHtmlScriptElementImpl;
- Source scriptSource = externalScript.scriptSource;
- if (_expectedExternalScriptName == null) {
- expect(scriptSource, isNull, reason: "script $scriptIndex");
- } else {
- expect(scriptSource, isNotNull, reason: "script $scriptIndex");
- String actualExternalScriptName = scriptSource.shortName;
- expect(actualExternalScriptName, _expectedExternalScriptName,
- reason: "script $scriptIndex");
- }
- }
-}
diff --git a/pkg/analyzer/test/generated/ast_test.dart b/pkg/analyzer/test/generated/ast_test.dart
index 947ca7f..bff9b8b 100644
--- a/pkg/analyzer/test/generated/ast_test.dart
+++ b/pkg/analyzer/test/generated/ast_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.ast_test;
+library analyzer.test.generated.ast_test;
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/java_core.dart';
@@ -1733,6 +1733,13 @@
"assert (a);", AstFactory.assertStatement(AstFactory.identifier3("a")));
}
+ void test_visitAssertStatement_withMessage() {
+ _assertSource(
+ "assert (a, b);",
+ AstFactory.assertStatement(
+ AstFactory.identifier3("a"), AstFactory.identifier3('b')));
+ }
+
void test_visitAssignmentExpression() {
_assertSource(
"a = b",
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index 154d448..a30a2cb 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.compile_time_error_code_test;
+library analyzer.test.generated.compile_time_error_code_test;
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
@@ -262,6 +262,19 @@
verify([source]);
}
+ void test_assertWithExtraArgument() {
+ // TODO(paulberry): once DEP 37 is turned on by default, this test should
+ // be removed.
+ Source source = addSource('''
+f(bool x) {
+ assert(x, 'foo');
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [CompileTimeErrorCode.EXTRA_ARGUMENT_TO_ASSERT]);
+ verify([source]);
+ }
+
void test_async_used_as_identifier_in_annotation() {
Source source = addSource('''
const int async = 0;
diff --git a/pkg/analyzer/test/generated/element_test.dart b/pkg/analyzer/test/generated/element_test.dart
index 4487fcb..9285b5f 100644
--- a/pkg/analyzer/test/generated/element_test.dart
+++ b/pkg/analyzer/test/generated/element_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.element_test;
+library analyzer.test.generated.element_test;
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
@@ -32,7 +32,6 @@
runReflectiveTests(CompilationUnitElementImplTest);
runReflectiveTests(ElementLocationImplTest);
runReflectiveTests(ElementImplTest);
- runReflectiveTests(HtmlElementImplTest);
runReflectiveTests(LibraryElementImplTest);
runReflectiveTests(MethodElementImplTest);
runReflectiveTests(MultiplyDefinedElementImplTest);
@@ -1889,18 +1888,6 @@
expect(paramType.prunedTypedefs[0], same(f));
}
- void test_withTypeArguments() {
- ClassElementImpl enclosingClass = ElementFactory.classElement2("C", ["E"]);
- MethodElementImpl methodElement =
- new MethodElementImpl.forNode(AstFactory.identifier3("m"));
- enclosingClass.methods = <MethodElement>[methodElement];
- FunctionTypeImpl type = new FunctionTypeImpl(methodElement);
- DartType expectedType = enclosingClass.typeParameters[0].type;
- List<DartType> arguments = type.typeArguments;
- expect(arguments, hasLength(1));
- expect(arguments[0], expectedType);
- }
-
void test_substitute2_equal() {
ClassElementImpl definingClass = ElementFactory.classElement2("C", ["E"]);
TypeParameterType parameterType = definingClass.typeParameters[0].type;
@@ -1985,34 +1972,17 @@
f.returnType = c.type.substitute4([f.type]);
expect(f.type.toString(), '() \u2192 C<...>');
}
-}
-@reflectiveTest
-class HtmlElementImplTest extends EngineTestCase {
- void test_equals_differentSource() {
- AnalysisContext context = createAnalysisContext();
- HtmlElementImpl elementA = ElementFactory.htmlUnit(context, "indexA.html");
- HtmlElementImpl elementB = ElementFactory.htmlUnit(context, "indexB.html");
- expect(elementA == elementB, isFalse);
- }
-
- void test_equals_null() {
- AnalysisContext context = createAnalysisContext();
- HtmlElementImpl element = ElementFactory.htmlUnit(context, "index.html");
- expect(element == null, isFalse);
- }
-
- void test_equals_sameSource() {
- AnalysisContext context = createAnalysisContext();
- HtmlElementImpl elementA = ElementFactory.htmlUnit(context, "index.html");
- HtmlElementImpl elementB = ElementFactory.htmlUnit(context, "index.html");
- expect(elementA == elementB, isTrue);
- }
-
- void test_equals_self() {
- AnalysisContext context = createAnalysisContext();
- HtmlElementImpl element = ElementFactory.htmlUnit(context, "index.html");
- expect(element == element, isTrue);
+ void test_withTypeArguments() {
+ ClassElementImpl enclosingClass = ElementFactory.classElement2("C", ["E"]);
+ MethodElementImpl methodElement =
+ new MethodElementImpl.forNode(AstFactory.identifier3("m"));
+ enclosingClass.methods = <MethodElement>[methodElement];
+ FunctionTypeImpl type = new FunctionTypeImpl(methodElement);
+ DartType expectedType = enclosingClass.typeParameters[0].type;
+ List<DartType> arguments = type.typeArguments;
+ expect(arguments, hasLength(1));
+ expect(arguments[0], expectedType);
}
}
@@ -2025,6 +1995,7 @@
@override
void setUp() {
+ super.setUp();
_typeProvider = new TestTypeProvider();
}
@@ -2493,241 +2464,6 @@
expect(result.typeArguments[0], same(typeI));
}
- void test_getLeastUpperBound_directInterfaceCase() {
- //
- // class A
- // class B implements A
- // class C implements B
- //
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- ClassElementImpl classC = ElementFactory.classElement2("C");
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
- classB.interfaces = <InterfaceType>[typeA];
- classC.interfaces = <InterfaceType>[typeB];
- expect(typeB.getLeastUpperBound(typeC), typeB);
- expect(typeC.getLeastUpperBound(typeB), typeB);
- }
-
- void test_getLeastUpperBound_directSubclassCase() {
- //
- // class A
- // class B extends A
- // class C extends B
- //
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
- expect(typeB.getLeastUpperBound(typeC), typeB);
- expect(typeC.getLeastUpperBound(typeB), typeB);
- }
-
- void test_getLeastUpperBound_functionType() {
- DartType interfaceType = ElementFactory.classElement2("A").type;
- FunctionTypeImpl functionType = new FunctionTypeImpl(
- new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
- expect(interfaceType.getLeastUpperBound(functionType), isNull);
- }
-
- void test_getLeastUpperBound_mixinCase() {
- //
- // class A
- // class B extends A
- // class C extends A
- // class D extends B with M, N, O, P
- //
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- ClassElement classC = ElementFactory.classElement("C", classA.type);
- ClassElementImpl classD = ElementFactory.classElement("D", classB.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeC = classC.type;
- InterfaceType typeD = classD.type;
- classD.mixins = <InterfaceType>[
- ElementFactory.classElement2("M").type,
- ElementFactory.classElement2("N").type,
- ElementFactory.classElement2("O").type,
- ElementFactory.classElement2("P").type
- ];
- expect(typeD.getLeastUpperBound(typeC), typeA);
- expect(typeC.getLeastUpperBound(typeD), typeA);
- }
-
- void test_getLeastUpperBound_null() {
- DartType interfaceType = ElementFactory.classElement2("A").type;
- expect(interfaceType.getLeastUpperBound(null), isNull);
- }
-
- void test_getLeastUpperBound_object() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- DartType typeObject = typeA.element.supertype;
- // assert that object does not have a super type
- expect((typeObject.element as ClassElement).supertype, isNull);
- // assert that both A and B have the same super type of Object
- expect(typeB.element.supertype, typeObject);
- // finally, assert that the only least upper bound of A and B is Object
- expect(typeA.getLeastUpperBound(typeB), typeObject);
- }
-
- void test_getLeastUpperBound_self() {
- ClassElement classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
- expect(typeA.getLeastUpperBound(typeA), typeA);
- }
-
- void test_getLeastUpperBound_sharedSuperclass1() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
- expect(typeB.getLeastUpperBound(typeC), typeA);
- expect(typeC.getLeastUpperBound(typeB), typeA);
- }
-
- void test_getLeastUpperBound_sharedSuperclass2() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
- ClassElementImpl classD = ElementFactory.classElement("D", classC.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeD = classD.type;
- expect(typeB.getLeastUpperBound(typeD), typeA);
- expect(typeD.getLeastUpperBound(typeB), typeA);
- }
-
- void test_getLeastUpperBound_sharedSuperclass3() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
- ClassElementImpl classD = ElementFactory.classElement("D", classB.type);
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
- InterfaceType typeD = classD.type;
- expect(typeC.getLeastUpperBound(typeD), typeB);
- expect(typeD.getLeastUpperBound(typeC), typeB);
- }
-
- void test_getLeastUpperBound_sharedSuperclass4() {
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classA2 = ElementFactory.classElement2("A2");
- ClassElement classA3 = ElementFactory.classElement2("A3");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeA2 = classA2.type;
- InterfaceType typeA3 = classA3.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
- classB.interfaces = <InterfaceType>[typeA2];
- classC.interfaces = <InterfaceType>[typeA3];
- expect(typeB.getLeastUpperBound(typeC), typeA);
- expect(typeC.getLeastUpperBound(typeB), typeA);
- }
-
- void test_getLeastUpperBound_sharedSuperinterface1() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- ClassElementImpl classC = ElementFactory.classElement2("C");
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
- classB.interfaces = <InterfaceType>[typeA];
- classC.interfaces = <InterfaceType>[typeA];
- expect(typeB.getLeastUpperBound(typeC), typeA);
- expect(typeC.getLeastUpperBound(typeB), typeA);
- }
-
- void test_getLeastUpperBound_sharedSuperinterface2() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- ClassElementImpl classC = ElementFactory.classElement2("C");
- ClassElementImpl classD = ElementFactory.classElement2("D");
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
- InterfaceType typeD = classD.type;
- classB.interfaces = <InterfaceType>[typeA];
- classC.interfaces = <InterfaceType>[typeA];
- classD.interfaces = <InterfaceType>[typeC];
- expect(typeB.getLeastUpperBound(typeD), typeA);
- expect(typeD.getLeastUpperBound(typeB), typeA);
- }
-
- void test_getLeastUpperBound_sharedSuperinterface3() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- ClassElementImpl classC = ElementFactory.classElement2("C");
- ClassElementImpl classD = ElementFactory.classElement2("D");
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
- InterfaceType typeD = classD.type;
- classB.interfaces = <InterfaceType>[typeA];
- classC.interfaces = <InterfaceType>[typeB];
- classD.interfaces = <InterfaceType>[typeB];
- expect(typeC.getLeastUpperBound(typeD), typeB);
- expect(typeD.getLeastUpperBound(typeC), typeB);
- }
-
- void test_getLeastUpperBound_sharedSuperinterface4() {
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classA2 = ElementFactory.classElement2("A2");
- ClassElement classA3 = ElementFactory.classElement2("A3");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- ClassElementImpl classC = ElementFactory.classElement2("C");
- InterfaceType typeA = classA.type;
- InterfaceType typeA2 = classA2.type;
- InterfaceType typeA3 = classA3.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
- classB.interfaces = <InterfaceType>[typeA, typeA2];
- classC.interfaces = <InterfaceType>[typeA, typeA3];
- expect(typeB.getLeastUpperBound(typeC), typeA);
- expect(typeC.getLeastUpperBound(typeB), typeA);
- }
-
- void test_getLeastUpperBound_twoComparables() {
- InterfaceType string = _typeProvider.stringType;
- InterfaceType num = _typeProvider.numType;
- expect(string.getLeastUpperBound(num), _typeProvider.objectType);
- }
-
- void test_getLeastUpperBound_typeParameters_different() {
- //
- // class List<int>
- // class List<double>
- //
- InterfaceType listType = _typeProvider.listType;
- InterfaceType intType = _typeProvider.intType;
- InterfaceType doubleType = _typeProvider.doubleType;
- InterfaceType listOfIntType = listType.substitute4(<DartType>[intType]);
- InterfaceType listOfDoubleType =
- listType.substitute4(<DartType>[doubleType]);
- expect(listOfIntType.getLeastUpperBound(listOfDoubleType),
- _typeProvider.objectType);
- }
-
- void test_getLeastUpperBound_typeParameters_same() {
- //
- // List<int>
- // List<int>
- //
- InterfaceType listType = _typeProvider.listType;
- InterfaceType intType = _typeProvider.intType;
- InterfaceType listOfIntType = listType.substitute4(<DartType>[intType]);
- expect(listOfIntType.getLeastUpperBound(listOfIntType), listOfIntType);
- }
-
void test_getMethod_implemented() {
//
// class A { m() {} }
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index 42a5bfc..243f273 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -2,2483 +2,32 @@
// for 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 engine.engine_test;
+library analyzer.test.generated.engine_test;
import 'dart:async';
-import 'dart:collection';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/embedder.dart';
-import 'package:analyzer/src/cancelable_future.dart';
-import 'package:analyzer/src/context/cache.dart' show CacheEntry;
+import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart' as ht;
import 'package:analyzer/src/generated/java_core.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
-import 'package:analyzer/src/generated/java_engine_io.dart';
-import 'package:analyzer/src/generated/java_io.dart';
-import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/sdk_io.dart';
import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
-import 'package:analyzer/src/generated/testing/element_factory.dart';
-import 'package:analyzer/src/generated/utilities_collection.dart';
-import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/string_source.dart';
-import 'package:analyzer/task/model.dart' as newContext;
+import 'package:analyzer/task/model.dart';
import 'package:html/dom.dart' show Document;
-import 'package:path/path.dart' as pathos;
import 'package:typed_mock/typed_mock.dart';
import 'package:unittest/unittest.dart';
-import 'package:watcher/src/utils.dart';
import '../reflective_tests.dart';
import '../utils.dart';
-import 'all_the_rest_test.dart';
-import 'resolver_test.dart';
-import 'test_support.dart';
main() {
initializeTestEnvironment();
- // Tests for the classes used in both old and new analysis implementations.
runReflectiveTests(SourcesChangedEventTest);
- // Tests for the classes used in the old analysis implementation.
- if (!AnalysisEngine.instance.useTaskModel) {
- runReflectiveTests(AnalysisCacheTest);
- runReflectiveTests(AnalysisContextImplTest);
- runReflectiveTests(AnalysisTaskTest);
- runReflectiveTests(AnalysisOptionsImplTest);
- runReflectiveTests(DartEntryTest);
- runReflectiveTests(GenerateDartErrorsTaskTest);
- runReflectiveTests(GenerateDartHintsTaskTest);
- runReflectiveTests(GenerateDartLintsTaskTest);
- runReflectiveTests(GetContentTaskTest);
- runReflectiveTests(HtmlEntryTest);
- runReflectiveTests(IncrementalAnalysisCacheTest);
- runReflectiveTests(IncrementalAnalysisTaskTest);
- runReflectiveTests(LintGeneratorTest);
- runReflectiveTests(ParseDartTaskTest);
- runReflectiveTests(ParseHtmlTaskTest);
- runReflectiveTests(PartitionManagerTest);
- runReflectiveTests(ResolveDartLibraryTaskTest);
- runReflectiveTests(ResolveDartUnitTaskTest);
- runReflectiveTests(ResolveHtmlTaskTest);
- runReflectiveTests(ScanDartTaskTest);
- runReflectiveTests(SdkCachePartitionTest);
- runReflectiveTests(UniversalCachePartitionTest);
- runReflectiveTests(WorkManagerTest);
- }
-}
-
-@reflectiveTest
-class AnalysisCacheTest extends EngineTestCase {
- void test_creation() {
- expect(new AnalysisCache(new List<CachePartition>(0)), isNotNull);
- }
-
- void test_get() {
- AnalysisCache cache = new AnalysisCache(new List<CachePartition>(0));
- TestSource source = new TestSource();
- expect(cache.get(source), isNull);
- }
-
- void test_iterator() {
- CachePartition partition =
- new UniversalCachePartition(null, 8, new DefaultRetentionPolicy());
- AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
- TestSource source = new TestSource();
- DartEntry entry = new DartEntry();
- cache.put(source, entry);
- MapIterator<Source, SourceEntry> iterator = cache.iterator();
- expect(iterator.moveNext(), isTrue);
- expect(iterator.key, same(source));
- expect(iterator.value, same(entry));
- expect(iterator.moveNext(), isFalse);
- }
-
- /**
- * Verify that if multiple Source objects refer to the same file via
- * different URIs, they are treated as separate entries in the cache.
- */
- void test_lookup_distinguishes_uris() {
- CachePartition partition =
- new UniversalCachePartition(null, 8, new DefaultRetentionPolicy());
- AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
- JavaFile file = new JavaFile('baz.dart');
- Source source1 = new FileBasedSource(file);
- Source source2 =
- new FileBasedSource(file, Uri.parse('package:foo/baz.dart'));
- Source source3 =
- new FileBasedSource(file, Uri.parse('package:bar/baz.dart'));
- DartEntry entry1 = new DartEntry();
- DartEntry entry2 = new DartEntry();
- DartEntry entry3 = new DartEntry();
- cache.put(source1, entry1);
- cache.put(source2, entry2);
- cache.put(source3, entry3);
- expect(cache.get(source1), same(entry1));
- expect(cache.get(source2), same(entry2));
- expect(cache.get(source3), same(entry3));
- }
-
- void test_put_noFlush() {
- CachePartition partition =
- new UniversalCachePartition(null, 8, new DefaultRetentionPolicy());
- AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
- TestSource source = new TestSource();
- DartEntry entry = new DartEntry();
- cache.put(source, entry);
- expect(cache.get(source), same(entry));
- }
-
- void test_setMaxCacheSize() {
- CachePartition partition = new UniversalCachePartition(
- null, 8, new _AnalysisCacheTest_test_setMaxCacheSize());
- AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
- int size = 6;
- for (int i = 0; i < size; i++) {
- Source source = new TestSource("/test$i.dart");
- DartEntry entry = new DartEntry();
- entry.setValue(DartEntry.PARSED_UNIT, null);
- cache.put(source, entry);
- cache.accessedAst(source);
- }
- _assertNonFlushedCount(size, cache);
- int newSize = size - 2;
- partition.maxCacheSize = newSize;
- _assertNonFlushedCount(newSize, cache);
- }
-
- void test_size() {
- CachePartition partition =
- new UniversalCachePartition(null, 8, new DefaultRetentionPolicy());
- AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
- int size = 4;
- for (int i = 0; i < size; i++) {
- Source source = new TestSource("/test$i.dart");
- cache.put(source, new DartEntry());
- cache.accessedAst(source);
- }
- expect(cache.size(), size);
- }
-
- void _assertNonFlushedCount(int expectedCount, AnalysisCache cache) {
- int nonFlushedCount = 0;
- MapIterator<Source, SourceEntry> iterator = cache.iterator();
- while (iterator.moveNext()) {
- if (iterator.value.getState(DartEntry.PARSED_UNIT) !=
- CacheState.FLUSHED) {
- nonFlushedCount++;
- }
- }
- expect(nonFlushedCount, expectedCount);
- }
-}
-
-@reflectiveTest
-class AnalysisContextImplTest extends EngineTestCase {
- /**
- * An analysis context whose source factory is [sourceFactory].
- */
- AnalysisContextImpl _context;
-
- /**
- * The source factory associated with the analysis [context].
- */
- SourceFactory _sourceFactory;
-
- void fail_performAnalysisTask_importedLibraryDelete_html() {
- Source htmlSource = _addSource(
- "/page.html",
- r'''
-<html><body><script type="application/dart">
- import 'libB.dart';
- main() {print('hello dart');}
-</script></body></html>''');
- Source libBSource = _addSource("/libB.dart", "library libB;");
- _analyzeAll_assertFinished();
- expect(_context.getResolvedHtmlUnit(htmlSource), isNotNull,
- reason: "htmlUnit resolved 1");
- expect(
- _context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
- reason: "libB resolved 1");
- expect(!_hasAnalysisErrorWithErrorSeverity(_context.getErrors(htmlSource)),
- isTrue,
- reason: "htmlSource doesn't have errors");
- // remove libB.dart content and analyze
- _context.setContents(libBSource, null);
- _analyzeAll_assertFinished();
- expect(_context.getResolvedHtmlUnit(htmlSource), isNotNull,
- reason: "htmlUnit resolved 1");
- AnalysisErrorInfo errors = _context.getErrors(htmlSource);
- expect(_hasAnalysisErrorWithErrorSeverity(errors), isTrue,
- reason: "htmlSource has an error");
- }
-
- void fail_recordLibraryElements() {
- fail("Implement this");
- }
-
- @override
- void setUp() {
- _context = new AnalysisContextImpl();
- _sourceFactory = new SourceFactory([
- new DartUriResolver(DirectoryBasedDartSdk.defaultSdk),
- new FileUriResolver()
- ]);
- _context.sourceFactory = _sourceFactory;
- AnalysisOptionsImpl options =
- new AnalysisOptionsImpl.from(_context.analysisOptions);
- options.cacheSize = 256;
- _context.analysisOptions = options;
- }
-
- @override
- void tearDown() {
- _context = null;
- _sourceFactory = null;
- super.tearDown();
- }
-
- Future test_applyChanges_add() {
- SourcesChangedListener listener = new SourcesChangedListener();
- _context.onSourcesChanged.listen(listener.onData);
- expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
- Source source =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source);
- _context.applyChanges(changeSet);
- expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
- return pumpEventQueue().then((_) {
- listener.assertEvent(wereSourcesAdded: true);
- listener.assertNoMoreEvents();
- });
- }
-
- Future test_applyChanges_change() {
- SourcesChangedListener listener = new SourcesChangedListener();
- _context.onSourcesChanged.listen(listener.onData);
- expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
- Source source =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- ChangeSet changeSet1 = new ChangeSet();
- changeSet1.addedSource(source);
- _context.applyChanges(changeSet1);
- expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
- Source source2 =
- new FileBasedSource(FileUtilities2.createFile("/test2.dart"));
- ChangeSet changeSet2 = new ChangeSet();
- changeSet2.addedSource(source2);
- changeSet2.changedSource(source);
- _context.applyChanges(changeSet2);
- return pumpEventQueue().then((_) {
- listener.assertEvent(wereSourcesAdded: true);
- listener.assertEvent(wereSourcesAdded: true, changedSources: [source]);
- listener.assertNoMoreEvents();
- });
- }
-
- Future test_applyChanges_change_content() {
- SourcesChangedListener listener = new SourcesChangedListener();
- _context.onSourcesChanged.listen(listener.onData);
- expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
- Source source =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- ChangeSet changeSet1 = new ChangeSet();
- changeSet1.addedSource(source);
- _context.applyChanges(changeSet1);
- expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
- Source source2 =
- new FileBasedSource(FileUtilities2.createFile("/test2.dart"));
- ChangeSet changeSet2 = new ChangeSet();
- changeSet2.addedSource(source2);
- changeSet2.changedContent(source, 'library test;');
- _context.applyChanges(changeSet2);
- return pumpEventQueue().then((_) {
- listener.assertEvent(wereSourcesAdded: true);
- listener.assertEvent(wereSourcesAdded: true, changedSources: [source]);
- listener.assertNoMoreEvents();
- });
- }
-
- void test_applyChanges_change_flush_element() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source librarySource = _addSource(
- "/lib.dart",
- r'''
-library lib;
-int a = 0;''');
- expect(_context.computeLibraryElement(librarySource), isNotNull);
- _context.setContents(
- librarySource,
- r'''
-library lib;
-int aa = 0;''');
- expect(_context.getLibraryElement(librarySource), isNull);
- }
-
- Future test_applyChanges_change_multiple() {
- _context = AnalysisContextFactory.oldContextWithCore();
- SourcesChangedListener listener = new SourcesChangedListener();
- _context.onSourcesChanged.listen(listener.onData);
- _sourceFactory = _context.sourceFactory;
- String libraryContents1 = r'''
-library lib;
-part 'part.dart';
-int a = 0;''';
- Source librarySource = _addSource("/lib.dart", libraryContents1);
- String partContents1 = r'''
-part of lib;
-int b = a;''';
- Source partSource = _addSource("/part.dart", partContents1);
- _context.computeLibraryElement(librarySource);
- String libraryContents2 = r'''
-library lib;
-part 'part.dart';
-int aa = 0;''';
- _context.setContents(librarySource, libraryContents2);
- String partContents2 = r'''
-part of lib;
-int b = aa;''';
- _context.setContents(partSource, partContents2);
- _context.computeLibraryElement(librarySource);
- CompilationUnit libraryUnit =
- _context.resolveCompilationUnit2(librarySource, librarySource);
- CompilationUnit partUnit =
- _context.resolveCompilationUnit2(partSource, librarySource);
- TopLevelVariableDeclaration declaration =
- libraryUnit.declarations[0] as TopLevelVariableDeclaration;
- Element declarationElement = declaration.variables.variables[0].element;
- TopLevelVariableDeclaration use =
- partUnit.declarations[0] as TopLevelVariableDeclaration;
- Element useElement = (use.variables.variables[0].initializer
- as SimpleIdentifier).staticElement;
- expect((useElement as PropertyAccessorElement).variable,
- same(declarationElement));
- return pumpEventQueue().then((_) {
- listener.assertEvent(wereSourcesAdded: true);
- listener.assertEvent(changedSources: [librarySource]);
- listener.assertEvent(wereSourcesAdded: true);
- listener.assertEvent(changedSources: [partSource]);
- listener.assertEvent(changedSources: [librarySource]);
- listener.assertEvent(changedSources: [partSource]);
- listener.assertNoMoreEvents();
- });
- }
-
- Future test_applyChanges_change_range() {
- SourcesChangedListener listener = new SourcesChangedListener();
- _context.onSourcesChanged.listen(listener.onData);
- expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
- Source source =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- ChangeSet changeSet1 = new ChangeSet();
- changeSet1.addedSource(source);
- _context.applyChanges(changeSet1);
- expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
- Source source2 =
- new FileBasedSource(FileUtilities2.createFile("/test2.dart"));
- ChangeSet changeSet2 = new ChangeSet();
- changeSet2.addedSource(source2);
- changeSet2.changedRange(source, 'library test;', 0, 0, 13);
- _context.applyChanges(changeSet2);
- return pumpEventQueue().then((_) {
- listener.assertEvent(wereSourcesAdded: true);
- listener.assertEvent(wereSourcesAdded: true, changedSources: [source]);
- listener.assertNoMoreEvents();
- });
- }
-
- void test_applyChanges_empty() {
- _context.applyChanges(new ChangeSet());
- expect(_context.performAnalysisTask().changeNotices, isNull);
- }
-
- void test_applyChanges_overriddenSource() {
- // Note: addSource adds the source to the contentCache.
- Source source = _addSource("/test.dart", "library test;");
- _context.computeErrors(source);
- while (!_context.sourcesNeedingProcessing.isEmpty) {
- _context.performAnalysisTask();
- }
- // Adding the source as a changedSource should have no effect since
- // it is already overridden in the content cache.
- ChangeSet changeSet = new ChangeSet();
- changeSet.changedSource(source);
- _context.applyChanges(changeSet);
- expect(_context.sourcesNeedingProcessing, hasLength(0));
- }
-
- Future test_applyChanges_remove() {
- _context = AnalysisContextFactory.oldContextWithCore();
- SourcesChangedListener listener = new SourcesChangedListener();
- _context.onSourcesChanged.listen(listener.onData);
- _sourceFactory = _context.sourceFactory;
- String libAContents = r'''
-library libA;
-import 'libB.dart';''';
- Source libA = _addSource("/libA.dart", libAContents);
- String libBContents = "library libB;";
- Source libB = _addSource("/libB.dart", libBContents);
- LibraryElement libAElement = _context.computeLibraryElement(libA);
- List<LibraryElement> importedLibraries = libAElement.importedLibraries;
- expect(importedLibraries, hasLength(2));
- _context.computeErrors(libA);
- _context.computeErrors(libB);
- expect(_context.sourcesNeedingProcessing, hasLength(0));
- _context.setContents(libB, null);
- _removeSource(libB);
- List<Source> sources = _context.sourcesNeedingProcessing;
- expect(sources, hasLength(1));
- expect(sources[0], same(libA));
- libAElement = _context.computeLibraryElement(libA);
- importedLibraries = libAElement.importedLibraries;
- expect(importedLibraries, hasLength(1));
- return pumpEventQueue().then((_) {
- listener.assertEvent(wereSourcesAdded: true);
- listener.assertEvent(changedSources: [libA]);
- listener.assertEvent(wereSourcesAdded: true);
- listener.assertEvent(changedSources: [libB]);
- listener.assertEvent(changedSources: [libB]);
- listener.assertEvent(wereSourcesRemovedOrDeleted: true);
- listener.assertNoMoreEvents();
- });
- }
-
- /**
- * IDEA uses the following scenario:
- * 1. Add overlay.
- * 2. Change overlay.
- * 3. If the contents of the document buffer is the same as the contents
- * of the file, remove overlay.
- * So, we need to try to use incremental resolution for removing overlays too.
- */
- void test_applyChanges_remove_incremental() {
- MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
- Source source = resourceProvider
- .newFile(
- '/test.dart',
- r'''
-main() {
- print(1);
-}
-''')
- .createSource();
- _context = AnalysisContextFactory.oldContextWithCore();
- _context.analysisOptions = new AnalysisOptionsImpl()..incremental = true;
- _context.applyChanges(new ChangeSet()..addedSource(source));
- // remember compilation unit
- _analyzeAll_assertFinished();
- CompilationUnit unit = _context.getResolvedCompilationUnit2(source, source);
- // add overlay
- _context.setContents(
- source,
- r'''
-main() {
- print(12);
-}
-''');
- _analyzeAll_assertFinished();
- expect(_context.getResolvedCompilationUnit2(source, source), unit);
- // remove overlay
- _context.setContents(source, null);
- _context.validateCacheConsistency();
- _analyzeAll_assertFinished();
- expect(_context.getResolvedCompilationUnit2(source, source), unit);
- }
-
- Future test_applyChanges_removeContainer() {
- _context = AnalysisContextFactory.oldContextWithCore();
- SourcesChangedListener listener = new SourcesChangedListener();
- _context.onSourcesChanged.listen(listener.onData);
- _sourceFactory = _context.sourceFactory;
- String libAContents = r'''
-library libA;
-import 'libB.dart';''';
- Source libA = _addSource("/libA.dart", libAContents);
- String libBContents = "library libB;";
- Source libB = _addSource("/libB.dart", libBContents);
- _context.computeLibraryElement(libA);
- _context.computeErrors(libA);
- _context.computeErrors(libB);
- expect(_context.sourcesNeedingProcessing, hasLength(0));
- ChangeSet changeSet = new ChangeSet();
- SourceContainer removedContainer =
- new _AnalysisContextImplTest_test_applyChanges_removeContainer(libB);
- changeSet.removedContainer(removedContainer);
- _context.applyChanges(changeSet);
- List<Source> sources = _context.sourcesNeedingProcessing;
- expect(sources, hasLength(1));
- expect(sources[0], same(libA));
- return pumpEventQueue().then((_) {
- listener.assertEvent(wereSourcesAdded: true);
- listener.assertEvent(changedSources: [libA]);
- listener.assertEvent(wereSourcesAdded: true);
- listener.assertEvent(changedSources: [libB]);
- listener.assertEvent(wereSourcesRemovedOrDeleted: true);
- listener.assertNoMoreEvents();
- });
- }
-
- void test_computeDocumentationComment_block() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- String comment = "/** Comment */";
- Source source = _addSource(
- "/test.dart",
- """
-$comment
-class A {}""");
- LibraryElement libraryElement = _context.computeLibraryElement(source);
- expect(libraryElement, isNotNull);
- ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
- expect(libraryElement, isNotNull);
- expect(_context.computeDocumentationComment(classElement), comment);
- }
-
- void test_computeDocumentationComment_none() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource("/test.dart", "class A {}");
- LibraryElement libraryElement = _context.computeLibraryElement(source);
- expect(libraryElement, isNotNull);
- ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
- expect(libraryElement, isNotNull);
- expect(_context.computeDocumentationComment(classElement), isNull);
- }
-
- void test_computeDocumentationComment_null() {
- expect(_context.computeDocumentationComment(null), isNull);
- }
-
- void test_computeDocumentationComment_singleLine_multiple_EOL_n() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- String comment = "/// line 1\n/// line 2\n/// line 3\n";
- Source source = _addSource("/test.dart", "${comment}class A {}");
- LibraryElement libraryElement = _context.computeLibraryElement(source);
- expect(libraryElement, isNotNull);
- ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
- expect(libraryElement, isNotNull);
- String actual = _context.computeDocumentationComment(classElement);
- expect(actual, "/// line 1\n/// line 2\n/// line 3");
- }
-
- void test_computeDocumentationComment_singleLine_multiple_EOL_rn() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- String comment = "/// line 1\r\n/// line 2\r\n/// line 3\r\n";
- Source source = _addSource("/test.dart", "${comment}class A {}");
- LibraryElement libraryElement = _context.computeLibraryElement(source);
- expect(libraryElement, isNotNull);
- ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
- expect(libraryElement, isNotNull);
- String actual = _context.computeDocumentationComment(classElement);
- expect(actual, "/// line 1\n/// line 2\n/// line 3");
- }
-
- void test_computeErrors_dart_none() {
- Source source = _addSource("/lib.dart", "library lib;");
- List<AnalysisError> errors = _context.computeErrors(source);
- expect(errors, hasLength(0));
- }
-
- void test_computeErrors_dart_part() {
- Source librarySource =
- _addSource("/lib.dart", "library lib; part 'part.dart';");
- Source partSource = _addSource("/part.dart", "part of 'lib';");
- _context.parseCompilationUnit(librarySource);
- List<AnalysisError> errors = _context.computeErrors(partSource);
- expect(errors, isNotNull);
- expect(errors.length > 0, isTrue);
- }
-
- void test_computeErrors_dart_some() {
- Source source = _addSource("/lib.dart", "library 'lib';");
- List<AnalysisError> errors = _context.computeErrors(source);
- expect(errors, isNotNull);
- expect(errors.length > 0, isTrue);
- }
-
- void test_computeErrors_html_none() {
- Source source = _addSource("/test.html", "<html></html>");
- List<AnalysisError> errors = _context.computeErrors(source);
- expect(errors, hasLength(0));
- }
-
- void test_computeExportedLibraries_none() {
- Source source = _addSource("/test.dart", "library test;");
- expect(_context.computeExportedLibraries(source), hasLength(0));
- }
-
- void test_computeExportedLibraries_some() {
- // addSource("/lib1.dart", "library lib1;");
- // addSource("/lib2.dart", "library lib2;");
- Source source = _addSource(
- "/test.dart", "library test; export 'lib1.dart'; export 'lib2.dart';");
- expect(_context.computeExportedLibraries(source), hasLength(2));
- }
-
- void test_computeHtmlElement_nonHtml() {
- Source source = _addSource("/test.dart", "library test;");
- expect(_context.computeHtmlElement(source), isNull);
- }
-
- void test_computeHtmlElement_valid() {
- Source source = _addSource("/test.html", "<html></html>");
- HtmlElement element = _context.computeHtmlElement(source);
- expect(element, isNotNull);
- expect(_context.computeHtmlElement(source), same(element));
- }
-
- void test_computeImportedLibraries_none() {
- Source source = _addSource("/test.dart", "library test;");
- expect(_context.computeImportedLibraries(source), hasLength(0));
- }
-
- void test_computeImportedLibraries_some() {
- // addSource("/lib1.dart", "library lib1;");
- // addSource("/lib2.dart", "library lib2;");
- Source source = _addSource(
- "/test.dart", "library test; import 'lib1.dart'; import 'lib2.dart';");
- expect(_context.computeImportedLibraries(source), hasLength(2));
- }
-
- void test_computeKindOf_html() {
- Source source = _addSource("/test.html", "");
- expect(_context.computeKindOf(source), same(SourceKind.HTML));
- }
-
- void test_computeKindOf_library() {
- Source source = _addSource("/test.dart", "library lib;");
- expect(_context.computeKindOf(source), same(SourceKind.LIBRARY));
- }
-
- void test_computeKindOf_libraryAndPart() {
- Source source = _addSource("/test.dart", "library lib; part of lib;");
- expect(_context.computeKindOf(source), same(SourceKind.LIBRARY));
- }
-
- void test_computeKindOf_part() {
- Source source = _addSource("/test.dart", "part of lib;");
- expect(_context.computeKindOf(source), same(SourceKind.PART));
- }
-
- void test_computeLibraryElement() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource("/test.dart", "library lib;");
- LibraryElement element = _context.computeLibraryElement(source);
- expect(element, isNotNull);
- }
-
- void test_computeLineInfo_dart() {
- Source source = _addSource(
- "/test.dart",
- r'''
-library lib;
-
-main() {}''');
- LineInfo info = _context.computeLineInfo(source);
- expect(info, isNotNull);
- }
-
- void test_computeLineInfo_html() {
- Source source = _addSource(
- "/test.html",
- r'''
-<html>
- <body>
- <h1>A</h1>
- </body>
-</html>''');
- LineInfo info = _context.computeLineInfo(source);
- expect(info, isNotNull);
- }
-
- void test_computeResolvableCompilationUnit_dart_exception() {
- TestSource source = _addSourceWithException("/test.dart");
- try {
- _context.computeResolvableCompilationUnit(source);
- fail("Expected AnalysisException");
- } on AnalysisException {
- // Expected
- }
- }
-
- void test_computeResolvableCompilationUnit_html_exception() {
- Source source = _addSource("/lib.html", "<html></html>");
- try {
- _context.computeResolvableCompilationUnit(source);
- fail("Expected AnalysisException");
- } on AnalysisException {
- // Expected
- }
- }
-
- void test_computeResolvableCompilationUnit_valid() {
- Source source = _addSource("/lib.dart", "library lib;");
- CompilationUnit parsedUnit = _context.parseCompilationUnit(source);
- expect(parsedUnit, isNotNull);
- CompilationUnit resolvedUnit =
- _context.computeResolvableCompilationUnit(source);
- expect(resolvedUnit, isNotNull);
- expect(resolvedUnit, same(parsedUnit));
- }
-
- Future test_computeResolvedCompilationUnitAsync() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource("/lib.dart", "library lib;");
- // Complete all pending analysis tasks and flush the AST so that it won't
- // be available immediately.
- _performPendingAnalysisTasks();
- DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
- dartEntry.flushAstStructures();
- bool completed = false;
- _context
- .computeResolvedCompilationUnitAsync(source, source)
- .then((CompilationUnit unit) {
- expect(unit, isNotNull);
- completed = true;
- });
- return pumpEventQueue().then((_) {
- expect(completed, isFalse);
- _performPendingAnalysisTasks();
- }).then((_) => pumpEventQueue()).then((_) {
- expect(completed, isTrue);
- });
- }
-
- Future test_computeResolvedCompilationUnitAsync_afterDispose() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource("/lib.dart", "library lib;");
- // Complete all pending analysis tasks and flush the AST so that it won't
- // be available immediately.
- _performPendingAnalysisTasks();
- DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
- dartEntry.flushAstStructures();
- // Dispose of the context.
- _context.dispose();
- // Any attempt to start an asynchronous computation should return a future
- // which completes with error.
- CancelableFuture<CompilationUnit> future =
- _context.computeResolvedCompilationUnitAsync(source, source);
- bool completed = false;
- future.then((CompilationUnit unit) {
- fail('Future should have completed with error');
- }, onError: (error) {
- expect(error, new isInstanceOf<AnalysisNotScheduledError>());
- completed = true;
- });
- return pumpEventQueue().then((_) {
- expect(completed, isTrue);
- });
- }
-
- Future test_computeResolvedCompilationUnitAsync_cancel() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource("/lib.dart", "library lib;");
- // Complete all pending analysis tasks and flush the AST so that it won't
- // be available immediately.
- _performPendingAnalysisTasks();
- DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
- dartEntry.flushAstStructures();
- CancelableFuture<CompilationUnit> future =
- _context.computeResolvedCompilationUnitAsync(source, source);
- bool completed = false;
- future.then((CompilationUnit unit) {
- fail('Future should have been canceled');
- }, onError: (error) {
- expect(error, new isInstanceOf<FutureCanceledError>());
- completed = true;
- });
- expect(completed, isFalse);
- expect(_context.pendingFutureSources_forTesting, isNotEmpty);
- future.cancel();
- expect(_context.pendingFutureSources_forTesting, isEmpty);
- return pumpEventQueue().then((_) {
- expect(completed, isTrue);
- expect(_context.pendingFutureSources_forTesting, isEmpty);
- });
- }
-
- Future test_computeResolvedCompilationUnitAsync_dispose() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource("/lib.dart", "library lib;");
- // Complete all pending analysis tasks and flush the AST so that it won't
- // be available immediately.
- _performPendingAnalysisTasks();
- DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
- dartEntry.flushAstStructures();
- CancelableFuture<CompilationUnit> future =
- _context.computeResolvedCompilationUnitAsync(source, source);
- bool completed = false;
- future.then((CompilationUnit unit) {
- fail('Future should have completed with error');
- }, onError: (error) {
- expect(error, new isInstanceOf<AnalysisNotScheduledError>());
- completed = true;
- });
- expect(completed, isFalse);
- expect(_context.pendingFutureSources_forTesting, isNotEmpty);
- // Disposing of the context should cause all pending futures to complete
- // with AnalysisNotScheduled, so that no clients are left hanging.
- _context.dispose();
- expect(_context.pendingFutureSources_forTesting, isEmpty);
- return pumpEventQueue().then((_) {
- expect(completed, isTrue);
- expect(_context.pendingFutureSources_forTesting, isEmpty);
- });
- }
-
- Future test_computeResolvedCompilationUnitAsync_unrelatedLibrary() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source librarySource = _addSource("/lib.dart", "library lib;");
- Source partSource = _addSource("/part.dart", "part of foo;");
- bool completed = false;
- _context
- .computeResolvedCompilationUnitAsync(partSource, librarySource)
- .then((_) {
- fail('Expected resolution to fail');
- }, onError: (e) {
- expect(e, new isInstanceOf<AnalysisNotScheduledError>());
- completed = true;
- });
- return pumpEventQueue().then((_) {
- expect(completed, isFalse);
- _performPendingAnalysisTasks();
- }).then((_) => pumpEventQueue()).then((_) {
- expect(completed, isTrue);
- });
- }
-
- void test_configurationData() {
- var key = new newContext.ResultDescriptor('test_key', '');
- var testData = ['test', 'data'];
- _context.setConfigurationData(key, testData);
- expect(_context.getConfigurationData(key), testData);
- var unusedKey = new newContext.ResultDescriptor('unused_key', '');
- expect(_context.getConfigurationData(unusedKey), null);
- }
-
- void test_dispose() {
- expect(_context.isDisposed, isFalse);
- _context.dispose();
- expect(_context.isDisposed, isTrue);
- }
-
- void test_exists_false() {
- TestSource source = new TestSource();
- source.exists2 = false;
- expect(_context.exists(source), isFalse);
- }
-
- void test_exists_null() {
- expect(_context.exists(null), isFalse);
- }
-
- void test_exists_overridden() {
- Source source = new TestSource();
- _context.setContents(source, "");
- expect(_context.exists(source), isTrue);
- }
-
- void test_exists_true() {
- expect(_context.exists(new AnalysisContextImplTest_Source_exists_true()),
- isTrue);
- }
-
- void test_getAnalysisOptions() {
- expect(_context.analysisOptions, isNotNull);
- }
-
- void test_getContents_fromSource() {
- String content = "library lib;";
- TimestampedData<String> contents =
- _context.getContents(new TestSource('/test.dart', content));
- expect(contents.data.toString(), content);
- }
-
- void test_getContents_overridden() {
- String content = "library lib;";
- Source source = new TestSource();
- _context.setContents(source, content);
- TimestampedData<String> contents = _context.getContents(source);
- expect(contents.data.toString(), content);
- }
-
- void test_getContents_unoverridden() {
- String content = "library lib;";
- Source source = new TestSource('/test.dart', content);
- _context.setContents(source, "part of lib;");
- _context.setContents(source, null);
- TimestampedData<String> contents = _context.getContents(source);
- expect(contents.data.toString(), content);
- }
-
- void test_getDeclaredVariables() {
- _context = AnalysisContextFactory.oldContextWithCore();
- expect(_context.declaredVariables, isNotNull);
- }
-
- void test_getElement() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- LibraryElement core =
- _context.computeLibraryElement(_sourceFactory.forUri("dart:core"));
- expect(core, isNotNull);
- ClassElement classObject =
- _findClass(core.definingCompilationUnit, "Object");
- expect(classObject, isNotNull);
- ElementLocation location = classObject.location;
- Element element = _context.getElement(location);
- expect(element, same(classObject));
- }
-
- void test_getElement_constructor_named() {
- Source source = _addSource(
- "/lib.dart",
- r'''
-class A {
- A.named() {}
-}''');
- _analyzeAll_assertFinished();
- LibraryElement library = _context.computeLibraryElement(source);
- ClassElement classA = _findClass(library.definingCompilationUnit, "A");
- ConstructorElement constructor = classA.constructors[0];
- ElementLocation location = constructor.location;
- Element element = _context.getElement(location);
- expect(element, same(constructor));
- }
-
- void test_getElement_constructor_unnamed() {
- Source source = _addSource(
- "/lib.dart",
- r'''
-class A {
- A() {}
-}''');
- _analyzeAll_assertFinished();
- LibraryElement library = _context.computeLibraryElement(source);
- ClassElement classA = _findClass(library.definingCompilationUnit, "A");
- ConstructorElement constructor = classA.constructors[0];
- ElementLocation location = constructor.location;
- Element element = _context.getElement(location);
- expect(element, same(constructor));
- }
-
- void test_getElement_enum() {
- Source source = _addSource('/test.dart', 'enum MyEnum {A, B, C}');
- _analyzeAll_assertFinished();
- LibraryElement library = _context.computeLibraryElement(source);
- ClassElement myEnum = library.definingCompilationUnit.getEnum('MyEnum');
- ElementLocation location = myEnum.location;
- Element element = _context.getElement(location);
- expect(element, same(myEnum));
- }
-
- void test_getErrors_dart_none() {
- Source source = _addSource("/lib.dart", "library lib;");
- List<AnalysisError> errors = _context.getErrors(source).errors;
- expect(errors, hasLength(0));
- _context.computeErrors(source);
- errors = _context.getErrors(source).errors;
- expect(errors, hasLength(0));
- }
-
- void test_getErrors_dart_some() {
- Source source = _addSource("/lib.dart", "library 'lib';");
- List<AnalysisError> errors = _context.getErrors(source).errors;
- expect(errors, hasLength(0));
- _context.computeErrors(source);
- errors = _context.getErrors(source).errors;
- expect(errors, hasLength(1));
- }
-
- void test_getErrors_html_none() {
- Source source = _addSource("/test.html", "<html></html>");
- List<AnalysisError> errors = _context.getErrors(source).errors;
- expect(errors, hasLength(0));
- _context.computeErrors(source);
- errors = _context.getErrors(source).errors;
- expect(errors, hasLength(0));
- }
-
- void test_getErrors_html_some() {
- Source source = _addSource(
- "/test.html",
- r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-</head></html>''');
- List<AnalysisError> errors = _context.getErrors(source).errors;
- expect(errors, hasLength(0));
- _context.computeErrors(source);
- errors = _context.getErrors(source).errors;
- expect(errors, hasLength(1));
- }
-
- void test_getHtmlElement_dart() {
- Source source = _addSource("/test.dart", "");
- expect(_context.getHtmlElement(source), isNull);
- expect(_context.computeHtmlElement(source), isNull);
- expect(_context.getHtmlElement(source), isNull);
- }
-
- void test_getHtmlElement_html() {
- Source source = _addSource("/test.html", "<html></html>");
- HtmlElement element = _context.getHtmlElement(source);
- expect(element, isNull);
- _context.computeHtmlElement(source);
- element = _context.getHtmlElement(source);
- expect(element, isNotNull);
- }
-
- void test_getHtmlFilesReferencing_html() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source htmlSource = _addSource(
- "/test.html",
- r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
- Source librarySource = _addSource("/test.dart", "library lib;");
- Source secondHtmlSource = _addSource("/test.html", "<html></html>");
- _context.computeLibraryElement(librarySource);
- List<Source> result = _context.getHtmlFilesReferencing(secondHtmlSource);
- expect(result, hasLength(0));
- _context.parseHtmlUnit(htmlSource);
- result = _context.getHtmlFilesReferencing(secondHtmlSource);
- expect(result, hasLength(0));
- }
-
- void test_getHtmlFilesReferencing_library() {
- Source htmlSource = _addSource(
- "/test.html",
- r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
- Source librarySource = _addSource("/test.dart", "library lib;");
- List<Source> result = _context.getHtmlFilesReferencing(librarySource);
- expect(result, hasLength(0));
- _context.parseHtmlUnit(htmlSource);
- result = _context.getHtmlFilesReferencing(librarySource);
- expect(result, hasLength(1));
- expect(result[0], htmlSource);
- }
-
- void test_getHtmlFilesReferencing_part() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source htmlSource = _addSource(
- "/test.html",
- r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
- Source librarySource =
- _addSource("/test.dart", "library lib; part 'part.dart';");
- Source partSource = _addSource("/part.dart", "part of lib;");
- _context.computeLibraryElement(librarySource);
- List<Source> result = _context.getHtmlFilesReferencing(partSource);
- expect(result, hasLength(0));
- _context.parseHtmlUnit(htmlSource);
- result = _context.getHtmlFilesReferencing(partSource);
- expect(result, hasLength(1));
- expect(result[0], htmlSource);
- }
-
- void test_getHtmlSources() {
- List<Source> sources = _context.htmlSources;
- expect(sources, hasLength(0));
- Source source = _addSource("/test.html", "");
- _context.computeKindOf(source);
- sources = _context.htmlSources;
- expect(sources, hasLength(1));
- expect(sources[0], source);
- }
-
- void test_getKindOf_html() {
- Source source = _addSource("/test.html", "");
- expect(_context.getKindOf(source), same(SourceKind.HTML));
- }
-
- void test_getKindOf_library() {
- Source source = _addSource("/test.dart", "library lib;");
- expect(_context.getKindOf(source), same(SourceKind.UNKNOWN));
- _context.computeKindOf(source);
- expect(_context.getKindOf(source), same(SourceKind.LIBRARY));
- }
-
- void test_getKindOf_part() {
- Source source = _addSource("/test.dart", "part of lib;");
- expect(_context.getKindOf(source), same(SourceKind.UNKNOWN));
- _context.computeKindOf(source);
- expect(_context.getKindOf(source), same(SourceKind.PART));
- }
-
- void test_getKindOf_unknown() {
- Source source = _addSource("/test.css", "");
- expect(_context.getKindOf(source), same(SourceKind.UNKNOWN));
- }
-
- void test_getLaunchableClientLibrarySources() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- List<Source> sources = _context.launchableClientLibrarySources;
- expect(sources, hasLength(0));
- Source source = _addSource(
- "/test.dart",
- r'''
-import 'dart:html';
-main() {}''');
- _context.computeLibraryElement(source);
- sources = _context.launchableClientLibrarySources;
- expect(sources, hasLength(1));
- }
-
- void test_getLaunchableServerLibrarySources() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- List<Source> sources = _context.launchableServerLibrarySources;
- expect(sources, hasLength(0));
- Source source = _addSource("/test.dart", "main() {}");
- _context.computeLibraryElement(source);
- sources = _context.launchableServerLibrarySources;
- expect(sources, hasLength(1));
- }
-
- void test_getLibrariesContaining() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source librarySource = _addSource(
- "/lib.dart",
- r'''
-library lib;
-part 'part.dart';''');
- Source partSource = _addSource("/part.dart", "part of lib;");
- _context.computeLibraryElement(librarySource);
- List<Source> result = _context.getLibrariesContaining(librarySource);
- expect(result, hasLength(1));
- expect(result[0], librarySource);
- result = _context.getLibrariesContaining(partSource);
- expect(result, hasLength(1));
- expect(result[0], librarySource);
- }
-
- void test_getLibrariesDependingOn() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source libASource = _addSource("/libA.dart", "library libA;");
- _addSource("/libB.dart", "library libB;");
- Source lib1Source = _addSource(
- "/lib1.dart",
- r'''
-library lib1;
-import 'libA.dart';
-export 'libB.dart';''');
- Source lib2Source = _addSource(
- "/lib2.dart",
- r'''
-library lib2;
-import 'libB.dart';
-export 'libA.dart';''');
- _context.computeLibraryElement(lib1Source);
- _context.computeLibraryElement(lib2Source);
- List<Source> result = _context.getLibrariesDependingOn(libASource);
- expect(result, unorderedEquals([lib1Source, lib2Source]));
- }
-
- void test_getLibrariesReferencedFromHtml() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source htmlSource = _addSource(
- "/test.html",
- r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
- Source librarySource = _addSource("/test.dart", "library lib;");
- _context.computeLibraryElement(librarySource);
- _context.parseHtmlUnit(htmlSource);
- List<Source> result = _context.getLibrariesReferencedFromHtml(htmlSource);
- expect(result, hasLength(1));
- expect(result[0], librarySource);
- }
-
- void test_getLibrariesReferencedFromHtml_no() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source htmlSource = _addSource(
- "/test.html",
- r'''
-<html><head>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
- _addSource("/test.dart", "library lib;");
- _context.parseHtmlUnit(htmlSource);
- List<Source> result = _context.getLibrariesReferencedFromHtml(htmlSource);
- expect(result, hasLength(0));
- }
-
- void test_getLibraryElement() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource("/test.dart", "library lib;");
- LibraryElement element = _context.getLibraryElement(source);
- expect(element, isNull);
- _context.computeLibraryElement(source);
- element = _context.getLibraryElement(source);
- expect(element, isNotNull);
- }
-
- void test_getLibrarySources() {
- List<Source> sources = _context.librarySources;
- int originalLength = sources.length;
- Source source = _addSource("/test.dart", "library lib;");
- _context.computeKindOf(source);
- sources = _context.librarySources;
- expect(sources, hasLength(originalLength + 1));
- for (Source returnedSource in sources) {
- if (returnedSource == source) {
- return;
- }
- }
- fail("The added source was not in the list of library sources");
- }
-
- void test_getLineInfo() {
- Source source = _addSource(
- "/test.dart",
- r'''
-library lib;
-
-main() {}''');
- LineInfo info = _context.getLineInfo(source);
- expect(info, isNull);
- _context.parseCompilationUnit(source);
- info = _context.getLineInfo(source);
- expect(info, isNotNull);
- }
-
- void test_getModificationStamp_fromSource() {
- int stamp = 42;
- expect(
- _context.getModificationStamp(
- new AnalysisContextImplTest_Source_getModificationStamp_fromSource(
- stamp)),
- stamp);
- }
-
- void test_getModificationStamp_overridden() {
- int stamp = 42;
- Source source =
- new AnalysisContextImplTest_Source_getModificationStamp_overridden(
- stamp);
- _context.setContents(source, "");
- expect(stamp != _context.getModificationStamp(source), isTrue);
- }
-
- void test_getPublicNamespace_element() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource("/test.dart", "class A {}");
- LibraryElement library = _context.computeLibraryElement(source);
- Namespace namespace = _context.getPublicNamespace(library);
- expect(namespace, isNotNull);
- EngineTestCase.assertInstanceOf(
- (obj) => obj is ClassElement, ClassElement, namespace.get("A"));
- }
-
- void test_getResolvedCompilationUnit_library() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource("/lib.dart", "library libb;");
- LibraryElement library = _context.computeLibraryElement(source);
- expect(_context.getResolvedCompilationUnit(source, library), isNotNull);
- _context.setContents(source, "library lib;");
- expect(_context.getResolvedCompilationUnit(source, library), isNull);
- }
-
- void test_getResolvedCompilationUnit_library_null() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource("/lib.dart", "library lib;");
- expect(_context.getResolvedCompilationUnit(source, null), isNull);
- }
-
- void test_getResolvedCompilationUnit_source_dart() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource("/lib.dart", "library lib;");
- expect(_context.getResolvedCompilationUnit2(source, source), isNull);
- _context.resolveCompilationUnit2(source, source);
- expect(_context.getResolvedCompilationUnit2(source, source), isNotNull);
- }
-
- void test_getResolvedCompilationUnit_source_html() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource("/test.html", "<html></html>");
- expect(_context.getResolvedCompilationUnit2(source, source), isNull);
- expect(_context.resolveCompilationUnit2(source, source), isNull);
- expect(_context.getResolvedCompilationUnit2(source, source), isNull);
- }
-
- void test_getResolvedHtmlUnit() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource("/test.html", "<html></html>");
- expect(_context.getResolvedHtmlUnit(source), isNull);
- _context.resolveHtmlUnit(source);
- expect(_context.getResolvedHtmlUnit(source), isNotNull);
- }
-
- void test_getSourceFactory() {
- expect(_context.sourceFactory, same(_sourceFactory));
- }
-
- void test_getSourcesWithFullName() {
- String filePath = '/foo/lib/file.dart';
- List<Source> expected = <Source>[];
- ChangeSet changeSet = new ChangeSet();
-
- TestSourceWithUri source1 =
- new TestSourceWithUri(filePath, Uri.parse('file://$filePath'));
- expected.add(source1);
- changeSet.addedSource(source1);
-
- TestSourceWithUri source2 =
- new TestSourceWithUri(filePath, Uri.parse('package:foo/file.dart'));
- expected.add(source2);
- changeSet.addedSource(source2);
-
- _context.applyChanges(changeSet);
- expect(
- _context.getSourcesWithFullName(filePath), unorderedEquals(expected));
- }
-
- void test_getStatistics() {
- AnalysisContextStatistics statistics = _context.statistics;
- expect(statistics, isNotNull);
- // The following lines are fragile.
- // The values depend on the number of libraries in the SDK.
-// assertLength(0, statistics.getCacheRows());
-// assertLength(0, statistics.getExceptions());
-// assertLength(0, statistics.getSources());
- }
-
- Future test_implicitAnalysisEvents_added() async {
- AnalyzedSourcesListener listener = new AnalyzedSourcesListener();
- _context.implicitAnalysisEvents.listen(listener.onData);
- //
- // Create a file that references an file that is not explicitly being
- // analyzed and fully analyze it. Ensure that the listener is told about
- // the implicitly analyzed file.
- //
- Source sourceA = _addSource('/a.dart', "library a; import 'b.dart';");
- Source sourceB = _createSource('/b.dart', "library b;");
- _context.computeErrors(sourceA);
- await pumpEventQueue();
- listener.expectAnalyzed(sourceB);
- }
-
- void test_isClientLibrary_dart() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource(
- "/test.dart",
- r'''
-import 'dart:html';
-
-main() {}''');
- expect(_context.isClientLibrary(source), isFalse);
- expect(_context.isServerLibrary(source), isFalse);
- _context.computeLibraryElement(source);
- expect(_context.isClientLibrary(source), isTrue);
- expect(_context.isServerLibrary(source), isFalse);
- }
-
- void test_isClientLibrary_html() {
- Source source = _addSource("/test.html", "<html></html>");
- expect(_context.isClientLibrary(source), isFalse);
- }
-
- void test_isServerLibrary_dart() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource(
- "/test.dart",
- r'''
-library lib;
-
-main() {}''');
- expect(_context.isClientLibrary(source), isFalse);
- expect(_context.isServerLibrary(source), isFalse);
- _context.computeLibraryElement(source);
- expect(_context.isClientLibrary(source), isFalse);
- expect(_context.isServerLibrary(source), isTrue);
- }
-
- void test_isServerLibrary_html() {
- Source source = _addSource("/test.html", "<html></html>");
- expect(_context.isServerLibrary(source), isFalse);
- }
-
- void test_parseCompilationUnit_errors() {
- Source source = _addSource("/lib.dart", "library {");
- CompilationUnit compilationUnit = _context.parseCompilationUnit(source);
- expect(compilationUnit, isNotNull);
- List<AnalysisError> errors = _context.getErrors(source).errors;
- expect(errors, isNotNull);
- expect(errors.length > 0, isTrue);
- }
-
- void test_parseCompilationUnit_exception() {
- Source source = _addSourceWithException("/test.dart");
- try {
- _context.parseCompilationUnit(source);
- fail("Expected AnalysisException");
- } on AnalysisException {
- // Expected
- }
- }
-
- void test_parseCompilationUnit_html() {
- Source source = _addSource("/test.html", "<html></html>");
- expect(_context.parseCompilationUnit(source), isNull);
- }
-
- void test_parseCompilationUnit_noErrors() {
- Source source = _addSource("/lib.dart", "library lib;");
- CompilationUnit compilationUnit = _context.parseCompilationUnit(source);
- expect(compilationUnit, isNotNull);
- expect(_context.getErrors(source).errors, hasLength(0));
- }
-
- void test_parseCompilationUnit_nonExistentSource() {
- Source source =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- try {
- _context.parseCompilationUnit(source);
- fail("Expected AnalysisException because file does not exist");
- } on AnalysisException {
- // Expected result
- }
- }
-
- void test_parseHtmlUnit_noErrors() {
- Source source = _addSource("/lib.html", "<html></html>");
- ht.HtmlUnit unit = _context.parseHtmlUnit(source);
- expect(unit, isNotNull);
- }
-
- void test_parseHtmlUnit_resolveDirectives() {
- Source libSource = _addSource(
- "/lib.dart",
- r'''
-library lib;
-class ClassA {}''');
- Source source = _addSource(
- "/lib.html",
- r'''
-<html>
-<head>
- <script type='application/dart'>
- import 'lib.dart';
- ClassA v = null;
- </script>
-</head>
-<body>
-</body>
-</html>''');
- ht.HtmlUnit unit = _context.parseHtmlUnit(source);
- // import directive should be resolved
- ht.XmlTagNode htmlNode = unit.tagNodes[0];
- ht.XmlTagNode headNode = htmlNode.tagNodes[0];
- ht.HtmlScriptTagNode scriptNode = headNode.tagNodes[0];
- CompilationUnit script = scriptNode.script;
- ImportDirective importNode = script.directives[0] as ImportDirective;
- expect(importNode.uriContent, isNotNull);
- expect(importNode.source, libSource);
- }
-
- void test_performAnalysisTask_addPart() {
- Source libSource = _addSource(
- "/lib.dart",
- r'''
-library lib;
-part 'part.dart';''');
- // run all tasks without part
- _analyzeAll_assertFinished();
- // add part and run all tasks
- Source partSource = _addSource(
- "/part.dart",
- r'''
-part of lib;
-''');
- _analyzeAll_assertFinished();
- // "libSource" should be here
- List<Source> librariesWithPart =
- _context.getLibrariesContaining(partSource);
- expect(librariesWithPart, unorderedEquals([libSource]));
- }
-
- void test_performAnalysisTask_changeLibraryContents() {
- Source libSource =
- _addSource("/test.dart", "library lib; part 'test-part.dart';");
- Source partSource = _addSource("/test-part.dart", "part of lib;");
- _analyzeAll_assertFinished();
- expect(
- _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
- reason: "library resolved 1");
- expect(
- _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
- reason: "part resolved 1");
- // update and analyze #1
- _context.setContents(libSource, "library lib;");
- expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
- reason: "library changed 2");
- expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
- reason: "part changed 2");
- _analyzeAll_assertFinished();
- expect(
- _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
- reason: "library resolved 2");
- expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
- reason: "part resolved 2");
- // update and analyze #2
- _context.setContents(libSource, "library lib; part 'test-part.dart';");
- expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
- reason: "library changed 3");
- expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
- reason: "part changed 3");
- _analyzeAll_assertFinished();
- expect(
- _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
- reason: "library resolved 2");
- expect(
- _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
- reason: "part resolved 3");
- }
-
- void test_performAnalysisTask_changeLibraryThenPartContents() {
- Source libSource =
- _addSource("/test.dart", "library lib; part 'test-part.dart';");
- Source partSource = _addSource("/test-part.dart", "part of lib;");
- _analyzeAll_assertFinished();
- expect(
- _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
- reason: "library resolved 1");
- expect(
- _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
- reason: "part resolved 1");
- // update and analyze #1
- _context.setContents(libSource, "library lib;");
- expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
- reason: "library changed 2");
- expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
- reason: "part changed 2");
- _analyzeAll_assertFinished();
- expect(
- _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
- reason: "library resolved 2");
- expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
- reason: "part resolved 2");
- // update and analyze #2
- _context.setContents(partSource, "part of lib; // 1");
- // Assert that changing the part's content does not effect the library
- // now that it is no longer part of that library
- expect(
- _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
- reason: "library changed 3");
- expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
- reason: "part changed 3");
- _analyzeAll_assertFinished();
- expect(
- _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
- reason: "library resolved 3");
- expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
- reason: "part resolved 3");
- }
-
- void test_performAnalysisTask_changePartContents_makeItAPart() {
- Source libSource = _addSource(
- "/lib.dart",
- r'''
-library lib;
-part 'part.dart';
-void f(x) {}''');
- Source partSource = _addSource("/part.dart", "void g() { f(null); }");
- _analyzeAll_assertFinished();
- expect(
- _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
- reason: "library resolved 1");
- expect(
- _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
- reason: "part resolved 1");
- // update and analyze
- _context.setContents(
- partSource,
- r'''
-part of lib;
-void g() { f(null); }''');
- expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
- reason: "library changed 2");
- expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
- reason: "part changed 2");
- _analyzeAll_assertFinished();
- expect(
- _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
- reason: "library resolved 2");
- expect(
- _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
- reason: "part resolved 2");
- expect(_context.getErrors(libSource).errors, hasLength(0));
- expect(_context.getErrors(partSource).errors, hasLength(0));
- }
-
- /**
- * https://code.google.com/p/dart/issues/detail?id=12424
- */
- void test_performAnalysisTask_changePartContents_makeItNotPart() {
- Source libSource = _addSource(
- "/lib.dart",
- r'''
-library lib;
-part 'part.dart';
-void f(x) {}''');
- Source partSource = _addSource(
- "/part.dart",
- r'''
-part of lib;
-void g() { f(null); }''');
- _analyzeAll_assertFinished();
- expect(_context.getErrors(libSource).errors, hasLength(0));
- expect(_context.getErrors(partSource).errors, hasLength(0));
- // Remove 'part' directive, which should make "f(null)" an error.
- _context.setContents(
- partSource,
- r'''
-//part of lib;
-void g() { f(null); }''');
- _analyzeAll_assertFinished();
- expect(_context.getErrors(libSource).errors.length != 0, isTrue);
- }
-
- void test_performAnalysisTask_changePartContents_noSemanticChanges() {
- Source libSource =
- _addSource("/test.dart", "library lib; part 'test-part.dart';");
- Source partSource = _addSource("/test-part.dart", "part of lib;");
- _analyzeAll_assertFinished();
- expect(
- _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
- reason: "library resolved 1");
- expect(
- _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
- reason: "part resolved 1");
- // update and analyze #1
- _context.setContents(partSource, "part of lib; // 1");
- expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
- reason: "library changed 2");
- expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
- reason: "part changed 2");
- _analyzeAll_assertFinished();
- expect(
- _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
- reason: "library resolved 2");
- expect(
- _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
- reason: "part resolved 2");
- // update and analyze #2
- _context.setContents(partSource, "part of lib; // 12");
- expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
- reason: "library changed 3");
- expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
- reason: "part changed 3");
- _analyzeAll_assertFinished();
- expect(
- _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
- reason: "library resolved 3");
- expect(
- _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
- reason: "part resolved 3");
- }
-
- void test_performAnalysisTask_getContentException_dart() {
- // add source that throw an exception on "get content"
- Source source = new _Source_getContent_throwException('test.dart');
- {
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source);
- _context.applyChanges(changeSet);
- }
- // prepare errors
- _analyzeAll_assertFinished();
- List<AnalysisError> errors = _context.getErrors(source).errors;
- // validate errors
- expect(errors, hasLength(1));
- AnalysisError error = errors[0];
- expect(error.source, same(source));
- expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
- }
-
- void test_performAnalysisTask_getContentException_html() {
- // add source that throw an exception on "get content"
- Source source = new _Source_getContent_throwException('test.html');
- {
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source);
- _context.applyChanges(changeSet);
- }
- // prepare errors
- _analyzeAll_assertFinished();
- List<AnalysisError> errors = _context.getErrors(source).errors;
- // validate errors
- expect(errors, hasLength(1));
- AnalysisError error = errors[0];
- expect(error.source, same(source));
- expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
- }
-
- void test_performAnalysisTask_importedLibraryAdd() {
- Source libASource =
- _addSource("/libA.dart", "library libA; import 'libB.dart';");
- _analyzeAll_assertFinished();
- expect(
- _context.getResolvedCompilationUnit2(libASource, libASource), isNotNull,
- reason: "libA resolved 1");
- expect(_hasAnalysisErrorWithErrorSeverity(_context.getErrors(libASource)),
- isTrue,
- reason: "libA has an error");
- // add libB.dart and analyze
- Source libBSource = _addSource("/libB.dart", "library libB;");
- _analyzeAll_assertFinished();
- expect(
- _context.getResolvedCompilationUnit2(libASource, libASource), isNotNull,
- reason: "libA resolved 2");
- expect(
- _context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
- reason: "libB resolved 2");
- expect(!_hasAnalysisErrorWithErrorSeverity(_context.getErrors(libASource)),
- isTrue,
- reason: "libA doesn't have errors");
- }
-
- void test_performAnalysisTask_importedLibraryAdd_html() {
- Source htmlSource = _addSource(
- "/page.html",
- r'''
-<html><body><script type="application/dart">
- import '/libB.dart';
- main() {print('hello dart');}
-</script></body></html>''');
- _analyzeAll_assertFinished();
- expect(_context.getResolvedHtmlUnit(htmlSource), isNotNull,
- reason: "htmlUnit resolved 1");
- expect(_hasAnalysisErrorWithErrorSeverity(_context.getErrors(htmlSource)),
- isTrue,
- reason: "htmlSource has an error");
- // add libB.dart and analyze
- Source libBSource = _addSource("/libB.dart", "library libB;");
- _analyzeAll_assertFinished();
- expect(_context.getResolvedHtmlUnit(htmlSource), isNotNull,
- reason: "htmlUnit resolved 1");
- expect(
- _context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
- reason: "libB resolved 2");
- // TODO (danrubel) commented out to fix red bots
-// AnalysisErrorInfo errors = _context.getErrors(htmlSource);
-// expect(
-// !_hasAnalysisErrorWithErrorSeverity(errors),
-// isTrue,
-// reason: "htmlSource doesn't have errors");
- }
-
- void test_performAnalysisTask_importedLibraryDelete() {
- Source libASource =
- _addSource("/libA.dart", "library libA; import 'libB.dart';");
- Source libBSource = _addSource("/libB.dart", "library libB;");
- _analyzeAll_assertFinished();
- expect(
- _context.getResolvedCompilationUnit2(libASource, libASource), isNotNull,
- reason: "libA resolved 1");
- expect(
- _context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
- reason: "libB resolved 1");
- expect(!_hasAnalysisErrorWithErrorSeverity(_context.getErrors(libASource)),
- isTrue,
- reason: "libA doesn't have errors");
- // remove libB.dart content and analyze
- _context.setContents(libBSource, null);
- _analyzeAll_assertFinished();
- expect(
- _context.getResolvedCompilationUnit2(libASource, libASource), isNotNull,
- reason: "libA resolved 2");
- expect(_hasAnalysisErrorWithErrorSeverity(_context.getErrors(libASource)),
- isTrue,
- reason: "libA has an error");
- }
-
- void test_performAnalysisTask_IOException() {
- TestSource source = _addSourceWithException2("/test.dart", "library test;");
- int oldTimestamp = _context.getModificationStamp(source);
- source.generateExceptionOnRead = false;
- _analyzeAll_assertFinished();
- expect(source.readCount, 1);
- source.generateExceptionOnRead = true;
- do {
- _changeSource(source, "");
- // Ensure that the timestamp differs,
- // so that analysis engine notices the change
- } while (oldTimestamp == _context.getModificationStamp(source));
- _analyzeAll_assertFinished();
- expect(source.readCount, 2);
- }
-
- void test_performAnalysisTask_missingPart() {
- Source source =
- _addSource("/test.dart", "library lib; part 'no-such-file.dart';");
- _analyzeAll_assertFinished();
- expect(_context.getLibraryElement(source), isNotNull,
- reason: "performAnalysisTask failed to compute an element model");
- }
-
- void test_performAnalysisTask_modifiedAfterParse() {
- // TODO(scheglov) no threads in Dart
-// Source source = _addSource("/test.dart", "library lib;");
-// int initialTime = _context.getModificationStamp(source);
-// List<Source> sources = new List<Source>();
-// sources.add(source);
-// _context.analysisPriorityOrder = sources;
-// _context.parseCompilationUnit(source);
-// while (initialTime == JavaSystem.currentTimeMillis()) {
-// Thread.sleep(1);
-// // Force the modification time to be different.
-// }
-// _context.setContents(source, "library test;");
-// JUnitTestCase.assertTrue(initialTime != _context.getModificationStamp(source));
-// _analyzeAll_assertFinished();
-// JUnitTestCase.assertNotNullMsg("performAnalysisTask failed to compute an element model", _context.getLibraryElement(source));
- }
-
- void test_resolveCompilationUnit_import_relative() {
- _context = AnalysisContextFactory.oldContextWithCore();
- Source sourceA =
- _addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}");
- _addSource("/libB.dart", "library libB; class B{}");
- CompilationUnit compilationUnit =
- _context.resolveCompilationUnit2(sourceA, sourceA);
- LibraryElement library = compilationUnit.element.library;
- List<LibraryElement> importedLibraries = library.importedLibraries;
- assertNamedElements(importedLibraries, ["dart.core", "libB"]);
- List<LibraryElement> visibleLibraries = library.visibleLibraries;
- assertNamedElements(visibleLibraries, ["dart.core", "libA", "libB"]);
- }
-
- void test_resolveCompilationUnit_import_relative_cyclic() {
- _context = AnalysisContextFactory.oldContextWithCore();
- Source sourceA =
- _addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}");
- _addSource("/libB.dart", "library libB; import 'libA.dart'; class B{}");
- CompilationUnit compilationUnit =
- _context.resolveCompilationUnit2(sourceA, sourceA);
- LibraryElement library = compilationUnit.element.library;
- List<LibraryElement> importedLibraries = library.importedLibraries;
- assertNamedElements(importedLibraries, ["dart.core", "libB"]);
- List<LibraryElement> visibleLibraries = library.visibleLibraries;
- assertNamedElements(visibleLibraries, ["dart.core", "libA", "libB"]);
- }
-
- void test_resolveCompilationUnit_library() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource("/lib.dart", "library lib;");
- LibraryElement library = _context.computeLibraryElement(source);
- CompilationUnit compilationUnit =
- _context.resolveCompilationUnit(source, library);
- expect(compilationUnit, isNotNull);
- expect(compilationUnit.element, isNotNull);
- }
-
- void test_resolveCompilationUnit_source() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource("/lib.dart", "library lib;");
- CompilationUnit compilationUnit =
- _context.resolveCompilationUnit2(source, source);
- expect(compilationUnit, isNotNull);
- }
-
- void test_resolveCompilationUnit_sourceChangeDuringResolution() {
- _context = new _AnalysisContext_sourceChangeDuringResolution();
- AnalysisContextFactory.initContextWithCore(_context);
- _sourceFactory = _context.sourceFactory;
- Source source = _addSource("/lib.dart", "library lib;");
- CompilationUnit compilationUnit =
- _context.resolveCompilationUnit2(source, source);
- expect(compilationUnit, isNotNull);
- expect(_context.getLineInfo(source), isNotNull);
- }
-
- void test_resolveHtmlUnit() {
- Source source = _addSource("/lib.html", "<html></html>");
- ht.HtmlUnit unit = _context.resolveHtmlUnit(source);
- expect(unit, isNotNull);
- }
-
- void test_setAnalysisOptions() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.cacheSize = 42;
- options.dart2jsHint = false;
- options.hint = false;
- _context.analysisOptions = options;
- AnalysisOptions result = _context.analysisOptions;
- expect(result.cacheSize, options.cacheSize);
- expect(result.dart2jsHint, options.dart2jsHint);
- expect(result.hint, options.hint);
- }
-
- void test_setAnalysisOptions_reduceAnalysisPriorityOrder() {
- AnalysisOptionsImpl options =
- new AnalysisOptionsImpl.from(_context.analysisOptions);
- List<Source> sources = new List<Source>();
- for (int index = 0; index < options.cacheSize; index++) {
- sources.add(_addSource("/lib.dart$index", ""));
- }
- _context.analysisPriorityOrder = sources;
- int oldPriorityOrderSize = _getPriorityOrder(_context).length;
- options.cacheSize = options.cacheSize - 10;
- _context.analysisOptions = options;
- expect(oldPriorityOrderSize > _getPriorityOrder(_context).length, isTrue);
- }
-
- void test_setAnalysisPriorityOrder_empty() {
- _context.analysisPriorityOrder = new List<Source>();
- }
-
- void test_setAnalysisPriorityOrder_lessThanCacheSize() {
- AnalysisOptions options = _context.analysisOptions;
- List<Source> sources = new List<Source>();
- for (int index = 0; index < options.cacheSize; index++) {
- sources.add(_addSource("/lib.dart$index", ""));
- }
- _context.analysisPriorityOrder = sources;
- expect(options.cacheSize > _getPriorityOrder(_context).length, isTrue);
- }
-
- void test_setAnalysisPriorityOrder_nonEmpty() {
- List<Source> sources = new List<Source>();
- sources.add(_addSource("/lib.dart", "library lib;"));
- _context.analysisPriorityOrder = sources;
- }
-
- Future test_setChangedContents_libraryWithPart() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.incremental = true;
- _context = AnalysisContextFactory.oldContextWithCoreAndOptions(options);
- SourcesChangedListener listener = new SourcesChangedListener();
- _context.onSourcesChanged.listen(listener.onData);
- _sourceFactory = _context.sourceFactory;
- String oldCode = r'''
-library lib;
-part 'part.dart';
-int a = 0;''';
- Source librarySource = _addSource("/lib.dart", oldCode);
- String partContents = r'''
-part of lib;
-int b = a;''';
- Source partSource = _addSource("/part.dart", partContents);
- LibraryElement element = _context.computeLibraryElement(librarySource);
- CompilationUnit unit =
- _context.getResolvedCompilationUnit(librarySource, element);
- expect(unit, isNotNull);
- int offset = oldCode.indexOf("int a") + 4;
- String newCode = r'''
-library lib;
-part 'part.dart';
-int ya = 0;''';
- expect(_getIncrementalAnalysisCache(_context), isNull);
- _context.setChangedContents(librarySource, newCode, offset, 0, 1);
- expect(_context.getContents(librarySource).data, newCode);
- IncrementalAnalysisCache incrementalCache =
- _getIncrementalAnalysisCache(_context);
- expect(incrementalCache.librarySource, librarySource);
- expect(incrementalCache.resolvedUnit, same(unit));
- expect(_context.getResolvedCompilationUnit2(partSource, librarySource),
- isNull);
- expect(incrementalCache.newContents, newCode);
- return pumpEventQueue().then((_) {
- listener.assertEvent(wereSourcesAdded: true);
- listener.assertEvent(changedSources: [librarySource]);
- listener.assertEvent(wereSourcesAdded: true);
- listener.assertEvent(changedSources: [partSource]);
- listener.assertEvent(changedSources: [librarySource]);
- listener.assertNoMoreEvents();
- });
- }
-
- void test_setChangedContents_notResolved() {
- _context = AnalysisContextFactory.oldContextWithCore();
- AnalysisOptionsImpl options =
- new AnalysisOptionsImpl.from(_context.analysisOptions);
- options.incremental = true;
- _context.analysisOptions = options;
- _sourceFactory = _context.sourceFactory;
- String oldCode = r'''
-library lib;
-int a = 0;''';
- Source librarySource = _addSource("/lib.dart", oldCode);
- int offset = oldCode.indexOf("int a") + 4;
- String newCode = r'''
-library lib;
-int ya = 0;''';
- _context.setChangedContents(librarySource, newCode, offset, 0, 1);
- expect(_context.getContents(librarySource).data, newCode);
- expect(_getIncrementalAnalysisCache(_context), isNull);
- }
-
- Future test_setContents_libraryWithPart() {
- _context = AnalysisContextFactory.oldContextWithCore();
- SourcesChangedListener listener = new SourcesChangedListener();
- _context.onSourcesChanged.listen(listener.onData);
- _sourceFactory = _context.sourceFactory;
- String libraryContents1 = r'''
-library lib;
-part 'part.dart';
-int a = 0;''';
- Source librarySource = _addSource("/lib.dart", libraryContents1);
- String partContents1 = r'''
-part of lib;
-int b = a;''';
- Source partSource = _addSource("/part.dart", partContents1);
- _context.computeLibraryElement(librarySource);
- IncrementalAnalysisCache incrementalCache = new IncrementalAnalysisCache(
- librarySource, librarySource, null, null, null, 0, 0, 0);
- _setIncrementalAnalysisCache(_context, incrementalCache);
- expect(_getIncrementalAnalysisCache(_context), same(incrementalCache));
- String libraryContents2 = r'''
-library lib;
-part 'part.dart';
-int aa = 0;''';
- _context.setContents(librarySource, libraryContents2);
- expect(_context.getResolvedCompilationUnit2(partSource, librarySource),
- isNull);
- expect(_getIncrementalAnalysisCache(_context), isNull);
- return pumpEventQueue().then((_) {
- listener.assertEvent(wereSourcesAdded: true);
- listener.assertEvent(changedSources: [librarySource]);
- listener.assertEvent(wereSourcesAdded: true);
- listener.assertEvent(changedSources: [partSource]);
- listener.assertEvent(changedSources: [librarySource]);
- listener.assertNoMoreEvents();
- });
- }
-
- void test_setContents_null() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source librarySource = _addSource(
- "/lib.dart",
- r'''
-library lib;
-int a = 0;''');
- _context.computeLibraryElement(librarySource);
- IncrementalAnalysisCache incrementalCache = new IncrementalAnalysisCache(
- librarySource, librarySource, null, null, null, 0, 0, 0);
- _setIncrementalAnalysisCache(_context, incrementalCache);
- expect(_getIncrementalAnalysisCache(_context), same(incrementalCache));
- _context.setContents(librarySource, null);
- expect(_context.getResolvedCompilationUnit2(librarySource, librarySource),
- isNull);
- expect(_getIncrementalAnalysisCache(_context), isNull);
- }
-
- void test_setContents_unchanged_consistentModificationTime() {
- String contents = "// foo";
- Source source = _addSource("/test.dart", contents);
- // do all, no tasks
- _analyzeAll_assertFinished();
- {
- AnalysisResult result = _context.performAnalysisTask();
- expect(result.changeNotices, isNull);
- }
- // set the same contents, still no tasks
- _context.setContents(source, contents);
- {
- AnalysisResult result = _context.performAnalysisTask();
- expect(result.changeNotices, isNull);
- }
- }
-
- void test_setSourceFactory() {
- expect(_context.sourceFactory, _sourceFactory);
- SourceFactory factory = new SourceFactory([]);
- _context.sourceFactory = factory;
- expect(_context.sourceFactory, factory);
- }
-
- void test_unreadableSource() {
- _context = AnalysisContextFactory.oldContextWithCore();
- _sourceFactory = _context.sourceFactory;
- Source test1 = _addSource(
- "/test1.dart",
- r'''
-import 'test2.dart';
-library test1;''');
- Source test2 = _addSource(
- "/test2.dart",
- r'''
-import 'test1.dart';
-import 'test3.dart';
-library test2;''');
- Source test3 = _addSourceWithException("/test3.dart");
- _analyzeAll_assertFinished();
- // test1 and test2 should have been successfully analyzed
- // despite the fact that test3 couldn't be read.
- expect(_context.computeLibraryElement(test1), isNotNull);
- expect(_context.computeLibraryElement(test2), isNotNull);
- expect(_context.computeLibraryElement(test3), isNull);
- }
-
- void test_updateAnalysis() {
- expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
- Source source =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- AnalysisDelta delta = new AnalysisDelta();
- delta.setAnalysisLevel(source, AnalysisLevel.ALL);
- _context.applyAnalysisDelta(delta);
- expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
- delta = new AnalysisDelta();
- delta.setAnalysisLevel(source, AnalysisLevel.NONE);
- _context.applyAnalysisDelta(delta);
- expect(_context.sourcesNeedingProcessing.contains(source), isFalse);
- }
-
- void xtest_performAnalysisTask_stress() {
- int maxCacheSize = 4;
- AnalysisOptionsImpl options =
- new AnalysisOptionsImpl.from(_context.analysisOptions);
- options.cacheSize = maxCacheSize;
- _context.analysisOptions = options;
- int sourceCount = maxCacheSize + 2;
- List<Source> sources = new List<Source>();
- ChangeSet changeSet = new ChangeSet();
- for (int i = 0; i < sourceCount; i++) {
- Source source = _addSource("/lib$i.dart", "library lib$i;");
- sources.add(source);
- changeSet.addedSource(source);
- }
- _context.applyChanges(changeSet);
- _context.analysisPriorityOrder = sources;
- for (int i = 0; i < 1000; i++) {
- List<ChangeNotice> notice = _context.performAnalysisTask().changeNotices;
- if (notice == null) {
- //System.out.println("test_performAnalysisTask_stress: " + i);
- break;
- }
- }
- List<ChangeNotice> notice = _context.performAnalysisTask().changeNotices;
- if (notice != null) {
- fail(
- "performAnalysisTask failed to terminate after analyzing all sources");
- }
- }
-
- Source _addSource(String fileName, String contents) {
- Source source = new FileBasedSource(FileUtilities2.createFile(fileName));
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source);
- _context.applyChanges(changeSet);
- _context.setContents(source, contents);
- return source;
- }
-
- TestSource _addSourceWithException(String fileName) {
- return _addSourceWithException2(fileName, "");
- }
-
- TestSource _addSourceWithException2(String fileName, String contents) {
- TestSource source = new TestSource(fileName, contents);
- source.generateExceptionOnRead = true;
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source);
- _context.applyChanges(changeSet);
- return source;
- }
-
- /**
- * Perform analysis tasks up to 512 times and asserts that that was enough.
- */
- void _analyzeAll_assertFinished() {
- _analyzeAll_assertFinished2(512);
- }
-
- /**
- * Perform analysis tasks up to the given number of times and asserts that that was enough.
- *
- * @param maxIterations the maximum number of tasks to perform
- */
- void _analyzeAll_assertFinished2(int maxIterations) {
- for (int i = 0; i < maxIterations; i++) {
- List<ChangeNotice> notice = _context.performAnalysisTask().changeNotices;
- if (notice == null) {
- return;
- }
- }
- fail("performAnalysisTask failed to terminate after analyzing all sources");
- }
-
- void _changeSource(TestSource source, String contents) {
- source.setContents(contents);
- ChangeSet changeSet = new ChangeSet();
- changeSet.changedSource(source);
- _context.applyChanges(changeSet);
- }
-
- Source _createSource(String fileName, String contents) {
- Source source = new FileBasedSource(FileUtilities2.createFile(fileName));
- _context.setContents(source, contents);
- return source;
- }
-
- /**
- * Search the given compilation unit for a class with the given name. Return the class with the
- * given name, or `null` if the class cannot be found.
- *
- * @param unit the compilation unit being searched
- * @param className the name of the class being searched for
- * @return the class with the given name
- */
- ClassElement _findClass(CompilationUnitElement unit, String className) {
- for (ClassElement classElement in unit.types) {
- if (classElement.displayName == className) {
- return classElement;
- }
- }
- return null;
- }
-
- IncrementalAnalysisCache _getIncrementalAnalysisCache(
- AnalysisContextImpl context2) {
- return context2.test_incrementalAnalysisCache;
- }
-
- List<Source> _getPriorityOrder(AnalysisContextImpl context2) {
- return context2.test_priorityOrder;
- }
-
- void _performPendingAnalysisTasks([int maxTasks = 20]) {
- for (int i = 0; _context.performAnalysisTask().hasMoreWork; i++) {
- if (i > maxTasks) {
- fail('Analysis did not terminate.');
- }
- }
- }
-
- void _removeSource(Source source) {
- ChangeSet changeSet = new ChangeSet();
- changeSet.removedSource(source);
- _context.applyChanges(changeSet);
- }
-
- void _setIncrementalAnalysisCache(
- AnalysisContextImpl context, IncrementalAnalysisCache incrementalCache) {
- context.test_incrementalAnalysisCache = incrementalCache;
- }
-
- /**
- * Returns `true` if there is an [AnalysisError] with [ErrorSeverity.ERROR] in
- * the given [AnalysisErrorInfo].
- */
- static bool _hasAnalysisErrorWithErrorSeverity(AnalysisErrorInfo errorInfo) {
- List<AnalysisError> errors = errorInfo.errors;
- for (AnalysisError analysisError in errors) {
- if (analysisError.errorCode.errorSeverity == ErrorSeverity.ERROR) {
- return true;
- }
- }
- return false;
- }
-}
-
-class AnalysisContextImplTest_Source_exists_true extends TestSource {
- @override
- bool exists() => true;
-}
-
-class AnalysisContextImplTest_Source_getModificationStamp_fromSource
- extends TestSource {
- int stamp;
- AnalysisContextImplTest_Source_getModificationStamp_fromSource(this.stamp);
- @override
- int get modificationStamp => stamp;
-}
-
-class AnalysisContextImplTest_Source_getModificationStamp_overridden
- extends TestSource {
- int stamp;
- AnalysisContextImplTest_Source_getModificationStamp_overridden(this.stamp);
- @override
- int get modificationStamp => stamp;
-}
-
-@reflectiveTest
-class AnalysisOptionsImplTest extends EngineTestCase {
- void test_AnalysisOptionsImpl_copy() {
- bool booleanValue = true;
- for (int i = 0; i < 2; i++, booleanValue = !booleanValue) {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.analyzeFunctionBodies = booleanValue;
- options.cacheSize = i;
- options.dart2jsHint = booleanValue;
- options.enableGenericMethods = booleanValue;
- options.enableStrictCallChecks = booleanValue;
- options.enableSuperMixins = booleanValue;
- options.generateImplicitErrors = booleanValue;
- options.generateSdkErrors = booleanValue;
- options.hint = booleanValue;
- options.incremental = booleanValue;
- options.preserveComments = booleanValue;
- options.strongMode = booleanValue;
- AnalysisOptionsImpl copy = new AnalysisOptionsImpl.from(options);
- expect(copy.analyzeFunctionBodies, options.analyzeFunctionBodies);
- expect(copy.cacheSize, options.cacheSize);
- expect(copy.dart2jsHint, options.dart2jsHint);
- expect(copy.enableStrictCallChecks, options.enableStrictCallChecks);
- expect(copy.enableSuperMixins, options.enableSuperMixins);
- expect(copy.generateImplicitErrors, options.generateImplicitErrors);
- expect(copy.generateSdkErrors, options.generateSdkErrors);
- expect(copy.hint, options.hint);
- expect(copy.incremental, options.incremental);
- expect(copy.preserveComments, options.preserveComments);
- expect(copy.strongMode, options.strongMode);
- }
- }
-
- void test_analyzeFunctionBodies() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- bool value = !options.analyzeFunctionBodies;
- options.analyzeFunctionBodies = value;
- expect(options.analyzeFunctionBodies, value);
- }
-
- void test_cacheSize() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- expect(options.cacheSize, AnalysisOptionsImpl.DEFAULT_CACHE_SIZE);
- int value = options.cacheSize + 1;
- options.cacheSize = value;
- expect(options.cacheSize, value);
- }
-
- void test_dart2jsHint() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- bool value = !options.dart2jsHint;
- options.dart2jsHint = value;
- expect(options.dart2jsHint, value);
- }
-
- void test_enableGenericMethods() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- bool value = !options.enableGenericMethods;
- options.enableGenericMethods = value;
- expect(options.enableGenericMethods, value);
- }
-
- void test_enableSuperMixins() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- bool value = !options.enableSuperMixins;
- options.enableSuperMixins = value;
- expect(options.enableSuperMixins, value);
- }
-
- void test_generateImplicitErrors() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- bool value = !options.generateImplicitErrors;
- options.generateImplicitErrors = value;
- expect(options.generateImplicitErrors, value);
- }
-
- void test_generateSdkErrors() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- bool value = !options.generateSdkErrors;
- options.generateSdkErrors = value;
- expect(options.generateSdkErrors, value);
- }
-
- void test_hint() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- bool value = !options.hint;
- options.hint = value;
- expect(options.hint, value);
- }
-
- void test_incremental() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- bool value = !options.incremental;
- options.incremental = value;
- expect(options.incremental, value);
- }
-
- void test_preserveComments() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- bool value = !options.preserveComments;
- options.preserveComments = value;
- expect(options.preserveComments, value);
- }
-
- void test_strongMode() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- bool value = !options.strongMode;
- options.strongMode = value;
- expect(options.strongMode, value);
- }
-}
-
-class AnalysisTask_test_perform_exception extends AnalysisTask {
- AnalysisTask_test_perform_exception(InternalAnalysisContext arg0)
- : super(arg0);
- @override
- String get taskDescription => null;
- @override
- accept(AnalysisTaskVisitor visitor) {
- expect(exception, isNotNull);
- return null;
- }
-
- @override
- void internalPerform() {
- throw new AnalysisException("Forced exception");
- }
-}
-
-@reflectiveTest
-class AnalysisTaskTest extends EngineTestCase {
- void test_perform_exception() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- AnalysisTask task = new AnalysisTask_test_perform_exception(context);
- task.perform(new TestTaskVisitor<Object>());
- }
}
/**
@@ -2523,2277 +72,7 @@
}
}
-class CompilationUnitMock extends TypedMock implements CompilationUnit {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-@reflectiveTest
-class DartEntryTest extends EngineTestCase {
- void test_allErrors() {
- Source source = new TestSource();
- DartEntry entry = new DartEntry();
- expect(entry.allErrors, hasLength(0));
- entry.setValue(SourceEntry.CONTENT_ERRORS, <AnalysisError>[
- new AnalysisError(source, 0, 0, ScannerErrorCode.UNABLE_GET_CONTENT,
- ['exception details'])
- ]);
- entry.setValue(DartEntry.SCAN_ERRORS, <AnalysisError>[
- new AnalysisError(
- source, 0, 0, ScannerErrorCode.UNTERMINATED_STRING_LITERAL)
- ]);
- entry.setValue(DartEntry.PARSE_ERRORS, <AnalysisError>[
- new AnalysisError(source, 0, 0, ParserErrorCode.ABSTRACT_CLASS_MEMBER)
- ]);
- entry.setValueInLibrary(
- DartEntry.RESOLUTION_ERRORS, source, <AnalysisError>[
- new AnalysisError(
- source, 0, 0, CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION)
- ]);
- entry.setValueInLibrary(
- DartEntry.VERIFICATION_ERRORS, source, <AnalysisError>[
- new AnalysisError(
- source, 0, 0, StaticWarningCode.CASE_BLOCK_NOT_TERMINATED)
- ]);
- entry.setValueInLibrary(DartEntry.HINTS, source,
- <AnalysisError>[new AnalysisError(source, 0, 0, HintCode.DEAD_CODE)]);
- expect(entry.allErrors, hasLength(6));
- }
-
- void test_creation() {
- Source librarySource = new TestSource();
- DartEntry entry = new DartEntry();
- expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
- expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.CONTAINING_LIBRARIES),
- same(CacheState.INVALID));
- expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
- expect(
- entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
- expect(
- entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.INVALID));
- expect(
- entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));
-
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource),
- same(CacheState.INVALID));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource),
- same(CacheState.INVALID));
- expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource),
- same(CacheState.INVALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource),
- same(CacheState.INVALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource),
- same(CacheState.INVALID));
- expect(
- entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource),
- same(CacheState.INVALID));
- }
-
- void test_getResolvableCompilationUnit_none() {
- DartEntry entry = new DartEntry();
- expect(entry.resolvableCompilationUnit, isNull);
- }
-
- void test_getResolvableCompilationUnit_parsed_accessed() {
- Source librarySource = new TestSource("/lib.dart");
- String importUri = "/f1.dart";
- Source importSource = new TestSource(importUri);
- ImportDirective importDirective =
- AstFactory.importDirective3(importUri, null);
- importDirective.source = importSource;
- importDirective.uriContent = importUri;
- String exportUri = "/f2.dart";
- Source exportSource = new TestSource(exportUri);
- ExportDirective exportDirective = AstFactory.exportDirective2(exportUri);
- exportDirective.source = exportSource;
- exportDirective.uriContent = exportUri;
- String partUri = "/f3.dart";
- Source partSource = new TestSource(partUri);
- PartDirective partDirective = AstFactory.partDirective2(partUri);
- partDirective.source = partSource;
- partDirective.uriContent = partUri;
- CompilationUnit unit = AstFactory
- .compilationUnit3([importDirective, exportDirective, partDirective]);
- DartEntry entry = new DartEntry();
- entry.setValue(DartEntry.PARSED_UNIT, unit);
- entry.getValue(DartEntry.PARSED_UNIT);
- CompilationUnit result = entry.resolvableCompilationUnit;
- expect(result, same(unit));
- entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource, unit);
- result = entry.resolvableCompilationUnit;
- expect(result, isNot(same(unit)));
- NodeList<Directive> directives = result.directives;
- ImportDirective resultImportDirective = directives[0] as ImportDirective;
- expect(resultImportDirective.uriContent, importUri);
- expect(resultImportDirective.source, same(importSource));
- ExportDirective resultExportDirective = directives[1] as ExportDirective;
- expect(resultExportDirective.uriContent, exportUri);
- expect(resultExportDirective.source, same(exportSource));
- PartDirective resultPartDirective = directives[2] as PartDirective;
- expect(resultPartDirective.uriContent, partUri);
- expect(resultPartDirective.source, same(partSource));
- }
-
- void test_getResolvableCompilationUnit_parsed_notAccessed() {
- CompilationUnit unit = AstFactory.compilationUnit();
- DartEntry entry = new DartEntry();
- entry.setValue(DartEntry.PARSED_UNIT, unit);
- expect(entry.resolvableCompilationUnit, same(unit));
- }
-
- void test_getResolvableCompilationUnit_resolved() {
- String importUri = "f1.dart";
- Source importSource = new TestSource(importUri);
- ImportDirective importDirective =
- AstFactory.importDirective3(importUri, null);
- importDirective.source = importSource;
- importDirective.uriContent = importUri;
- String exportUri = "f2.dart";
- Source exportSource = new TestSource(exportUri);
- ExportDirective exportDirective = AstFactory.exportDirective2(exportUri);
- exportDirective.source = exportSource;
- exportDirective.uriContent = exportUri;
- String partUri = "f3.dart";
- Source partSource = new TestSource(partUri);
- PartDirective partDirective = AstFactory.partDirective2(partUri);
- partDirective.source = partSource;
- partDirective.uriContent = partUri;
- CompilationUnit unit = AstFactory
- .compilationUnit3([importDirective, exportDirective, partDirective]);
- DartEntry entry = new DartEntry();
- entry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, new TestSource("lib.dart"), unit);
- CompilationUnit result = entry.resolvableCompilationUnit;
- expect(result, isNot(same(unit)));
- NodeList<Directive> directives = result.directives;
- ImportDirective resultImportDirective = directives[0] as ImportDirective;
- expect(resultImportDirective.uriContent, importUri);
- expect(resultImportDirective.source, same(importSource));
- ExportDirective resultExportDirective = directives[1] as ExportDirective;
- expect(resultExportDirective.uriContent, exportUri);
- expect(resultExportDirective.source, same(exportSource));
- PartDirective resultPartDirective = directives[2] as PartDirective;
- expect(resultPartDirective.uriContent, partUri);
- expect(resultPartDirective.source, same(partSource));
- }
-
- void test_getState_invalid_resolutionErrors() {
- DartEntry entry = new DartEntry();
- try {
- entry.getState(DartEntry.RESOLUTION_ERRORS);
- fail("Expected ArgumentError for RESOLUTION_ERRORS");
- } on ArgumentError {
- // Expected
- }
- }
-
- void test_getState_invalid_verificationErrors() {
- DartEntry entry = new DartEntry();
- try {
- entry.getState(DartEntry.VERIFICATION_ERRORS);
- fail("Expected ArgumentError for VERIFICATION_ERRORS");
- } on ArgumentError {
- // Expected
- }
- }
-
- void test_getStateInLibrary_invalid_element() {
- DartEntry entry = new DartEntry();
- try {
- entry.getStateInLibrary(DartEntry.ELEMENT, new TestSource());
- fail("Expected ArgumentError for ELEMENT");
- } on ArgumentError {
- // Expected
- }
- }
-
- void test_getValue_containingLibraries() {
- Source testSource = new TestSource();
- DartEntry entry = new DartEntry();
- List<Source> value = entry.containingLibraries;
- expect(value, hasLength(0));
- entry.addContainingLibrary(testSource);
- value = entry.containingLibraries;
- expect(value, hasLength(1));
- expect(value[0], testSource);
- entry.removeContainingLibrary(testSource);
- value = entry.containingLibraries;
- expect(value, hasLength(0));
- }
-
- void test_getValue_invalid_resolutionErrors() {
- DartEntry entry = new DartEntry();
- try {
- entry.getValue(DartEntry.RESOLUTION_ERRORS);
- fail("Expected ArgumentError for RESOLUTION_ERRORS");
- } on ArgumentError {}
- }
-
- void test_getValue_invalid_verificationErrors() {
- DartEntry entry = new DartEntry();
- try {
- entry.getValue(DartEntry.VERIFICATION_ERRORS);
- fail("Expected ArgumentError for VERIFICATION_ERRORS");
- } on ArgumentError {
- // Expected
- }
- }
-
- void test_getValueInLibrary_invalid_element() {
- DartEntry entry = new DartEntry();
- try {
- entry.getValueInLibrary(DartEntry.ELEMENT, new TestSource());
- fail("Expected ArgumentError for ELEMENT");
- } on ArgumentError {
- // Expected
- }
- }
-
- void test_getValueInLibrary_invalid_resolutionErrors_multiple() {
- Source source1 = new TestSource();
- Source source2 = new TestSource();
- Source source3 = new TestSource();
- DartEntry entry = new DartEntry();
- entry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, source1, AstFactory.compilationUnit());
- entry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, source2, AstFactory.compilationUnit());
- entry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, source3, AstFactory.compilationUnit());
- try {
- entry.getValueInLibrary(DartEntry.ELEMENT, source3);
- fail("Expected ArgumentError for ELEMENT");
- } on ArgumentError {
- // Expected
- }
- }
-
- void test_hasInvalidData_false() {
- DartEntry entry = new DartEntry();
- entry.recordScanError(new CaughtException(new AnalysisException(), null));
- expect(entry.hasInvalidData(DartEntry.ELEMENT), isFalse);
- expect(entry.hasInvalidData(DartEntry.EXPORTED_LIBRARIES), isFalse);
- expect(entry.hasInvalidData(DartEntry.HINTS), isFalse);
- expect(entry.hasInvalidData(DartEntry.IMPORTED_LIBRARIES), isFalse);
- expect(entry.hasInvalidData(DartEntry.INCLUDED_PARTS), isFalse);
- expect(entry.hasInvalidData(DartEntry.IS_CLIENT), isFalse);
- expect(entry.hasInvalidData(DartEntry.IS_LAUNCHABLE), isFalse);
- expect(entry.hasInvalidData(SourceEntry.LINE_INFO), isFalse);
- expect(entry.hasInvalidData(DartEntry.PARSE_ERRORS), isFalse);
- expect(entry.hasInvalidData(DartEntry.PARSED_UNIT), isFalse);
- expect(entry.hasInvalidData(DartEntry.PUBLIC_NAMESPACE), isFalse);
- expect(entry.hasInvalidData(DartEntry.SOURCE_KIND), isFalse);
- expect(entry.hasInvalidData(DartEntry.RESOLUTION_ERRORS), isFalse);
- expect(entry.hasInvalidData(DartEntry.RESOLVED_UNIT), isFalse);
- expect(entry.hasInvalidData(DartEntry.VERIFICATION_ERRORS), isFalse);
- }
-
- void test_hasInvalidData_true() {
- DartEntry entry = new DartEntry();
- expect(entry.hasInvalidData(DartEntry.ELEMENT), isTrue);
- expect(entry.hasInvalidData(DartEntry.EXPORTED_LIBRARIES), isTrue);
- expect(entry.hasInvalidData(DartEntry.HINTS), isTrue);
- expect(entry.hasInvalidData(DartEntry.IMPORTED_LIBRARIES), isTrue);
- expect(entry.hasInvalidData(DartEntry.INCLUDED_PARTS), isTrue);
- expect(entry.hasInvalidData(DartEntry.IS_CLIENT), isTrue);
- expect(entry.hasInvalidData(DartEntry.IS_LAUNCHABLE), isTrue);
- expect(entry.hasInvalidData(SourceEntry.LINE_INFO), isTrue);
- expect(entry.hasInvalidData(DartEntry.PARSE_ERRORS), isTrue);
- expect(entry.hasInvalidData(DartEntry.PARSED_UNIT), isTrue);
- expect(entry.hasInvalidData(DartEntry.PUBLIC_NAMESPACE), isTrue);
- expect(entry.hasInvalidData(DartEntry.SOURCE_KIND), isTrue);
- expect(entry.hasInvalidData(DartEntry.RESOLUTION_ERRORS), isTrue);
- expect(entry.hasInvalidData(DartEntry.RESOLVED_UNIT), isTrue);
- expect(entry.hasInvalidData(DartEntry.VERIFICATION_ERRORS), isTrue);
- }
-
- void test_invalidateAllInformation() {
- Source librarySource = new TestSource();
- DartEntry entry = _entryWithValidState(librarySource);
- entry.invalidateAllInformation();
- expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
- expect(
- entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.INVALID));
- expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
- expect(
- entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
- expect(
- entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
- expect(
- entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.INVALID));
- expect(
- entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));
-
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource),
- same(CacheState.INVALID));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource),
- same(CacheState.INVALID));
- expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource),
- same(CacheState.INVALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource),
- same(CacheState.INVALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource),
- same(CacheState.INVALID));
- expect(
- entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource),
- same(CacheState.INVALID));
- }
-
- void test_invalidateAllResolutionInformation() {
- Source librarySource = new TestSource();
- DartEntry entry = _entryWithValidState(librarySource);
- entry.invalidateAllResolutionInformation(false);
- expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
- expect(
- entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
- expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource),
- same(CacheState.INVALID));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource),
- same(CacheState.INVALID));
- expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource),
- same(CacheState.INVALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource),
- same(CacheState.INVALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource),
- same(CacheState.INVALID));
- expect(
- entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource),
- same(CacheState.INVALID));
- }
-
- void test_invalidateAllResolutionInformation_includingUris() {
- Source librarySource = new TestSource();
- DartEntry entry = _entryWithValidState(librarySource);
- entry.invalidateAllResolutionInformation(true);
- expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
- expect(
- entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
- expect(
- entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
- expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
- expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource),
- same(CacheState.INVALID));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource),
- same(CacheState.INVALID));
- expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource),
- same(CacheState.INVALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource),
- same(CacheState.INVALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource),
- same(CacheState.INVALID));
- expect(
- entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource),
- same(CacheState.INVALID));
- }
-
- void test_isClient() {
- DartEntry entry = new DartEntry();
- // true
- entry.setValue(DartEntry.IS_CLIENT, true);
- expect(entry.getValue(DartEntry.IS_CLIENT), isTrue);
- expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
- // invalidate
- entry.setState(DartEntry.IS_CLIENT, CacheState.INVALID);
- expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
- // false
- entry.setValue(DartEntry.IS_CLIENT, false);
- expect(entry.getValue(DartEntry.IS_CLIENT), isFalse);
- expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
- }
-
- void test_isLaunchable() {
- DartEntry entry = new DartEntry();
- // true
- entry.setValue(DartEntry.IS_LAUNCHABLE, true);
- expect(entry.getValue(DartEntry.IS_LAUNCHABLE), isTrue);
- expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
- // invalidate
- entry.setState(DartEntry.IS_LAUNCHABLE, CacheState.INVALID);
- expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
- // false
- entry.setValue(DartEntry.IS_LAUNCHABLE, false);
- expect(entry.getValue(DartEntry.IS_LAUNCHABLE), isFalse);
- expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
- }
-
- void test_recordBuildElementError() {
- Source firstLibrary = new TestSource('first.dart');
- Source secondLibrary = new TestSource('second.dart');
- DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
- entry.recordBuildElementErrorInLibrary(
- firstLibrary, new CaughtException(new AnalysisException(), null));
- expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
- expect(
- entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
- expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
- same(CacheState.ERROR));
-
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
- same(CacheState.VALID));
- expect(
- entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
- same(CacheState.VALID));
- }
-
- void test_recordContentError() {
- Source firstLibrary = new TestSource('first.dart');
-// Source secondLibrary = new TestSource('second.dart');
- DartEntry entry = _entryWithValidState(firstLibrary);
- entry
- .recordContentError(new CaughtException(new AnalysisException(), null));
- expect(entry.getState(SourceEntry.CONTENT), same(CacheState.ERROR));
- expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.ERROR));
- expect(
- entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
- expect(
- entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.ERROR));
- expect(
- entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.ERROR));
-
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
- same(CacheState.ERROR));
-
- // The following lines are commented out because we don't currently have
- // any way of setting the state for data associated with a library we
- // don't know anything about.
-// expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
- }
-
- void test_recordHintErrorInLibrary() {
- Source firstLibrary = new TestSource('first.dart');
- Source secondLibrary = new TestSource('second.dart');
- DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
- entry.recordHintErrorInLibrary(
- firstLibrary, new CaughtException(new AnalysisException(), null));
- expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.ELEMENT), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
- expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.VALID));
- expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
- expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
- same(CacheState.VALID));
-
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
- same(CacheState.VALID));
- expect(
- entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
- same(CacheState.VALID));
- }
-
- void test_recordParseError() {
- Source firstLibrary = new TestSource('first.dart');
-// Source secondLibrary = new TestSource('second.dart');
- DartEntry entry = _entryWithValidState(firstLibrary);
- entry.recordParseError(new CaughtException(new AnalysisException(), null));
- expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
- expect(
- entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.ERROR));
- expect(
- entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
- same(CacheState.ERROR));
-
- // The following lines are commented out because we don't currently have
- // any way of setting the state for data associated with a library we
- // don't know anything about.
-// expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
- }
-
- void test_recordResolutionError() {
- Source firstLibrary = new TestSource('first.dart');
-// Source secondLibrary = new TestSource('second.dart');
- DartEntry entry = _entryWithValidState(firstLibrary);
- entry.recordResolutionError(
- new CaughtException(new AnalysisException(), null));
- expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
- expect(
- entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
- expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
- same(CacheState.ERROR));
-
- // The following lines are commented out because we don't currently have
- // any way of setting the state for data associated with a library we
- // don't know anything about.
-// expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
- }
-
- void test_recordResolutionErrorInLibrary() {
- Source firstLibrary = new TestSource('first.dart');
- Source secondLibrary = new TestSource('second.dart');
- DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
- entry.recordResolutionErrorInLibrary(
- firstLibrary, new CaughtException(new AnalysisException(), null));
- expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
- expect(
- entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
- expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
- same(CacheState.ERROR));
-
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
- same(CacheState.VALID));
- expect(
- entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
- same(CacheState.VALID));
- }
-
- void test_recordScanError() {
- Source firstLibrary = new TestSource('first.dart');
-// Source secondLibrary = new TestSource('second.dart');
- DartEntry entry = _entryWithValidState(firstLibrary);
- entry.recordScanError(new CaughtException(new AnalysisException(), null));
- expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.ERROR));
- expect(
- entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
- expect(
- entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.ERROR));
- expect(
- entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.ERROR));
- expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.ERROR));
-
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
- same(CacheState.ERROR));
-
- // The following lines are commented out because we don't currently have
- // any way of setting the state for data associated with a library we
- // don't know anything about.
-// expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
-// expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
- }
-
- void test_recordVerificationErrorInLibrary() {
- Source firstLibrary = new TestSource('first.dart');
- Source secondLibrary = new TestSource('second.dart');
- DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
- entry.recordVerificationErrorInLibrary(
- firstLibrary, new CaughtException(new AnalysisException(), null));
- expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.ELEMENT), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
- expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.VALID));
- expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
- expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
- same(CacheState.ERROR));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
- same(CacheState.ERROR));
-
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
- same(CacheState.VALID));
- expect(
- entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
- same(CacheState.VALID));
- }
-
- void test_removeResolution_multiple_first() {
- Source source1 = new TestSource('first.dart');
- Source source2 = new TestSource('second.dart');
- Source source3 = new TestSource('third.dart');
- DartEntry entry = new DartEntry();
- entry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, source1, AstFactory.compilationUnit());
- entry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, source2, AstFactory.compilationUnit());
- entry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, source3, AstFactory.compilationUnit());
- entry.removeResolution(source1);
- }
-
- void test_removeResolution_multiple_last() {
- Source source1 = new TestSource('first.dart');
- Source source2 = new TestSource('second.dart');
- Source source3 = new TestSource('third.dart');
- DartEntry entry = new DartEntry();
- entry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, source1, AstFactory.compilationUnit());
- entry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, source2, AstFactory.compilationUnit());
- entry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, source3, AstFactory.compilationUnit());
- entry.removeResolution(source3);
- }
-
- void test_removeResolution_multiple_middle() {
- Source source1 = new TestSource('first.dart');
- Source source2 = new TestSource('second.dart');
- Source source3 = new TestSource('third.dart');
- DartEntry entry = new DartEntry();
- entry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, source1, AstFactory.compilationUnit());
- entry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, source2, AstFactory.compilationUnit());
- entry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, source3, AstFactory.compilationUnit());
- entry.removeResolution(source2);
- }
-
- void test_removeResolution_single() {
- Source source1 = new TestSource();
- DartEntry entry = new DartEntry();
- entry.setValueInLibrary(
- DartEntry.RESOLVED_UNIT, source1, AstFactory.compilationUnit());
- entry.removeResolution(source1);
- }
-
- void test_resolvableCompilationUnit_builtUnit() {
- Source librarySource = new TestSource('/lib.dart');
- CompilationUnit unit = AstFactory.compilationUnit();
- CompilationUnitElement element =
- ElementFactory.compilationUnit('test.dart');
- unit.element = element;
- DartEntry entry = new DartEntry();
- entry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
- entry.setValueInLibrary(DartEntry.BUILT_UNIT, librarySource, unit);
- entry.invalidateAllResolutionInformation(false);
- CompilationUnit resolvableUnit = entry.resolvableCompilationUnit;
- expect(resolvableUnit, isNotNull);
- expect(resolvableUnit.element, isNull);
- expect(entry.resolvableCompilationUnit, isNull);
- }
-
- void test_resolvableCompilationUnit_none() {
- DartEntry entry = new DartEntry();
- expect(entry.resolvableCompilationUnit, isNull);
- }
-
- void test_resolvableCompilationUnit_parsed() {
- CompilationUnit unit = AstFactory.compilationUnit();
- DartEntry entry = new DartEntry();
- entry.setValue(DartEntry.PARSED_UNIT, unit);
- expect(entry.resolvableCompilationUnit, unit);
- expect(entry.resolvableCompilationUnit, isNull);
- }
-
- void test_resolvableCompilationUnit_resolved() {
- Source librarySource = new TestSource('/lib.dart');
- CompilationUnit unit = AstFactory.compilationUnit();
- CompilationUnitElement element =
- ElementFactory.compilationUnit('test.dart');
- unit.element = element;
- DartEntry entry = new DartEntry();
- entry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
- entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource, unit);
- entry.invalidateAllResolutionInformation(false);
- CompilationUnit resolvableUnit = entry.resolvableCompilationUnit;
- expect(resolvableUnit, isNotNull);
- expect(resolvableUnit.element, isNull);
- expect(entry.resolvableCompilationUnit, isNull);
- }
-
- void test_setState_element() {
- _setState(DartEntry.ELEMENT);
- }
-
- void test_setState_exportedLibraries() {
- _setState(DartEntry.EXPORTED_LIBRARIES);
- }
-
- void test_setState_hints() {
- _setStateInLibrary(DartEntry.HINTS);
- }
-
- void test_setState_importedLibraries() {
- _setState(DartEntry.IMPORTED_LIBRARIES);
- }
-
- void test_setState_includedParts() {
- _setState(DartEntry.INCLUDED_PARTS);
- }
-
- void test_setState_invalid_element() {
- DartEntry entry = new DartEntry();
- try {
- entry.setStateInLibrary(DartEntry.ELEMENT, null, CacheState.FLUSHED);
- fail("Expected ArgumentError for ELEMENT");
- } on ArgumentError {
- // Expected
- }
- }
-
- void test_setState_invalid_resolutionErrors() {
- DartEntry entry = new DartEntry();
- try {
- entry.setState(DartEntry.RESOLUTION_ERRORS, CacheState.FLUSHED);
- fail("Expected ArgumentError for RESOLUTION_ERRORS");
- } on ArgumentError {
- // Expected
- }
- }
-
- void test_setState_invalid_validState() {
- DartEntry entry = new DartEntry();
- try {
- entry.setState(SourceEntry.LINE_INFO, CacheState.VALID);
- fail("Expected ArgumentError for a state of VALID");
- } on ArgumentError {}
- }
-
- void test_setState_invalid_verificationErrors() {
- DartEntry entry = new DartEntry();
- try {
- entry.setState(DartEntry.VERIFICATION_ERRORS, CacheState.FLUSHED);
- fail("Expected ArgumentError for VERIFICATION_ERRORS");
- } on ArgumentError {
- // Expected
- }
- }
-
- void test_setState_isClient() {
- _setState(DartEntry.IS_CLIENT);
- }
-
- void test_setState_isLaunchable() {
- _setState(DartEntry.IS_LAUNCHABLE);
- }
-
- void test_setState_lineInfo() {
- _setState(SourceEntry.LINE_INFO);
- }
-
- void test_setState_parsedUnit() {
- _setState(DartEntry.PARSED_UNIT);
- }
-
- void test_setState_parseErrors() {
- _setState(DartEntry.PARSE_ERRORS);
- }
-
- void test_setState_publicNamespace() {
- _setState(DartEntry.PUBLIC_NAMESPACE);
- }
-
- void test_setState_resolutionErrors() {
- _setStateInLibrary(DartEntry.RESOLUTION_ERRORS);
- }
-
- void test_setState_resolvedUnit() {
- _setStateInLibrary(DartEntry.RESOLVED_UNIT);
- }
-
- void test_setState_scanErrors() {
- _setState(DartEntry.SCAN_ERRORS);
- }
-
- void test_setState_sourceKind() {
- _setState(DartEntry.SOURCE_KIND);
- }
-
- void test_setState_tokenStream() {
- _setState(DartEntry.TOKEN_STREAM);
- }
-
- void test_setState_verificationErrors() {
- _setStateInLibrary(DartEntry.VERIFICATION_ERRORS);
- }
-
- void test_setValue_element() {
- _setValue(
- DartEntry.ELEMENT,
- new LibraryElementImpl.forNode(
- null, AstFactory.libraryIdentifier2(["lib"])));
- }
-
- void test_setValue_exportedLibraries() {
- _setValue(DartEntry.EXPORTED_LIBRARIES, <Source>[new TestSource()]);
- }
-
- void test_setValue_hints() {
- _setValueInLibrary(DartEntry.HINTS,
- <AnalysisError>[new AnalysisError(null, 0, 0, HintCode.DEAD_CODE)]);
- }
-
- void test_setValue_importedLibraries() {
- _setValue(DartEntry.IMPORTED_LIBRARIES, <Source>[new TestSource()]);
- }
-
- void test_setValue_includedParts() {
- _setValue(DartEntry.INCLUDED_PARTS, <Source>[new TestSource()]);
- }
-
- void test_setValue_isClient() {
- _setValue(DartEntry.IS_CLIENT, true);
- }
-
- void test_setValue_isLaunchable() {
- _setValue(DartEntry.IS_LAUNCHABLE, true);
- }
-
- void test_setValue_lineInfo() {
- _setValue(SourceEntry.LINE_INFO, new LineInfo(<int>[0]));
- }
-
- void test_setValue_parsedUnit() {
- _setValue(DartEntry.PARSED_UNIT, AstFactory.compilationUnit());
- }
-
- void test_setValue_parseErrors() {
- _setValue(DartEntry.PARSE_ERRORS, <AnalysisError>[
- new AnalysisError(null, 0, 0, ParserErrorCode.ABSTRACT_CLASS_MEMBER)
- ]);
- }
-
- void test_setValue_publicNamespace() {
- _setValue(DartEntry.PUBLIC_NAMESPACE,
- new Namespace(new HashMap<String, Element>()));
- }
-
- void test_setValue_resolutionErrors() {
- _setValueInLibrary(DartEntry.RESOLUTION_ERRORS, <AnalysisError>[
- new AnalysisError(
- null, 0, 0, CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION)
- ]);
- }
-
- void test_setValue_resolvedUnit() {
- _setValueInLibrary(DartEntry.RESOLVED_UNIT, AstFactory.compilationUnit());
- }
-
- void test_setValue_scanErrors() {
- _setValue(DartEntry.SCAN_ERRORS, <AnalysisError>[
- new AnalysisError(
- null, 0, 0, ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT)
- ]);
- }
-
- void test_setValue_sourceKind() {
- _setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
- }
-
- void test_setValue_tokenStream() {
- _setValue(DartEntry.TOKEN_STREAM, new Token(TokenType.LT, 5));
- }
-
- void test_setValue_verificationErrors() {
- _setValueInLibrary(DartEntry.VERIFICATION_ERRORS, <AnalysisError>[
- new AnalysisError(null, 0, 0, StaticWarningCode.CASE_BLOCK_NOT_TERMINATED)
- ]);
- }
-
- DartEntry _entryWithValidState([Source firstLibrary, Source secondLibrary]) {
- DartEntry entry = new DartEntry();
- entry.setValue(SourceEntry.CONTENT, null);
- entry.setValue(SourceEntry.CONTENT_ERRORS, null);
- entry.setValue(SourceEntry.LINE_INFO, null);
- entry.setValue(DartEntry.CONTAINING_LIBRARIES, null);
- entry.setValue(DartEntry.ELEMENT, null);
- entry.setValue(DartEntry.EXPORTED_LIBRARIES, null);
- entry.setValue(DartEntry.IMPORTED_LIBRARIES, null);
- entry.setValue(DartEntry.INCLUDED_PARTS, null);
- entry.setValue(DartEntry.IS_CLIENT, null);
- entry.setValue(DartEntry.IS_LAUNCHABLE, null);
- entry.setValue(DartEntry.PARSE_ERRORS, null);
- entry.setValue(DartEntry.PARSED_UNIT, null);
- entry.setValue(DartEntry.PUBLIC_NAMESPACE, null);
- entry.setValue(DartEntry.SCAN_ERRORS, null);
- entry.setValue(DartEntry.SOURCE_KIND, null);
- entry.setValue(DartEntry.TOKEN_STREAM, null);
- if (firstLibrary != null) {
- entry.setValueInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary, null);
- entry.setValueInLibrary(DartEntry.BUILT_UNIT, firstLibrary, null);
- entry.setValueInLibrary(DartEntry.HINTS, firstLibrary, null);
- entry.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary, null);
- entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary, null);
- entry.setValueInLibrary(
- DartEntry.VERIFICATION_ERRORS, firstLibrary, null);
- }
- if (secondLibrary != null) {
- entry.setValueInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary, null);
- entry.setValueInLibrary(DartEntry.BUILT_UNIT, secondLibrary, null);
- entry.setValueInLibrary(DartEntry.HINTS, secondLibrary, null);
- entry.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary, null);
- entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary, null);
- entry.setValueInLibrary(
- DartEntry.VERIFICATION_ERRORS, secondLibrary, null);
- }
- //
- // Validate that the state was set correctly.
- //
- expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.ELEMENT), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
- expect(
- entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
- expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
- expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.VALID));
- expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
- expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
- expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
- if (firstLibrary != null) {
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
- same(CacheState.VALID));
- expect(
- entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
- same(CacheState.VALID));
- }
- if (secondLibrary != null) {
- expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
- same(CacheState.VALID));
- expect(
- entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
- same(CacheState.VALID));
- expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
- same(CacheState.VALID));
- expect(
- entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
- same(CacheState.VALID));
- }
- return entry;
- }
-
- void _setState(DataDescriptor descriptor) {
- DartEntry entry = new DartEntry();
- expect(entry.getState(descriptor), isNot(same(CacheState.FLUSHED)));
- entry.setState(descriptor, CacheState.FLUSHED);
- expect(entry.getState(descriptor), same(CacheState.FLUSHED));
- }
-
- void _setStateInLibrary(DataDescriptor descriptor) {
- Source source = new TestSource();
- DartEntry entry = new DartEntry();
- expect(entry.getStateInLibrary(descriptor, source),
- isNot(same(CacheState.FLUSHED)));
- entry.setStateInLibrary(descriptor, source, CacheState.FLUSHED);
- expect(
- entry.getStateInLibrary(descriptor, source), same(CacheState.FLUSHED));
- }
-
- void _setValue(DataDescriptor descriptor, Object newValue) {
- DartEntry entry = new DartEntry();
- Object value = entry.getValue(descriptor);
- expect(newValue, isNot(same(value)));
- entry.setValue(descriptor, newValue);
- expect(entry.getState(descriptor), same(CacheState.VALID));
- expect(entry.getValue(descriptor), same(newValue));
- }
-
- void _setValueInLibrary(DataDescriptor descriptor, Object newValue) {
- Source source = new TestSource();
- DartEntry entry = new DartEntry();
- Object value = entry.getValueInLibrary(descriptor, source);
- expect(newValue, isNot(same(value)));
- entry.setValueInLibrary(descriptor, source, newValue);
- expect(entry.getStateInLibrary(descriptor, source), same(CacheState.VALID));
- expect(entry.getValueInLibrary(descriptor, source), same(newValue));
- }
-}
-
-@reflectiveTest
-class GenerateDartErrorsTaskTest extends EngineTestCase {
- void test_accept() {
- GenerateDartErrorsTask task =
- new GenerateDartErrorsTask(null, null, null, null);
- expect(task.accept(new GenerateDartErrorsTaskTestTV_accept()), isTrue);
- }
-
- void test_getException() {
- GenerateDartErrorsTask task =
- new GenerateDartErrorsTask(null, null, null, null);
- expect(task.exception, isNull);
- }
-
- void test_getLibraryElement() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- LibraryElement element = ElementFactory.library(context, "lib");
- GenerateDartErrorsTask task =
- new GenerateDartErrorsTask(context, null, null, element);
- expect(task.libraryElement, same(element));
- }
-
- void test_getSource() {
- Source source =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- GenerateDartErrorsTask task =
- new GenerateDartErrorsTask(null, source, null, null);
- expect(task.source, same(source));
- }
-
- void test_perform() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- Source source =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source);
- context.applyChanges(changeSet);
- context.setContents(
- source,
- r'''
-library lib;
-class A {
- int f = new A();
-}''');
- LibraryElement libraryElement = context.computeLibraryElement(source);
- CompilationUnit unit =
- context.getResolvedCompilationUnit(source, libraryElement);
- GenerateDartErrorsTask task =
- new GenerateDartErrorsTask(context, source, unit, libraryElement);
- task.perform(
- new GenerateDartErrorsTaskTestTV_perform(libraryElement, source));
- }
-
- void test_perform_validateDirectives() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- Source source =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source);
- context.applyChanges(changeSet);
- // TODO(scheglov) "import" causes second error reported
-// context.setContents(source, EngineTestCase.createSource([
-// "library lib;",
-// "import 'invaliduri^.dart';",
-// "export '\${a}lib3.dart';",
-// "part '/does/not/exist.dart';",
-// "class A {}"]));
- context.setContents(
- source,
- r'''
-library lib;
-part '/does/not/exist.dart';
-class A {}''');
- LibraryElement libraryElement = context.computeLibraryElement(source);
- CompilationUnit unit =
- context.getResolvedCompilationUnit(source, libraryElement);
- GenerateDartErrorsTask task =
- new GenerateDartErrorsTask(context, source, unit, libraryElement);
- task.perform(new GenerateDartErrorsTaskTestTV_perform_validateDirectives(
- libraryElement, source));
- }
-}
-
-class GenerateDartErrorsTaskTestTV_accept extends TestTaskVisitor<bool> {
- @override
- bool visitGenerateDartErrorsTask(GenerateDartErrorsTask task) => true;
-}
-
-class GenerateDartErrorsTaskTestTV_perform extends TestTaskVisitor<bool> {
- LibraryElement libraryElement;
- Source source;
- GenerateDartErrorsTaskTestTV_perform(this.libraryElement, this.source);
- @override
- bool visitGenerateDartErrorsTask(GenerateDartErrorsTask task) {
- CaughtException exception = task.exception;
- if (exception != null) {
- throw exception;
- }
- expect(task.libraryElement, same(libraryElement));
- expect(task.source, same(source));
- List<AnalysisError> errors = task.errors;
- expect(errors, hasLength(1));
- return true;
- }
-}
-
-class GenerateDartErrorsTaskTestTV_perform_validateDirectives
- extends TestTaskVisitor<bool> {
- LibraryElement libraryElement;
- Source source;
- GenerateDartErrorsTaskTestTV_perform_validateDirectives(
- this.libraryElement, this.source);
- @override
- bool visitGenerateDartErrorsTask(GenerateDartErrorsTask task) {
- CaughtException exception = task.exception;
- if (exception != null) {
- throw exception;
- }
- expect(task.libraryElement, same(libraryElement));
- expect(task.source, same(source));
- List<AnalysisError> errors = task.errors;
- expect(errors, hasLength(1));
- expect(errors[0].errorCode, same(CompileTimeErrorCode.URI_DOES_NOT_EXIST));
- return true;
- }
-}
-
-@reflectiveTest
-class GenerateDartHintsTaskTest extends EngineTestCase {
- void test_accept() {
- GenerateDartHintsTask task = new GenerateDartHintsTask(null, null, null);
- expect(task.accept(new GenerateDartHintsTaskTestTV_accept()), isTrue);
- }
-
- void test_getException() {
- GenerateDartHintsTask task = new GenerateDartHintsTask(null, null, null);
- expect(task.exception, isNull);
- }
-
- void test_getHintMap() {
- GenerateDartHintsTask task = new GenerateDartHintsTask(null, null, null);
- expect(task.hintMap, isNull);
- }
-
- void test_getLibraryElement() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- LibraryElement element = ElementFactory.library(context, "lib");
- GenerateDartHintsTask task =
- new GenerateDartHintsTask(context, null, element);
- expect(task.libraryElement, same(element));
- }
-
- void test_perform() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- ChangeSet changeSet = new ChangeSet();
- Source librarySource =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- changeSet.addedSource(librarySource);
- Source unusedSource =
- new FileBasedSource(FileUtilities2.createFile("/unused.dart"));
- changeSet.addedSource(unusedSource);
- Source partSource =
- new FileBasedSource(FileUtilities2.createFile("/part.dart"));
- changeSet.addedSource(partSource);
- context.applyChanges(changeSet);
- context.setContents(
- librarySource,
- r'''
-library lib;
-import 'unused.dart';
-part 'part.dart';''');
- context.setContents(unusedSource, "library unused;");
- context.setContents(partSource, "part of lib;");
- List<TimestampedData<CompilationUnit>> units = new List<TimestampedData>(2);
- units[0] = new TimestampedData<CompilationUnit>(
- context.getModificationStamp(librarySource),
- context.resolveCompilationUnit2(librarySource, librarySource));
- units[1] = new TimestampedData<CompilationUnit>(
- context.getModificationStamp(partSource),
- context.resolveCompilationUnit2(partSource, librarySource));
- GenerateDartHintsTask task = new GenerateDartHintsTask(
- context, units, context.computeLibraryElement(librarySource));
- task.perform(
- new GenerateDartHintsTaskTestTV_perform(librarySource, partSource));
- }
-}
-
-class GenerateDartHintsTaskTestTV_accept extends TestTaskVisitor<bool> {
- @override
- bool visitGenerateDartHintsTask(GenerateDartHintsTask task) => true;
-}
-
-class GenerateDartHintsTaskTestTV_perform extends TestTaskVisitor<bool> {
- Source librarySource;
- Source partSource;
- GenerateDartHintsTaskTestTV_perform(this.librarySource, this.partSource);
- @override
- bool visitGenerateDartHintsTask(GenerateDartHintsTask task) {
- CaughtException exception = task.exception;
- if (exception != null) {
- throw exception;
- }
- expect(task.libraryElement, isNotNull);
- HashMap<Source, List<AnalysisError>> hintMap = task.hintMap;
- expect(hintMap, hasLength(2));
- expect(hintMap[librarySource], hasLength(1));
- expect(hintMap[partSource], hasLength(0));
- return true;
- }
-}
-
-@reflectiveTest
-class GenerateDartLintsTaskTest extends EngineTestCase {
- void test_accept() {
- GenerateDartLintsTask task = new GenerateDartLintsTask(null, null, null);
- expect(task.accept(new GenerateDartLintsTaskTestTV_accept()), isTrue);
- }
-
- void test_exception() {
- GenerateDartLintsTask task = new GenerateDartLintsTask(null, null, null);
- expect(task.exception, isNull);
- }
-
- void test_libraryElement() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- LibraryElement element = ElementFactory.library(context, "lib");
- GenerateDartLintsTask task =
- new GenerateDartLintsTask(context, null, element);
- expect(task.libraryElement, same(element));
- }
-
- void test_lintMap() {
- GenerateDartLintsTask task = new GenerateDartLintsTask(null, null, null);
- expect(task.lintMap, isNull);
- }
-
- void test_perform() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- ChangeSet changeSet = new ChangeSet();
- Source librarySource =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- changeSet.addedSource(librarySource);
- context.applyChanges(changeSet);
- context.setContents(
- librarySource,
- r'''
-library lib;
-''');
- List<TimestampedData<CompilationUnit>> units = new List<TimestampedData>(1);
- units[0] = new TimestampedData<CompilationUnit>(
- context.getModificationStamp(librarySource),
- context.resolveCompilationUnit2(librarySource, librarySource));
- GenerateDartLintsTask task = new GenerateDartLintsTask(
- context, units, context.computeLibraryElement(librarySource));
- task.perform(new GenerateDartLintsTaskTestTV_perform(librarySource));
- }
-}
-
-class GenerateDartLintsTaskTestTV_accept extends TestTaskVisitor<bool> {
- @override
- bool visitGenerateDartLintsTask(GenerateDartLintsTask task) => true;
-}
-
-class GenerateDartLintsTaskTestTV_perform extends TestTaskVisitor<bool> {
- Source librarySource;
- GenerateDartLintsTaskTestTV_perform(this.librarySource);
- @override
- bool visitGenerateDartLintsTask(GenerateDartLintsTask task) {
- CaughtException exception = task.exception;
- if (exception != null) {
- throw exception;
- }
- expect(task.libraryElement, isNotNull);
- return true;
- }
-}
-
-@reflectiveTest
-class GetContentTaskTest extends EngineTestCase {
- void test_accept() {
- Source source = new TestSource('/test.dart', '');
- GetContentTask task = new GetContentTask(null, source);
- expect(task.accept(new GetContentTaskTestTV_accept()), isTrue);
- }
-
- void test_getException() {
- Source source = new TestSource('/test.dart', '');
- GetContentTask task = new GetContentTask(null, source);
- expect(task.exception, isNull);
- }
-
- void test_getModificationTime() {
- Source source = new TestSource('/test.dart', '');
- GetContentTask task = new GetContentTask(null, source);
- expect(task.modificationTime, -1);
- }
-
- void test_getSource() {
- Source source = new TestSource('/test.dart', '');
- GetContentTask task = new GetContentTask(null, source);
- expect(task.source, same(source));
- }
-
- void test_perform_exception() {
- TestSource source = new TestSource();
- source.generateExceptionOnRead = true;
- // final InternalAnalysisContext context = new AnalysisContextImpl();
- // context.setSourceFactory(new SourceFactory(new FileUriResolver()));
- GetContentTask task = new GetContentTask(null, source);
- task.perform(new GetContentTaskTestTV_perform_exception());
- }
-
- void test_perform_valid() {
- Source source = new TestSource('/test.dart', 'class A {}');
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- GetContentTask task = new GetContentTask(context, source);
- task.perform(new GetContentTaskTestTV_perform_valid(context, source));
- }
-}
-
-class GetContentTaskTestTV_accept extends TestTaskVisitor<bool> {
- @override
- bool visitGetContentTask(GetContentTask task) => true;
-}
-
-class GetContentTaskTestTV_perform_exception extends TestTaskVisitor<bool> {
- @override
- bool visitGetContentTask(GetContentTask task) {
- expect(task.exception, isNotNull);
- return true;
- }
-}
-
-class GetContentTaskTestTV_perform_valid extends TestTaskVisitor<bool> {
- InternalAnalysisContext context;
- Source source;
- GetContentTaskTestTV_perform_valid(this.context, this.source);
- @override
- bool visitGetContentTask(GetContentTask task) {
- CaughtException exception = task.exception;
- if (exception != null) {
- throw exception;
- }
- expect(task.modificationTime, context.getModificationStamp(source));
- expect(task.source, same(source));
- return true;
- }
-}
-
-@reflectiveTest
-class HtmlEntryTest extends EngineTestCase {
- void set state(DataDescriptor descriptor) {
- HtmlEntry entry = new HtmlEntry();
- expect(entry.getState(descriptor), isNot(same(CacheState.FLUSHED)));
- entry.setState(descriptor, CacheState.FLUSHED);
- expect(entry.getState(descriptor), same(CacheState.FLUSHED));
- }
-
- void test_creation() {
- HtmlEntry entry = new HtmlEntry();
- expect(entry, isNotNull);
- }
-
- void test_getAllErrors() {
- Source source = new TestSource();
- HtmlEntry entry = new HtmlEntry();
- expect(entry.allErrors, hasLength(0));
- entry.setValue(HtmlEntry.PARSE_ERRORS, <AnalysisError>[
- new AnalysisError(source, 0, 0, ParserErrorCode.EXPECTED_TOKEN, [";"])
- ]);
- entry.setValue(HtmlEntry.RESOLUTION_ERRORS, <AnalysisError>[
- new AnalysisError(source, 0, 0, HtmlWarningCode.INVALID_URI, ["-"])
- ]);
- entry.setValue(HtmlEntry.HINTS,
- <AnalysisError>[new AnalysisError(source, 0, 0, HintCode.DEAD_CODE)]);
- expect(entry.allErrors, hasLength(3));
- }
-
- void test_invalidateAllResolutionInformation() {
- HtmlEntry entry = _entryWithValidState();
- entry.invalidateAllResolutionInformation(false);
- expect(entry.getState(HtmlEntry.ELEMENT), same(CacheState.INVALID));
- expect(entry.getState(HtmlEntry.HINTS), same(CacheState.INVALID));
- expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
- expect(entry.getState(HtmlEntry.PARSE_ERRORS), same(CacheState.VALID));
- expect(entry.getState(HtmlEntry.PARSED_UNIT), same(CacheState.VALID));
- expect(
- entry.getState(HtmlEntry.REFERENCED_LIBRARIES), same(CacheState.VALID));
- expect(
- entry.getState(HtmlEntry.RESOLUTION_ERRORS), same(CacheState.INVALID));
- }
-
- void test_invalidateAllResolutionInformation_includingUris() {
- HtmlEntry entry = _entryWithValidState();
- entry.invalidateAllResolutionInformation(true);
- expect(entry.getState(HtmlEntry.ELEMENT), same(CacheState.INVALID));
- expect(entry.getState(HtmlEntry.HINTS), same(CacheState.INVALID));
- expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
- expect(entry.getState(HtmlEntry.PARSE_ERRORS), same(CacheState.VALID));
- expect(entry.getState(HtmlEntry.PARSED_UNIT), same(CacheState.VALID));
- expect(entry.getState(HtmlEntry.REFERENCED_LIBRARIES),
- same(CacheState.INVALID));
- expect(
- entry.getState(HtmlEntry.RESOLUTION_ERRORS), same(CacheState.INVALID));
- }
-
- void test_setState_element() {
- state = HtmlEntry.ELEMENT;
- }
-
- void test_setState_hints() {
- state = HtmlEntry.HINTS;
- }
-
- void test_setState_lineInfo() {
- state = SourceEntry.LINE_INFO;
- }
-
- void test_setState_parsedUnit() {
- state = HtmlEntry.PARSED_UNIT;
- }
-
- void test_setState_parseErrors() {
- state = HtmlEntry.PARSE_ERRORS;
- }
-
- void test_setState_referencedLibraries() {
- state = HtmlEntry.REFERENCED_LIBRARIES;
- }
-
- void test_setState_resolutionErrors() {
- state = HtmlEntry.RESOLUTION_ERRORS;
- }
-
- void test_setValue_element() {
- _setValue(HtmlEntry.ELEMENT, new HtmlElementImpl(null, "test.html"));
- }
-
- void test_setValue_hints() {
- _setValue(HtmlEntry.HINTS,
- <AnalysisError>[new AnalysisError(null, 0, 0, HintCode.DEAD_CODE)]);
- }
-
- void test_setValue_illegal() {
- HtmlEntry entry = new HtmlEntry();
- try {
- entry.setValue(DartEntry.ELEMENT, null);
- fail("Expected ArgumentError for DartEntry.ELEMENT");
- } on ArgumentError {}
- }
-
- void test_setValue_lineInfo() {
- _setValue(SourceEntry.LINE_INFO, new LineInfo(<int>[0]));
- }
-
- void test_setValue_parsedUnit() {
- _setValue(HtmlEntry.PARSED_UNIT, new ht.HtmlUnit(null, null, null));
- }
-
- void test_setValue_parseErrors() {
- _setValue(HtmlEntry.PARSE_ERRORS, <AnalysisError>[
- new AnalysisError(null, 0, 0, HtmlWarningCode.INVALID_URI, ["-"])
- ]);
- }
-
- void test_setValue_referencedLibraries() {
- _setValue(HtmlEntry.REFERENCED_LIBRARIES, <Source>[new TestSource()]);
- }
-
- void test_setValue_resolutionErrors() {
- _setValue(HtmlEntry.RESOLUTION_ERRORS, <AnalysisError>[
- new AnalysisError(null, 0, 0, HtmlWarningCode.INVALID_URI, ["-"])
- ]);
- }
-
- HtmlEntry _entryWithValidState() {
- HtmlEntry entry = new HtmlEntry();
- entry.setValue(HtmlEntry.ELEMENT, null);
- entry.setValue(HtmlEntry.HINTS, null);
- entry.setValue(SourceEntry.LINE_INFO, null);
- entry.setValue(HtmlEntry.PARSE_ERRORS, null);
- entry.setValue(HtmlEntry.PARSED_UNIT, null);
- entry.setValue(HtmlEntry.REFERENCED_LIBRARIES, null);
- entry.setValue(HtmlEntry.RESOLUTION_ERRORS, null);
- expect(entry.getState(HtmlEntry.ELEMENT), same(CacheState.VALID));
- expect(entry.getState(HtmlEntry.HINTS), same(CacheState.VALID));
- expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
- expect(entry.getState(HtmlEntry.PARSE_ERRORS), same(CacheState.VALID));
- expect(entry.getState(HtmlEntry.PARSED_UNIT), same(CacheState.VALID));
- expect(
- entry.getState(HtmlEntry.REFERENCED_LIBRARIES), same(CacheState.VALID));
- expect(entry.getState(HtmlEntry.RESOLUTION_ERRORS), same(CacheState.VALID));
- return entry;
- }
-
- void _setValue(DataDescriptor descriptor, Object newValue) {
- HtmlEntry entry = new HtmlEntry();
- Object value = entry.getValue(descriptor);
- expect(newValue, isNot(same(value)));
- entry.setValue(descriptor, newValue);
- expect(entry.getState(descriptor), same(CacheState.VALID));
- expect(entry.getValue(descriptor), same(newValue));
- }
-}
-
-@reflectiveTest
-class IncrementalAnalysisCacheTest {
- Source _source = new TestSource();
- DartEntry _entry = new DartEntry();
- CompilationUnit _unit = new CompilationUnitMock();
- IncrementalAnalysisCache _result;
- void setUp() {
- _entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, _unit);
- }
-
- void test_cacheResult() {
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
- CompilationUnit newUnit = new CompilationUnitMock();
- _result = IncrementalAnalysisCache.cacheResult(cache, newUnit);
- expect(_result, isNotNull);
- expect(_result.source, same(_source));
- expect(_result.resolvedUnit, same(newUnit));
- expect(_result.oldContents, "hbazlo");
- expect(_result.newContents, "hbazlo");
- expect(_result.offset, 0);
- expect(_result.oldLength, 0);
- expect(_result.newLength, 0);
- }
-
- void test_cacheResult_noCache() {
- IncrementalAnalysisCache cache = null;
- CompilationUnit newUnit = new CompilationUnitMock();
- _result = IncrementalAnalysisCache.cacheResult(cache, newUnit);
- expect(_result, isNull);
- }
-
- void test_cacheResult_noCacheNoResult() {
- IncrementalAnalysisCache cache = null;
- CompilationUnit newUnit = null;
- _result = IncrementalAnalysisCache.cacheResult(cache, newUnit);
- expect(_result, isNull);
- }
-
- void test_cacheResult_noResult() {
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
- CompilationUnit newUnit = null;
- _result = IncrementalAnalysisCache.cacheResult(cache, newUnit);
- expect(_result, isNull);
- }
-
- void test_clear_differentSource() {
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
- Source otherSource = new TestSource("blat.dart", "blat");
- _result = IncrementalAnalysisCache.clear(cache, otherSource);
- expect(_result, same(cache));
- }
-
- void test_clear_nullCache() {
- IncrementalAnalysisCache cache = null;
- _result = IncrementalAnalysisCache.clear(cache, _source);
- expect(_result, isNull);
- }
-
- void test_clear_sameSource() {
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
- _result = IncrementalAnalysisCache.clear(cache, _source);
- expect(_result, isNull);
- }
-
- void test_update_append() {
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
- DartEntry newEntry = new DartEntry();
- _result = IncrementalAnalysisCache.update(
- cache, _source, "hbazlo", "hbazxlo", 4, 0, 1, newEntry);
- expect(_result, isNotNull);
- expect(_result.source, same(_source));
- expect(_result.resolvedUnit, same(_unit));
- expect(_result.oldContents, "hello");
- expect(_result.newContents, "hbazxlo");
- expect(_result.offset, 1);
- expect(_result.oldLength, 2);
- expect(_result.newLength, 4);
- }
-
- void test_update_appendToCachedResult() {
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
- CompilationUnit newUnit = new CompilationUnitMock();
- cache = IncrementalAnalysisCache.cacheResult(cache, newUnit);
- expect(cache, isNotNull);
- DartEntry newEntry = new DartEntry();
- _result = IncrementalAnalysisCache.update(
- cache, _source, "hbazlo", "hbazxlo", 4, 0, 1, newEntry);
- expect(_result, isNotNull);
- expect(_result.source, same(_source));
- expect(_result.resolvedUnit, same(newUnit));
- expect(_result.oldContents, "hbazlo");
- expect(_result.newContents, "hbazxlo");
- expect(_result.offset, 4);
- expect(_result.oldLength, 0);
- expect(_result.newLength, 1);
- }
-
- void test_update_appendWithNewResolvedUnit() {
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
- DartEntry newEntry = new DartEntry();
- CompilationUnit newUnit = new CompilationUnitMock();
- newEntry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, newUnit);
- _result = IncrementalAnalysisCache.update(
- cache, _source, "hbazlo", "hbazxlo", 4, 0, 1, newEntry);
- expect(_result, isNotNull);
- expect(_result.source, same(_source));
- expect(_result.resolvedUnit, same(newUnit));
- expect(_result.oldContents, "hbazlo");
- expect(_result.newContents, "hbazxlo");
- expect(_result.offset, 4);
- expect(_result.oldLength, 0);
- expect(_result.newLength, 1);
- }
-
- void test_update_appendWithNoNewResolvedUnit() {
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
- DartEntry newEntry = new DartEntry();
- _result = IncrementalAnalysisCache.update(
- cache, _source, "hbazlo", "hbazxlo", 4, 0, 1, newEntry);
- expect(_result, isNotNull);
- expect(_result.source, same(_source));
- expect(_result.resolvedUnit, same(_unit));
- expect(_result.oldContents, "hello");
- expect(_result.newContents, "hbazxlo");
- expect(_result.offset, 1);
- expect(_result.oldLength, 2);
- expect(_result.newLength, 4);
- }
-
- void test_update_delete() {
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
- DartEntry newEntry = new DartEntry();
- _result = IncrementalAnalysisCache.update(
- cache, _source, "hbazlo", "hzlo", 1, 2, 0, newEntry);
- expect(_result, isNotNull);
- expect(_result.source, same(_source));
- expect(_result.resolvedUnit, same(_unit));
- expect(_result.oldContents, "hello");
- expect(_result.newContents, "hzlo");
- expect(_result.offset, 1);
- expect(_result.oldLength, 2);
- expect(_result.newLength, 1);
- }
-
- void test_update_insert_nonContiguous_after() {
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
- DartEntry newEntry = new DartEntry();
- _result = IncrementalAnalysisCache.update(
- cache, _source, "hbazlo", "hbazlox", 6, 0, 1, newEntry);
- expect(_result, isNull);
- }
-
- void test_update_insert_nonContiguous_before() {
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
- DartEntry newEntry = new DartEntry();
- _result = IncrementalAnalysisCache.update(
- cache, _source, "hbazlo", "xhbazlo", 0, 0, 1, newEntry);
- expect(_result, isNull);
- }
-
- void test_update_newSource_entry() {
- Source oldSource = new TestSource("blat.dart", "blat");
- DartEntry oldEntry = new DartEntry();
- CompilationUnit oldUnit = new CompilationUnitMock();
- oldEntry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, oldUnit);
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, oldSource, "hello", "hbazlo", 1, 2, 3, oldEntry);
- expect(cache.source, same(oldSource));
- expect(cache.resolvedUnit, same(oldUnit));
- _result = IncrementalAnalysisCache.update(
- cache, _source, "foo", "foobz", 3, 0, 2, _entry);
- expect(_result, isNotNull);
- expect(_result.source, same(_source));
- expect(_result.resolvedUnit, same(_unit));
- expect(_result.oldContents, "foo");
- expect(_result.newContents, "foobz");
- expect(_result.offset, 3);
- expect(_result.oldLength, 0);
- expect(_result.newLength, 2);
- }
-
- void test_update_newSource_noEntry() {
- Source oldSource = new TestSource("blat.dart", "blat");
- DartEntry oldEntry = new DartEntry();
- CompilationUnit oldUnit = new CompilationUnitMock();
- oldEntry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, oldUnit);
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, oldSource, "hello", "hbazlo", 1, 2, 3, oldEntry);
- expect(cache.source, same(oldSource));
- expect(cache.resolvedUnit, same(oldUnit));
- _result = IncrementalAnalysisCache.update(
- cache, _source, "foo", "foobar", 3, 0, 3, null);
- expect(_result, isNull);
- }
-
- void test_update_noCache_entry() {
- _result = IncrementalAnalysisCache.update(
- null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
- expect(_result, isNotNull);
- expect(_result.source, same(_source));
- expect(_result.resolvedUnit, same(_unit));
- expect(_result.oldContents, "hello");
- expect(_result.newContents, "hbazlo");
- expect(_result.offset, 1);
- expect(_result.oldLength, 2);
- expect(_result.newLength, 3);
- expect(_result.hasWork, isTrue);
- }
-
- void test_update_noCache_entry_noOldSource_append() {
- _result = IncrementalAnalysisCache.update(
- null, _source, null, "hellxo", 4, 0, 1, _entry);
- expect(_result, isNotNull);
- expect(_result.source, same(_source));
- expect(_result.resolvedUnit, same(_unit));
- expect(_result.oldContents, "hello");
- expect(_result.newContents, "hellxo");
- expect(_result.offset, 4);
- expect(_result.oldLength, 0);
- expect(_result.newLength, 1);
- expect(_result.hasWork, isTrue);
- }
-
- void test_update_noCache_entry_noOldSource_delete() {
- _result = IncrementalAnalysisCache.update(
- null, _source, null, "helo", 4, 1, 0, _entry);
- expect(_result, isNull);
- }
-
- void test_update_noCache_entry_noOldSource_replace() {
- _result = IncrementalAnalysisCache.update(
- null, _source, null, "helxo", 4, 1, 1, _entry);
- expect(_result, isNull);
- }
-
- void test_update_noCache_noEntry() {
- _result = IncrementalAnalysisCache.update(
- null, _source, "hello", "hbazlo", 1, 2, 3, null);
- expect(_result, isNull);
- }
-
- void test_update_replace() {
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
- _result = IncrementalAnalysisCache.update(
- cache, _source, "hbazlo", "hbarrlo", 3, 1, 2, null);
- expect(_result, isNotNull);
- expect(_result.source, same(_source));
- expect(_result.resolvedUnit, same(_unit));
- expect(_result.oldContents, "hello");
- expect(_result.newContents, "hbarrlo");
- expect(_result.offset, 1);
- expect(_result.oldLength, 2);
- expect(_result.newLength, 4);
- }
-
- void test_verifyStructure_invalidUnit() {
- String oldCode = "main() {foo;}";
- String newCode = "main() {boo;}";
- CompilationUnit badUnit = _parse("main() {bad;}");
- _entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, badUnit);
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, _source, oldCode, newCode, 8, 1, 1, _entry);
- CompilationUnit newUnit = _parse(newCode);
- _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
- expect(_result, isNull);
- }
-
- void test_verifyStructure_noCache() {
- IncrementalAnalysisCache cache = null;
- CompilationUnit newUnit = new CompilationUnitMock();
- _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
- expect(_result, isNull);
- }
-
- void test_verifyStructure_noCacheNoUnit() {
- IncrementalAnalysisCache cache = null;
- CompilationUnit newUnit = null;
- _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
- expect(_result, isNull);
- }
-
- void test_verifyStructure_noUnit() {
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
- CompilationUnit newUnit = null;
- _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
- expect(_result, same(cache));
- expect(_result.resolvedUnit, same(_unit));
- }
-
- void test_verifyStructure_otherSource() {
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
- CompilationUnit newUnit = new CompilationUnitMock();
- Source otherSource = new TestSource("blat.dart", "blat");
- _result =
- IncrementalAnalysisCache.verifyStructure(cache, otherSource, newUnit);
- expect(_result, same(cache));
- expect(_result.resolvedUnit, same(_unit));
- }
-
- void test_verifyStructure_validUnit() {
- String oldCode = "main() {foo;}";
- String newCode = "main() {boo;}";
- CompilationUnit goodUnit = _parse(newCode);
- _entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, goodUnit);
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null, _source, oldCode, newCode, 1, 2, 3, _entry);
- CompilationUnit newUnit = _parse(newCode);
- _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
- expect(_result, same(cache));
- expect(_result.resolvedUnit, same(goodUnit));
- }
-
- CompilationUnit _parse(String code) {
- Scanner scanner = new Scanner(_source, new CharSequenceReader(code),
- AnalysisErrorListener.NULL_LISTENER);
- Parser parser = new Parser(_source, AnalysisErrorListener.NULL_LISTENER);
- return parser.parseCompilationUnit(scanner.tokenize());
- }
-}
-
-@reflectiveTest
-class IncrementalAnalysisTaskTest extends EngineTestCase {
- void test_accept() {
- IncrementalAnalysisTask task = new IncrementalAnalysisTask(null, null);
- expect(task.accept(new IncrementalAnalysisTaskTestTV_accept()), isTrue);
- }
-
- void test_perform() {
- // main() {} String foo;
- // main() {String} String foo;
- CompilationUnit newUnit =
- _assertTask("main() {", "", "String", "} String foo;");
- NodeList<CompilationUnitMember> declarations = newUnit.declarations;
- FunctionDeclaration main = declarations[0] as FunctionDeclaration;
- expect(main.name.name, "main");
- BlockFunctionBody body = main.functionExpression.body as BlockFunctionBody;
- ExpressionStatement statement =
- body.block.statements[0] as ExpressionStatement;
- expect(statement.toSource(), "String;");
- SimpleIdentifier identifier = statement.expression as SimpleIdentifier;
- expect(identifier.name, "String");
- expect(identifier.staticElement, isNotNull);
- TopLevelVariableDeclaration fooDecl =
- declarations[1] as TopLevelVariableDeclaration;
- SimpleIdentifier fooName = fooDecl.variables.variables[0].name;
- expect(fooName.name, "foo");
- expect(fooName.staticElement, isNotNull);
- // assert element reference is preserved
- }
-
- CompilationUnit _assertTask(
- String prefix, String removed, String added, String suffix) {
- String oldCode = "$prefix$removed$suffix";
- String newCode = "$prefix$added$suffix";
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- Source source = new TestSource("/test.dart", oldCode);
- DartEntry entry = new DartEntry();
- CompilationUnit oldUnit = context.resolveCompilationUnit2(source, source);
- expect(oldUnit, isNotNull);
- entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, source, oldUnit);
- IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
- null,
- source,
- oldCode,
- newCode,
- prefix.length,
- removed.length,
- added.length,
- entry);
- expect(cache, isNotNull);
- IncrementalAnalysisTask task = new IncrementalAnalysisTask(context, cache);
- CompilationUnit newUnit =
- task.perform(new IncrementalAnalysisTaskTestTV_assertTask(task));
- expect(newUnit, isNotNull);
- return newUnit;
- }
-}
-
-class IncrementalAnalysisTaskTestTV_accept extends TestTaskVisitor<bool> {
- @override
- bool visitIncrementalAnalysisTask(IncrementalAnalysisTask task) => true;
-}
-
-class IncrementalAnalysisTaskTestTV_assertTask
- extends TestTaskVisitor<CompilationUnit> {
- IncrementalAnalysisTask task;
- IncrementalAnalysisTaskTestTV_assertTask(this.task);
- @override
- CompilationUnit visitIncrementalAnalysisTask(
- IncrementalAnalysisTask incrementalAnalysisTask) =>
- task.compilationUnit;
-}
-
-@reflectiveTest
-class LintGeneratorTest extends EngineTestCase {
- void test_generate() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- ChangeSet changeSet = new ChangeSet();
- Source librarySource =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- changeSet.addedSource(librarySource);
- context.applyChanges(changeSet);
- context.setContents(
- librarySource,
- r'''
-library lib;
-''');
-
- CompilationUnit unit =
- context.resolveCompilationUnit2(librarySource, librarySource);
- List<CompilationUnit> units = <CompilationUnit>[];
- units.add(unit);
-
- RecordingErrorListener errorListener = new RecordingErrorListener();
-
- LintGeneratorTest_Linter linter = new LintGeneratorTest_Linter();
-
- LintGenerator lintGenerator =
- new LintGenerator(units, errorListener, [linter]);
- lintGenerator.generate();
-
- linter.testExpectations();
- }
-
- void test_generate_null_visitor() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- ChangeSet changeSet = new ChangeSet();
- Source librarySource =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- changeSet.addedSource(librarySource);
- context.applyChanges(changeSet);
- context.setContents(
- librarySource,
- r'''
-library lib;
-''');
-
- CompilationUnit unit =
- context.resolveCompilationUnit2(librarySource, librarySource);
- List<CompilationUnit> units = <CompilationUnit>[];
- units.add(unit);
-
- RecordingErrorListener errorListener = new RecordingErrorListener();
-
- Linter badLinter = new LintGeneratorTest_Linter_Null_Visitor();
- LintGeneratorTest_Linter goodLinter = new LintGeneratorTest_Linter();
-
- LintGenerator lintGenerator =
- new LintGenerator(units, errorListener, [badLinter, goodLinter]);
- // Test that generate does not fall down with a null visitor
- lintGenerator.generate();
- // Well-formed linter should still get called
- goodLinter.testExpectations();
- }
-}
-
-class LintGeneratorTest_Linter extends Linter with SimpleAstVisitor<Object> {
- bool visited;
-
- @override
- AstVisitor getVisitor() => this;
-
- testExpectations() {
- expect(reporter, isNotNull);
- expect(visited, isTrue);
- }
-
- @override
- Object visitCompilationUnit(CompilationUnit node) {
- visited = true;
- return null;
- }
-}
-
-class LintGeneratorTest_Linter_Null_Visitor extends Linter {
- @override
- AstVisitor getVisitor() => null;
-}
+class CompilationUnitMock extends TypedMock implements CompilationUnit {}
class MockSourceFactory extends SourceFactory {
MockSourceFactory() : super([]);
@@ -4803,773 +82,6 @@
}
@reflectiveTest
-class ParseDartTaskTest extends EngineTestCase {
- void test_accept() {
- ParseDartTask task = new ParseDartTask(null, null, null, null);
- expect(task.accept(new ParseDartTaskTestTV_accept()), isTrue);
- }
-
- void test_getCompilationUnit() {
- ParseDartTask task = new ParseDartTask(null, null, null, null);
- expect(task.compilationUnit, isNull);
- }
-
- void test_getErrors() {
- ParseDartTask task = new ParseDartTask(null, null, null, null);
- expect(task.errors, hasLength(0));
- }
-
- void test_getException() {
- ParseDartTask task = new ParseDartTask(null, null, null, null);
- expect(task.exception, isNull);
- }
-
- void test_getSource() {
- Source source = new TestSource('/test.dart');
- ParseDartTask task = new ParseDartTask(null, source, null, null);
- expect(task.source, same(source));
- }
-
- void test_hasNonPartOfDirective() {
- ParseDartTask task = new ParseDartTask(null, null, null, null);
- expect(task.hasNonPartOfDirective, isFalse);
- }
-
- void test_hasPartOfDirective() {
- ParseDartTask task = new ParseDartTask(null, null, null, null);
- expect(task.hasPartOfDirective, isFalse);
- }
-
- void test_perform_exception() {
- TestSource source = new TestSource();
- source.generateExceptionOnRead = true;
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- ParseDartTask task = new ParseDartTask(context, source, null, null);
- task.perform(new ParseDartTaskTestTV_perform_exception());
- }
-
- void test_perform_library() {
- String content = r'''
-library lib;
-import 'lib2.dart';
-export 'lib3.dart';
-part 'part.dart';
-class A {''';
- Source source = new TestSource('/test.dart', content);
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- ParseDartTask task = _createParseTask(context, source, content);
- task.perform(new ParseDartTaskTestTV_perform_library(context, source));
- }
-
- void test_perform_part() {
- String content = r'''
-part of lib;
-class B {}''';
- Source source = new TestSource('/test.dart', content);
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- ParseDartTask task = _createParseTask(context, source, content);
- task.perform(new ParseDartTaskTestTV_perform_part(context, source));
- }
-
- void test_perform_validateDirectives() {
- String content = r'''
-library lib;
-import '/does/not/exist.dart';
-import '://invaliduri.dart';
-export '${a}lib3.dart';
-part 'part.dart';
-class A {}''';
- Source source = new TestSource('/test.dart', content);
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- ParseDartTask task = _createParseTask(context, source, content);
- task.perform(
- new ParseDartTaskTestTV_perform_validateDirectives(context, source));
- }
-
- void test_resolveDirective_dartUri() {
- GatheringErrorListener listener = new GatheringErrorListener();
- ImportDirective directive = AstFactory.importDirective3('dart:core', null);
- AnalysisContext context = AnalysisContextFactory.contextWithCore();
- Source source =
- ParseDartTask.resolveDirective(context, null, directive, listener);
- expect(source, isNotNull);
- }
-
- void test_resolveDirective_exception() {
- GatheringErrorListener listener = new GatheringErrorListener();
- ImportDirective directive = AstFactory.importDirective3('dart:core', null);
- AnalysisContext context = AnalysisContextFactory.contextWithCore();
- context.sourceFactory = new MockSourceFactory();
- Source source =
- ParseDartTask.resolveDirective(context, null, directive, listener);
- expect(source, isNull);
- expect(listener.errors, hasLength(1));
- }
-
- /**
- * Create and return a task that will parse the given content from the given source in the given
- * context.
- *
- * @param context the context to be passed to the task
- * @param source the source to be parsed
- * @param content the content of the source to be parsed
- * @return the task that was created
- * @throws AnalysisException if the task could not be created
- */
- ParseDartTask _createParseTask(
- InternalAnalysisContext context, Source source, String content) {
- ScanDartTask scanTask = new ScanDartTask(context, source, content);
- scanTask.perform(new ParseDartTaskTestTV_createParseTask());
- return new ParseDartTask(
- context, source, scanTask.tokenStream, scanTask.lineInfo);
- }
-}
-
-class ParseDartTaskTestTV_accept extends TestTaskVisitor<bool> {
- @override
- bool visitParseDartTask(ParseDartTask task) => true;
-}
-
-class ParseDartTaskTestTV_createParseTask extends TestTaskVisitor<Object> {
- @override
- Object visitScanDartTask(ScanDartTask task) => null;
-}
-
-class ParseDartTaskTestTV_perform_exception extends TestTaskVisitor<bool> {
- @override
- bool visitParseDartTask(ParseDartTask task) {
- expect(task.exception, isNotNull);
- return true;
- }
-}
-
-class ParseDartTaskTestTV_perform_library extends TestTaskVisitor<Object> {
- InternalAnalysisContext context;
- Source source;
- ParseDartTaskTestTV_perform_library(this.context, this.source);
- @override
- Object visitParseDartTask(ParseDartTask task) {
- CaughtException exception = task.exception;
- if (exception != null) {
- throw exception;
- }
- expect(task.compilationUnit, isNotNull);
- expect(task.errors, hasLength(1));
- expect(task.source, same(source));
- expect(task.hasNonPartOfDirective, isTrue);
- expect(task.hasPartOfDirective, isFalse);
- return null;
- }
-}
-
-class ParseDartTaskTestTV_perform_part extends TestTaskVisitor<Object> {
- InternalAnalysisContext context;
- Source source;
- ParseDartTaskTestTV_perform_part(this.context, this.source);
- @override
- Object visitParseDartTask(ParseDartTask task) {
- CaughtException exception = task.exception;
- if (exception != null) {
- throw exception;
- }
- expect(task.compilationUnit, isNotNull);
- expect(task.errors, hasLength(0));
- expect(task.source, same(source));
- expect(task.hasNonPartOfDirective, isFalse);
- expect(task.hasPartOfDirective, isTrue);
- return null;
- }
-}
-
-class ParseDartTaskTestTV_perform_validateDirectives
- extends TestTaskVisitor<Object> {
- InternalAnalysisContext context;
- Source source;
- ParseDartTaskTestTV_perform_validateDirectives(this.context, this.source);
- @override
- Object visitParseDartTask(ParseDartTask task) {
- CaughtException exception = task.exception;
- if (exception != null) {
- throw exception;
- }
- expect(task.compilationUnit, isNotNull);
- GatheringErrorListener errorListener = new GatheringErrorListener();
- errorListener.addAll(task.errors);
- errorListener.assertErrorsWithCodes([
- CompileTimeErrorCode.URI_WITH_INTERPOLATION,
- CompileTimeErrorCode.INVALID_URI
- ]);
- expect(task.source, same(source));
- expect(task.hasNonPartOfDirective, isTrue);
- expect(task.hasPartOfDirective, isFalse);
- return null;
- }
-}
-
-@reflectiveTest
-class ParseHtmlTaskTest extends EngineTestCase {
- ParseHtmlTask parseContents(String contents, TestLogger testLogger) {
- return parseSource(
- new TestSource('/test.dart', contents), contents, testLogger);
- }
-
- ParseHtmlTask parseSource(
- Source source, String contents, TestLogger testLogger) {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- context.setContents(source, contents);
- ParseHtmlTask task = new ParseHtmlTask(context, source, contents);
- Logger oldLogger = AnalysisEngine.instance.logger;
- try {
- AnalysisEngine.instance.logger = testLogger;
- task.perform(new ParseHtmlTaskTestTV_parseSource(context, source));
- } finally {
- AnalysisEngine.instance.logger = oldLogger;
- }
- return task;
- }
-
- void test_accept() {
- ParseHtmlTask task = new ParseHtmlTask(null, null, "");
- expect(task.accept(new ParseHtmlTaskTestTV_accept()), isTrue);
- }
-
- void test_getException() {
- ParseHtmlTask task = new ParseHtmlTask(null, null, "");
- expect(task.exception, isNull);
- }
-
- void test_getHtmlUnit() {
- ParseHtmlTask task = new ParseHtmlTask(null, null, "");
- expect(task.htmlUnit, isNull);
- }
-
- void test_getLineInfo() {
- ParseHtmlTask task = new ParseHtmlTask(null, null, "");
- expect(task.lineInfo, isNull);
- }
-
- void test_getReferencedLibraries() {
- ParseHtmlTask task = new ParseHtmlTask(null, null, "");
- expect(task.referencedLibraries, hasLength(0));
- }
-
- void test_getSource() {
- Source source = new TestSource('/test.dart');
- ParseHtmlTask task = new ParseHtmlTask(null, source, "");
- expect(task.source, same(source));
- }
-
- void test_perform_embedded_source() {
- String contents = r'''
-<html>
-<head>
- <script type='application/dart'>
- void buttonPressed() {}
- </script>
-</head>
-<body>
-</body>
-</html>''';
- TestLogger testLogger = new TestLogger();
- ParseHtmlTask task = parseContents(contents, testLogger);
- expect(task.referencedLibraries, hasLength(0));
- expect(testLogger.errorCount, 0);
- expect(testLogger.infoCount, 0);
- }
-
- void test_perform_empty_source_reference() {
- String contents = r'''
-<html>
-<head>
- <script type='application/dart' src=''/>
-</head>
-<body>
-</body>
-</html>''';
- TestLogger testLogger = new TestLogger();
- ParseHtmlTask task = parseContents(contents, testLogger);
- expect(task.referencedLibraries, hasLength(0));
- expect(testLogger.errorCount, 0);
- expect(testLogger.infoCount, 0);
- }
-
- void test_perform_invalid_source_reference() {
- String contents = r'''
-<html>
-<head>
- <script type='application/dart' src='an;invalid:[]uri'/>
-</head>
-<body>
-</body>
-</html>''';
- TestLogger testLogger = new TestLogger();
- ParseHtmlTask task = parseContents(contents, testLogger);
- expect(task.referencedLibraries, hasLength(0));
- expect(testLogger.errorCount, 0);
- expect(testLogger.infoCount, 0);
- }
-
- void test_perform_non_existing_source_reference() {
- String contents = r'''
-<html>
-<head>
- <script type='application/dart' src='does/not/exist.dart'/>
-</head>
-<body>
-</body>
-</html>''';
- TestLogger testLogger = new TestLogger();
- ParseHtmlTask task = parseSource(
- new ParseHtmlTaskTest_non_existing_source(contents),
- contents,
- testLogger);
- expect(task.referencedLibraries, hasLength(0));
- expect(testLogger.errorCount, 0);
- expect(testLogger.infoCount, 0);
- }
-
- void test_perform_referenced_source() {
- // TODO(scheglov) this test fails because we put into cache TestSource
- // test.dart (and actually should test.html), but resolve
- // src='test.dart' as a FileBasedSource
- // We need to switch to a virtual file system and use it everywhere.
-// String contents = EngineTestCase.createSource([
-// "<html>",
-// "<head>",
-// " <script type='application/dart' src='test.dart'/>",
-// "</head>",
-// "<body>",
-// "</body>",
-// "</html>"]);
-// TestLogger testLogger = new TestLogger();
-// ParseHtmlTask task = parseContents(contents, testLogger);
-// EngineTestCase.assertLength(1, task.referencedLibraries);
-// JUnitTestCase.assertEquals(0, testLogger.errorCount);
-// JUnitTestCase.assertEquals(0, testLogger.errorCount);
- }
-}
-
-class ParseHtmlTaskTest_non_existing_source extends TestSource {
- ParseHtmlTaskTest_non_existing_source(String arg0) : super(arg0);
- @override
- Uri resolveRelativeUri(Uri containedUri) {
- try {
- return parseUriWithException("file:/does/not/exist.dart");
- } on URISyntaxException {
- return null;
- }
- }
-}
-
-class ParseHtmlTaskTestTV_accept extends TestTaskVisitor<bool> {
- @override
- bool visitParseHtmlTask(ParseHtmlTask task) => true;
-}
-
-class ParseHtmlTaskTestTV_parseSource extends TestTaskVisitor<bool> {
- InternalAnalysisContext context;
- Source source;
- ParseHtmlTaskTestTV_parseSource(this.context, this.source);
- @override
- bool visitParseHtmlTask(ParseHtmlTask task) {
- CaughtException exception = task.exception;
- if (exception != null) {
- throw exception;
- }
- expect(task.htmlUnit, isNotNull);
- expect(task.lineInfo, isNotNull);
- expect(task.source, same(source));
- return true;
- }
-}
-
-@reflectiveTest
-class PartitionManagerTest extends EngineTestCase {
- void test_clearCache() {
- PartitionManager manager = new PartitionManager();
- DartSdk sdk = new MockDartSdk();
- SdkCachePartition oldPartition = manager.forSdk(sdk);
- manager.clearCache();
- SdkCachePartition newPartition = manager.forSdk(sdk);
- expect(newPartition, isNot(same(oldPartition)));
- }
-
- void test_creation() {
- expect(new PartitionManager(), isNotNull);
- }
-
- void test_forSdk() {
- PartitionManager manager = new PartitionManager();
- DartSdk sdk1 = new MockDartSdk();
- SdkCachePartition partition1 = manager.forSdk(sdk1);
- expect(partition1, isNotNull);
- expect(manager.forSdk(sdk1), same(partition1));
- DartSdk sdk2 = new MockDartSdk();
- SdkCachePartition partition2 = manager.forSdk(sdk2);
- expect(partition2, isNotNull);
- expect(manager.forSdk(sdk2), same(partition2));
- expect(partition2, isNot(same(partition1)));
- }
-}
-
-@reflectiveTest
-class ResolveDartLibraryTaskTest extends EngineTestCase {
- void test_accept() {
- ResolveDartLibraryTask task = new ResolveDartLibraryTask(null, null, null);
- expect(task.accept(new ResolveDartLibraryTaskTestTV_accept()), isTrue);
- }
-
- void test_getException() {
- ResolveDartLibraryTask task = new ResolveDartLibraryTask(null, null, null);
- expect(task.exception, isNull);
- }
-
- void test_getLibraryResolver() {
- ResolveDartLibraryTask task = new ResolveDartLibraryTask(null, null, null);
- expect(task.libraryResolver, isNull);
- }
-
- void test_getLibrarySource() {
- Source source = new TestSource('/test.dart');
- ResolveDartLibraryTask task =
- new ResolveDartLibraryTask(null, null, source);
- expect(task.librarySource, same(source));
- }
-
- void test_getUnitSource() {
- Source source = new TestSource('/test.dart');
- ResolveDartLibraryTask task =
- new ResolveDartLibraryTask(null, source, null);
- expect(task.unitSource, same(source));
- }
-
- void test_perform_exception() {
- TestSource source = new TestSource();
- source.generateExceptionOnRead = true;
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- ResolveDartLibraryTask task =
- new ResolveDartLibraryTask(context, source, source);
- task.perform(new ResolveDartLibraryTaskTestTV_perform_exception());
- }
-
- void test_perform_library() {
- Source source = new TestSource(
- '/test.dart',
- r'''
-library lib;
-class A {}''');
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- ResolveDartLibraryTask task =
- new ResolveDartLibraryTask(context, source, source);
- task.perform(new ResolveDartLibraryTaskTestTV_perform_library(source));
- }
-}
-
-class ResolveDartLibraryTaskTestTV_accept extends TestTaskVisitor<bool> {
- @override
- bool visitResolveDartLibraryTask(ResolveDartLibraryTask task) => true;
-}
-
-class ResolveDartLibraryTaskTestTV_perform_exception
- extends TestTaskVisitor<bool> {
- @override
- bool visitResolveDartLibraryTask(ResolveDartLibraryTask task) {
- expect(task.exception, isNotNull);
- return true;
- }
-}
-
-class ResolveDartLibraryTaskTestTV_perform_library
- extends TestTaskVisitor<bool> {
- Source source;
- ResolveDartLibraryTaskTestTV_perform_library(this.source);
- @override
- bool visitResolveDartLibraryTask(ResolveDartLibraryTask task) {
- CaughtException exception = task.exception;
- if (exception != null) {
- throw exception;
- }
- expect(task.libraryResolver, isNotNull);
- expect(task.librarySource, same(source));
- expect(task.unitSource, same(source));
- return true;
- }
-}
-
-@reflectiveTest
-class ResolveDartUnitTaskTest extends EngineTestCase {
- void test_accept() {
- ResolveDartUnitTask task = new ResolveDartUnitTask(null, null, null);
- expect(task.accept(new ResolveDartUnitTaskTestTV_accept()), isTrue);
- }
-
- void test_getException() {
- ResolveDartUnitTask task = new ResolveDartUnitTask(null, null, null);
- expect(task.exception, isNull);
- }
-
- void test_getLibrarySource() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- LibraryElementImpl element = ElementFactory.library(context, "lib");
- Source source = element.source;
- ResolveDartUnitTask task = new ResolveDartUnitTask(null, null, element);
- expect(task.librarySource, same(source));
- }
-
- void test_getResolvedUnit() {
- ResolveDartUnitTask task = new ResolveDartUnitTask(null, null, null);
- expect(task.resolvedUnit, isNull);
- }
-
- void test_getSource() {
- Source source = new TestSource('/test.dart');
- ResolveDartUnitTask task = new ResolveDartUnitTask(null, source, null);
- expect(task.source, same(source));
- }
-
- void test_perform_exception() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- LibraryElementImpl element = ElementFactory.library(context, "lib");
- TestSource source = new TestSource();
- source.generateExceptionOnRead = true;
- (element.definingCompilationUnit as CompilationUnitElementImpl).source =
- source;
- ResolveDartUnitTask task =
- new ResolveDartUnitTask(context, source, element);
- task.perform(new ResolveDartUnitTaskTestTV_perform_exception());
- }
-
- void test_perform_library() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- LibraryElementImpl libraryElement = ElementFactory.library(context, "lib");
- CompilationUnitElementImpl unitElement =
- libraryElement.definingCompilationUnit as CompilationUnitElementImpl;
- ClassElementImpl classElement = ElementFactory.classElement2("A");
- classElement.nameOffset = 19;
- ConstructorElementImpl constructorElement =
- ElementFactory.constructorElement2(classElement, null);
- constructorElement.synthetic = true;
- classElement.constructors = <ConstructorElement>[constructorElement];
- unitElement.types = <ClassElement>[classElement];
- Source source = unitElement.source;
- context.setContents(
- source,
- r'''
-library lib;
-class A {}''');
- ResolveDartUnitTask task =
- new ResolveDartUnitTask(context, source, libraryElement);
- task.perform(
- new ResolveDartUnitTaskTestTV_perform_library(source, context));
- }
-}
-
-class ResolveDartUnitTaskTestTV_accept extends TestTaskVisitor<bool> {
- @override
- bool visitResolveDartUnitTask(ResolveDartUnitTask task) => true;
-}
-
-class ResolveDartUnitTaskTestTV_perform_exception
- extends TestTaskVisitor<bool> {
- @override
- bool visitResolveDartUnitTask(ResolveDartUnitTask task) {
- expect(task.exception, isNotNull);
- return true;
- }
-}
-
-class ResolveDartUnitTaskTestTV_perform_library extends TestTaskVisitor<bool> {
- Source source;
- InternalAnalysisContext context;
- ResolveDartUnitTaskTestTV_perform_library(this.source, this.context);
- @override
- bool visitResolveDartUnitTask(ResolveDartUnitTask task) {
- CaughtException exception = task.exception;
- if (exception != null) {
- throw exception;
- }
- expect(task.librarySource, same(source));
- expect(task.resolvedUnit, isNotNull);
- expect(task.source, same(source));
- return true;
- }
-}
-
-@reflectiveTest
-class ResolveHtmlTaskTest extends EngineTestCase {
- void test_accept() {
- ResolveHtmlTask task = new ResolveHtmlTask(null, null, 0, null);
- expect(task.accept(new ResolveHtmlTaskTestTV_accept()), isTrue);
- }
-
- void test_getElement() {
- ResolveHtmlTask task = new ResolveHtmlTask(null, null, 0, null);
- expect(task.element, isNull);
- }
-
- void test_getException() {
- ResolveHtmlTask task = new ResolveHtmlTask(null, null, 0, null);
- expect(task.exception, isNull);
- }
-
- void test_getResolutionErrors() {
- ResolveHtmlTask task = new ResolveHtmlTask(null, null, 0, null);
- expect(task.resolutionErrors, hasLength(0));
- }
-
- void test_getSource() {
- Source source = new TestSource('test.dart', '');
- ResolveHtmlTask task = new ResolveHtmlTask(null, source, 0, null);
- expect(task.source, same(source));
- }
-
- void test_perform_exception() {
- Source source = new TestSource();
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- ResolveHtmlTask task = new ResolveHtmlTask(context, source, 0, null);
- task.perform(new ResolveHtmlTaskTestTV_perform_exception());
- }
-
- void test_perform_valid() {
- int modificationStamp = 73;
- String content = r'''
-<html>
-<head>
- <script type='application/dart'>
- void f() { x = 0; }
- </script>
-</head>
-<body>
-</body>
-</html>''';
- Source source = new TestSource("/test.html", content);
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- ParseHtmlTask parseTask = new ParseHtmlTask(context, source, content);
- parseTask.perform(new ResolveHtmlTaskTestTV_perform_valid_2());
- ResolveHtmlTask task = new ResolveHtmlTask(
- context, source, modificationStamp, parseTask.htmlUnit);
- task.perform(
- new ResolveHtmlTaskTestTV_perform_valid(modificationStamp, source));
- }
-}
-
-class ResolveHtmlTaskTestTV_accept extends TestTaskVisitor<bool> {
- @override
- bool visitResolveHtmlTask(ResolveHtmlTask task) => true;
-}
-
-class ResolveHtmlTaskTestTV_perform_exception extends TestTaskVisitor<bool> {
- @override
- bool visitResolveHtmlTask(ResolveHtmlTask task) {
- expect(task.exception, isNotNull);
- return true;
- }
-}
-
-class ResolveHtmlTaskTestTV_perform_valid extends TestTaskVisitor<Object> {
- int modificationStamp;
- Source source;
- ResolveHtmlTaskTestTV_perform_valid(this.modificationStamp, this.source);
- @override
- Object visitResolveHtmlTask(ResolveHtmlTask task) {
- CaughtException exception = task.exception;
- if (exception != null) {
- throw exception;
- }
- expect(task.element, isNotNull);
- expect(task.resolutionErrors, hasLength(1));
- expect(task.source, same(source));
- return null;
- }
-}
-
-class ResolveHtmlTaskTestTV_perform_valid_2 extends TestTaskVisitor<Object> {
- @override
- Object visitParseHtmlTask(ParseHtmlTask task) => null;
-}
-
-@reflectiveTest
-class ScanDartTaskTest extends EngineTestCase {
- void test_accept() {
- ScanDartTask task = new ScanDartTask(null, null, null);
- expect(task.accept(new ScanDartTaskTestTV_accept()), isTrue);
- }
-
- void test_getErrors() {
- ScanDartTask task = new ScanDartTask(null, null, null);
- expect(task.errors, hasLength(0));
- }
-
- void test_getException() {
- ScanDartTask task = new ScanDartTask(null, null, null);
- expect(task.exception, isNull);
- }
-
- void test_getLineInfo() {
- ScanDartTask task = new ScanDartTask(null, null, null);
- expect(task.lineInfo, isNull);
- }
-
- void test_getSource() {
- Source source = new TestSource('test.dart', '');
- ScanDartTask task = new ScanDartTask(null, source, null);
- expect(task.source, same(source));
- }
-
- void test_perform_valid() {
- String content = 'class A {}';
- Source source = new TestSource('test.dart', content);
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- ScanDartTask task = new ScanDartTask(context, source, content);
- task.perform(new ScanDartTaskTestTV_perform_valid(context, source));
- }
-}
-
-class ScanDartTaskTestTV_accept extends TestTaskVisitor<bool> {
- @override
- bool visitScanDartTask(ScanDartTask task) => true;
-}
-
-class ScanDartTaskTestTV_perform_valid extends TestTaskVisitor<bool> {
- InternalAnalysisContext context;
- Source source;
- ScanDartTaskTestTV_perform_valid(this.context, this.source);
- @override
- bool visitScanDartTask(ScanDartTask task) {
- CaughtException exception = task.exception;
- if (exception != null) {
- throw exception;
- }
- expect(task.tokenStream, isNotNull);
- expect(task.errors, hasLength(0));
- expect(task.lineInfo, isNotNull);
- expect(task.source, same(source));
- return true;
- }
-}
-
-@reflectiveTest
-class SdkCachePartitionTest extends EngineTestCase {
- void test_contains_false() {
- SdkCachePartition partition = new SdkCachePartition(null, 8);
- Source source = new TestSource();
- expect(partition.contains(source), isFalse);
- }
-
- void test_contains_true() {
- SdkCachePartition partition = new SdkCachePartition(null, 8);
- SourceFactory factory = new SourceFactory(
- [new DartUriResolver(DirectoryBasedDartSdk.defaultSdk)]);
- Source source = factory.forUri("dart:core");
- expect(partition.contains(source), isTrue);
- }
-
- void test_creation() {
- expect(new SdkCachePartition(null, 8), isNotNull);
- }
-}
-
-@reflectiveTest
class SourcesChangedEventTest {
void test_added() {
var source = new StringSource('', '/test.dart');
@@ -5692,12 +204,6 @@
}
@override
- EmbedderYamlLocator get embedderYamlLocator {
- fail("Unexpected invocation of get embedderYamlLocator");
- return null;
- }
-
- @override
void set analysisOptions(AnalysisOptions options) {
fail("Unexpected invocation of setAnalysisOptions");
}
@@ -5719,7 +225,13 @@
}
@override
- List<newContext.AnalysisTarget> get explicitTargets {
+ EmbedderYamlLocator get embedderYamlLocator {
+ fail("Unexpected invocation of get embedderYamlLocator");
+ return null;
+ }
+
+ @override
+ List<AnalysisTarget> get explicitTargets {
fail("Unexpected invocation of visitCacheItems");
return null;
}
@@ -5755,12 +267,6 @@
}
@override
- LibraryResolverFactory get libraryResolverFactory {
- fail("Unexpected invocation of getLibraryResolverFactory");
- return null;
- }
-
- @override
List<Source> get librarySources {
fail("Unexpected invocation of getLibrarySources");
return null;
@@ -5790,7 +296,7 @@
}
@override
- List<newContext.AnalysisTarget> get priorityTargets {
+ List<AnalysisTarget> get priorityTargets {
fail("Unexpected invocation of visitCacheItems");
return null;
}
@@ -5802,12 +308,6 @@
}
@override
- ResolverVisitorFactory get resolverVisitorFactory {
- fail("Unexpected invocation of getResolverVisitorFactory");
- return null;
- }
-
- @override
SourceFactory get sourceFactory {
fail("Unexpected invocation of getSourceFactory");
return null;
@@ -5825,12 +325,6 @@
}
@override
- AnalysisContextStatistics get statistics {
- fail("Unexpected invocation of getStatistics");
- return null;
- }
-
- @override
TypeProvider get typeProvider {
fail("Unexpected invocation of getTypeProvider");
return null;
@@ -5842,19 +336,13 @@
}
@override
- TypeResolverVisitorFactory get typeResolverVisitorFactory {
- fail("Unexpected invocation of getTypeResolverVisitorFactory");
- return null;
- }
-
- @override
TypeSystem get typeSystem {
fail("Unexpected invocation of getTypeSystem");
return null;
}
@override
- List<newContext.WorkManager> get workManagers {
+ List<WorkManager> get workManagers {
fail("Unexpected invocation of workManagers");
return null;
}
@@ -5894,13 +382,6 @@
}
@override
- @deprecated
- HtmlElement computeHtmlElement(Source source) {
- fail("Unexpected invocation of computeHtmlElement");
- return null;
- }
-
- @override
List<Source> computeImportedLibraries(Source source) {
fail("Unexpected invocation of computeImportedLibraries");
return null;
@@ -5925,12 +406,6 @@
}
@override
- CompilationUnit computeResolvableCompilationUnit(Source source) {
- fail("Unexpected invocation of computeResolvableCompilationUnit");
- return null;
- }
-
- @override
Future<CompilationUnit> computeResolvedCompilationUnitAsync(
Source source, Source librarySource) {
fail("Unexpected invocation of getResolvedCompilationUnitFuture");
@@ -5938,8 +413,7 @@
}
@override
- Object computeResult(
- newContext.AnalysisTarget target, newContext.ResultDescriptor result) {
+ Object computeResult(AnalysisTarget target, ResultDescriptor result) {
fail("Unexpected invocation of computeResult");
return null;
}
@@ -5962,7 +436,7 @@
}
@override
- CacheEntry getCacheEntry(newContext.AnalysisTarget target) {
+ CacheEntry getCacheEntry(AnalysisTarget target) {
fail("Unexpected invocation of visitCacheItems");
return null;
}
@@ -5975,7 +449,7 @@
}
@override
- Object getConfigurationData(newContext.ResultDescriptor key) {
+ Object getConfigurationData(ResultDescriptor key) {
fail("Unexpected invocation of getConfigurationData");
return null;
}
@@ -6005,13 +479,6 @@
}
@override
- @deprecated
- HtmlElement getHtmlElement(Source source) {
- fail("Unexpected invocation of getHtmlElement");
- return null;
- }
-
- @override
List<Source> getHtmlFilesReferencing(Source source) {
fail("Unexpected invocation of getHtmlFilesReferencing");
return null;
@@ -6086,15 +553,7 @@
}
@override
- @deprecated
- ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
- fail("Unexpected invocation of getResolvedHtmlUnit");
- return null;
- }
-
- @override
- Object getResult(
- newContext.AnalysisTarget target, newContext.ResultDescriptor result) {
+ Object getResult(AnalysisTarget target, ResultDescriptor result) {
fail("Unexpected invocation of getResult");
return null;
}
@@ -6130,8 +589,7 @@
}
@override
- Stream<ComputedResult> onResultComputed(
- newContext.ResultDescriptor descriptor) {
+ Stream<ComputedResult> onResultComputed(ResultDescriptor descriptor) {
fail("Unexpected invocation of onResultComputed");
return null;
}
@@ -6149,12 +607,6 @@
}
@override
- ht.HtmlUnit parseHtmlUnit(Source source) {
- fail("Unexpected invocation of parseHtmlUnit");
- return null;
- }
-
- @override
AnalysisResult performAnalysisTask() {
fail("Unexpected invocation of performAnalysisTask");
return null;
@@ -6185,20 +637,13 @@
}
@override
- @deprecated
- ht.HtmlUnit resolveHtmlUnit(Source htmlSource) {
- fail("Unexpected invocation of resolveHtmlUnit");
- return null;
- }
-
- @override
void setChangedContents(Source source, String contents, int offset,
int oldLength, int newLength) {
fail("Unexpected invocation of setChangedContents");
}
@override
- void setConfigurationData(newContext.ResultDescriptor key, Object data) {
+ void setConfigurationData(ResultDescriptor key, Object data) {
fail("Unexpected invocation of setConfigurationData");
}
@@ -6208,7 +653,7 @@
}
@override
- bool shouldErrorsBeAnalyzed(Source source, Object entry) {
+ bool shouldErrorsBeAnalyzed(Source source) {
fail("Unexpected invocation of shouldErrorsBeAnalyzed");
return false;
}
@@ -6224,844 +669,8 @@
return false;
}
- @deprecated
- @override
- void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
- DataDescriptor rowDesc, CacheState state)) {
- fail("Unexpected invocation of visitCacheItems");
- }
-
@override
void visitContentCache(ContentCacheVisitor visitor) {
fail("Unexpected invocation of visitContentCache");
}
}
-
-class TestAnalysisContext_test_applyChanges extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_applyChanges();
- @override
- ApplyChangesStatus applyChanges(ChangeSet changeSet) {
- invoked = true;
- return new ApplyChangesStatus(false);
- }
-}
-
-class TestAnalysisContext_test_computeDocumentationComment
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_computeDocumentationComment();
- @override
- String computeDocumentationComment(Element element) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_computeErrors extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_computeErrors();
- @override
- List<AnalysisError> computeErrors(Source source) {
- invoked = true;
- return AnalysisError.NO_ERRORS;
- }
-}
-
-class TestAnalysisContext_test_computeExportedLibraries
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_computeExportedLibraries();
- @override
- List<Source> computeExportedLibraries(Source source) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_computeHtmlElement extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_computeHtmlElement();
- @override
- @deprecated
- HtmlElement computeHtmlElement(Source source) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_computeImportedLibraries
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_computeImportedLibraries();
- @override
- List<Source> computeImportedLibraries(Source source) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_computeKindOf extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_computeKindOf();
- @override
- SourceKind computeKindOf(Source source) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_computeLibraryElement
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_computeLibraryElement();
- @override
- LibraryElement computeLibraryElement(Source source) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_computeLineInfo extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_computeLineInfo();
- @override
- LineInfo computeLineInfo(Source source) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_computeResolvableCompilationUnit
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_computeResolvableCompilationUnit();
- @override
- CompilationUnit computeResolvableCompilationUnit(Source source) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_dispose extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_dispose();
- @override
- void dispose() {
- invoked = true;
- }
-}
-
-class TestAnalysisContext_test_exists extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_exists();
- @override
- bool exists(Source source) {
- invoked = true;
- return false;
- }
-}
-
-class TestAnalysisContext_test_getAnalysisOptions extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getAnalysisOptions();
- @override
- AnalysisOptions get analysisOptions {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_getCompilationUnitElement
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getCompilationUnitElement();
- @override
- CompilationUnitElement getCompilationUnitElement(
- Source unitSource, Source librarySource) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_getContents extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getContents();
- @override
- TimestampedData<String> getContents(Source source) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_getElement extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getElement();
- @override
- Element getElement(ElementLocation location) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_getErrors extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getErrors();
- @override
- AnalysisErrorInfo getErrors(Source source) {
- invoked = true;
- return new AnalysisErrorInfoImpl(AnalysisError.NO_ERRORS, null);
- }
-}
-
-class TestAnalysisContext_test_getHtmlElement extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getHtmlElement();
- @override
- @deprecated
- HtmlElement getHtmlElement(Source source) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_getHtmlFilesReferencing
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getHtmlFilesReferencing();
- @override
- List<Source> getHtmlFilesReferencing(Source source) {
- invoked = true;
- return Source.EMPTY_LIST;
- }
-}
-
-class TestAnalysisContext_test_getHtmlSources extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getHtmlSources();
- @override
- List<Source> get htmlSources {
- invoked = true;
- return Source.EMPTY_LIST;
- }
-}
-
-class TestAnalysisContext_test_getKindOf extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getKindOf();
- @override
- SourceKind getKindOf(Source source) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_getLaunchableClientLibrarySources
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getLaunchableClientLibrarySources();
- @override
- List<Source> get launchableClientLibrarySources {
- invoked = true;
- return Source.EMPTY_LIST;
- }
-}
-
-class TestAnalysisContext_test_getLaunchableServerLibrarySources
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getLaunchableServerLibrarySources();
- @override
- List<Source> get launchableServerLibrarySources {
- invoked = true;
- return Source.EMPTY_LIST;
- }
-}
-
-class TestAnalysisContext_test_getLibrariesContaining
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getLibrariesContaining();
- @override
- List<Source> getLibrariesContaining(Source source) {
- invoked = true;
- return Source.EMPTY_LIST;
- }
-}
-
-class TestAnalysisContext_test_getLibrariesDependingOn
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getLibrariesDependingOn();
- @override
- List<Source> getLibrariesDependingOn(Source librarySource) {
- invoked = true;
- return Source.EMPTY_LIST;
- }
-}
-
-class TestAnalysisContext_test_getLibrariesReferencedFromHtml
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getLibrariesReferencedFromHtml();
- @override
- List<Source> getLibrariesReferencedFromHtml(Source htmlSource) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_getLibraryElement extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getLibraryElement();
- @override
- LibraryElement getLibraryElement(Source source) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_getLibrarySources extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getLibrarySources();
- @override
- List<Source> get librarySources {
- invoked = true;
- return Source.EMPTY_LIST;
- }
-}
-
-class TestAnalysisContext_test_getLineInfo extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getLineInfo();
- @override
- LineInfo getLineInfo(Source source) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_getModificationStamp
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getModificationStamp();
- @override
- int getModificationStamp(Source source) {
- invoked = true;
- return 0;
- }
-}
-
-class TestAnalysisContext_test_getPublicNamespace extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getPublicNamespace();
- @override
- Namespace getPublicNamespace(LibraryElement library) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_getResolvedCompilationUnit_element
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getResolvedCompilationUnit_element();
- @override
- CompilationUnit getResolvedCompilationUnit(
- Source unitSource, LibraryElement library) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_getResolvedCompilationUnit_source
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getResolvedCompilationUnit_source();
- @override
- CompilationUnit getResolvedCompilationUnit2(
- Source unitSource, Source librarySource) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_getResolvedHtmlUnit extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getResolvedHtmlUnit();
- @override
- @deprecated
- ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_getSourceFactory extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getSourceFactory();
- @override
- SourceFactory get sourceFactory {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_getStatistics extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getStatistics();
- @override
- AnalysisContextStatistics get statistics {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_getTypeProvider extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_getTypeProvider();
- @override
- TypeProvider get typeProvider {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_isClientLibrary extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_isClientLibrary();
- @override
- bool isClientLibrary(Source librarySource) {
- invoked = true;
- return false;
- }
-}
-
-class TestAnalysisContext_test_isDisposed extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_isDisposed();
- @override
- bool get isDisposed {
- invoked = true;
- return false;
- }
-}
-
-class TestAnalysisContext_test_isServerLibrary extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_isServerLibrary();
- @override
- bool isServerLibrary(Source librarySource) {
- invoked = true;
- return false;
- }
-}
-
-class TestAnalysisContext_test_parseCompilationUnit
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_parseCompilationUnit();
- @override
- CompilationUnit parseCompilationUnit(Source source) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_parseHtmlUnit extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_parseHtmlUnit();
- @override
- ht.HtmlUnit parseHtmlUnit(Source source) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_performAnalysisTask extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_performAnalysisTask();
- @override
- AnalysisResult performAnalysisTask() {
- invoked = true;
- return new AnalysisResult(new List<ChangeNotice>(0), 0, null, 0);
- }
-}
-
-class TestAnalysisContext_test_recordLibraryElements
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_recordLibraryElements();
- @override
- void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
- invoked = true;
- }
-}
-
-class TestAnalysisContext_test_resolveCompilationUnit
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_resolveCompilationUnit();
- @override
- CompilationUnit resolveCompilationUnit2(
- Source unitSource, Source librarySource) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_resolveCompilationUnit_element
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_resolveCompilationUnit_element();
- @override
- CompilationUnit resolveCompilationUnit(
- Source unitSource, LibraryElement library) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_resolveHtmlUnit extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_resolveHtmlUnit();
- @override
- @deprecated
- ht.HtmlUnit resolveHtmlUnit(Source htmlSource) {
- invoked = true;
- return null;
- }
-}
-
-class TestAnalysisContext_test_setAnalysisOptions extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_setAnalysisOptions();
- @override
- void set analysisOptions(AnalysisOptions options) {
- invoked = true;
- }
-}
-
-class TestAnalysisContext_test_setAnalysisPriorityOrder
- extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_setAnalysisPriorityOrder();
- @override
- void set analysisPriorityOrder(List<Source> sources) {
- invoked = true;
- }
-}
-
-class TestAnalysisContext_test_setChangedContents extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_setChangedContents();
- @override
- void setChangedContents(Source source, String contents, int offset,
- int oldLength, int newLength) {
- invoked = true;
- }
-}
-
-class TestAnalysisContext_test_setContents extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_setContents();
- @override
- void setContents(Source source, String contents) {
- invoked = true;
- }
-}
-
-class TestAnalysisContext_test_setSourceFactory extends TestAnalysisContext {
- bool invoked = false;
- TestAnalysisContext_test_setSourceFactory();
- @override
- void set sourceFactory(SourceFactory factory) {
- invoked = true;
- }
-}
-
-/**
- * Instances of the class `TestTaskVisitor` implement a task visitor that fails if any of its
- * methods are invoked. Subclasses typically override the expected methods to not cause a test
- * failure.
- */
-class TestTaskVisitor<E> implements AnalysisTaskVisitor<E> {
- @override
- E visitGenerateDartErrorsTask(GenerateDartErrorsTask task) {
- fail("Unexpectedly invoked visitGenerateDartErrorsTask");
- return null;
- }
-
- @override
- E visitGenerateDartHintsTask(GenerateDartHintsTask task) {
- fail("Unexpectedly invoked visitGenerateDartHintsTask");
- return null;
- }
-
- @override
- E visitGenerateDartLintsTask(GenerateDartLintsTask task) {
- fail("Unexpectedly invoked visitGenerateDartLintsTask");
- return null;
- }
-
- @override
- E visitGetContentTask(GetContentTask task) {
- fail("Unexpectedly invoked visitGetContentsTask");
- return null;
- }
-
- @override
- E visitIncrementalAnalysisTask(
- IncrementalAnalysisTask incrementalAnalysisTask) {
- fail("Unexpectedly invoked visitIncrementalAnalysisTask");
- return null;
- }
-
- @override
- E visitParseDartTask(ParseDartTask task) {
- fail("Unexpectedly invoked visitParseDartTask");
- return null;
- }
-
- @override
- E visitParseHtmlTask(ParseHtmlTask task) {
- fail("Unexpectedly invoked visitParseHtmlTask");
- return null;
- }
-
- @override
- E visitResolveDartLibraryCycleTask(ResolveDartLibraryCycleTask task) {
- fail("Unexpectedly invoked visitResolveDartLibraryCycleTask");
- return null;
- }
-
- @override
- E visitResolveDartLibraryTask(ResolveDartLibraryTask task) {
- fail("Unexpectedly invoked visitResolveDartLibraryTask");
- return null;
- }
-
- @override
- E visitResolveDartUnitTask(ResolveDartUnitTask task) {
- fail("Unexpectedly invoked visitResolveDartUnitTask");
- return null;
- }
-
- @override
- E visitResolveHtmlTask(ResolveHtmlTask task) {
- fail("Unexpectedly invoked visitResolveHtmlTask");
- return null;
- }
-
- @override
- E visitScanDartTask(ScanDartTask task) {
- fail("Unexpectedly invoked visitScanDartTask");
- return null;
- }
-}
-
-@reflectiveTest
-class UniversalCachePartitionTest extends EngineTestCase {
- void test_contains() {
- UniversalCachePartition partition =
- new UniversalCachePartition(null, 8, null);
- TestSource source = new TestSource();
- expect(partition.contains(source), isTrue);
- }
-
- void test_creation() {
- expect(new UniversalCachePartition(null, 8, null), isNotNull);
- }
-
- void test_entrySet() {
- UniversalCachePartition partition =
- new UniversalCachePartition(null, 8, null);
- TestSource source = new TestSource();
- DartEntry entry = new DartEntry();
- partition.put(source, entry);
- Map<Source, SourceEntry> entryMap = partition.map;
- expect(entryMap.length, 1);
- Source entryKey = entryMap.keys.first;
- expect(entryKey, same(source));
- expect(entryMap[entryKey], same(entry));
- }
-
- void test_get() {
- UniversalCachePartition partition =
- new UniversalCachePartition(null, 8, null);
- TestSource source = new TestSource();
- expect(partition.get(source), isNull);
- }
-
- void test_put_noFlush() {
- UniversalCachePartition partition =
- new UniversalCachePartition(null, 8, null);
- TestSource source = new TestSource();
- DartEntry entry = new DartEntry();
- partition.put(source, entry);
- expect(partition.get(source), same(entry));
- }
-
- void test_remove() {
- UniversalCachePartition partition =
- new UniversalCachePartition(null, 8, null);
- TestSource source = new TestSource();
- DartEntry entry = new DartEntry();
- partition.put(source, entry);
- expect(partition.get(source), same(entry));
- partition.remove(source);
- expect(partition.get(source), isNull);
- }
-
- void test_setMaxCacheSize() {
- UniversalCachePartition partition = new UniversalCachePartition(
- null, 8, new _UniversalCachePartitionTest_test_setMaxCacheSize());
- int size = 6;
- for (int i = 0; i < size; i++) {
- Source source = new TestSource("/test$i.dart");
- DartEntry entry = new DartEntry();
- entry.setValue(DartEntry.PARSED_UNIT, null);
- partition.put(source, entry);
- partition.accessedAst(source);
- }
- _assertNonFlushedCount(size, partition);
- int newSize = size - 2;
- partition.maxCacheSize = newSize;
- _assertNonFlushedCount(newSize, partition);
- }
-
- void test_size() {
- UniversalCachePartition partition =
- new UniversalCachePartition(null, 8, null);
- int size = 4;
- for (int i = 0; i < size; i++) {
- Source source = new TestSource("/test$i.dart");
- partition.put(source, new DartEntry());
- partition.accessedAst(source);
- }
- expect(partition.size(), size);
- }
-
- void _assertNonFlushedCount(
- int expectedCount, UniversalCachePartition partition) {
- int nonFlushedCount = 0;
- Map<Source, SourceEntry> entryMap = partition.map;
- entryMap.values.forEach((SourceEntry value) {
- if (value.getState(DartEntry.PARSED_UNIT) != CacheState.FLUSHED) {
- nonFlushedCount++;
- }
- });
- expect(nonFlushedCount, expectedCount);
- }
-}
-
-@reflectiveTest
-class WorkManagerTest extends EngineTestCase {
- void test_addFirst() {
- TestSource source1 = new TestSource("/f1.dart");
- TestSource source2 = new TestSource("/f2.dart");
- WorkManager manager = new WorkManager();
- manager.add(source1, SourcePriority.UNKNOWN);
- manager.addFirst(source2, SourcePriority.UNKNOWN);
- WorkManager_WorkIterator iterator = manager.iterator();
- expect(iterator.next(), same(source2));
- expect(iterator.next(), same(source1));
- }
-
- void test_creation() {
- expect(new WorkManager(), isNotNull);
- }
-
- void test_iterator_empty() {
- WorkManager manager = new WorkManager();
- WorkManager_WorkIterator iterator = manager.iterator();
- expect(iterator.hasNext, isFalse);
- try {
- iterator.next();
- fail("Expected NoSuchElementException");
- } on NoSuchElementException {}
- }
-
- void test_iterator_nonEmpty() {
- TestSource source = new TestSource();
- WorkManager manager = new WorkManager();
- manager.add(source, SourcePriority.UNKNOWN);
- WorkManager_WorkIterator iterator = manager.iterator();
- expect(iterator.hasNext, isTrue);
- expect(iterator.next(), same(source));
- }
-
- void test_remove() {
- TestSource source1 = new TestSource("/f1.dart");
- TestSource source2 = new TestSource("/f2.dart");
- TestSource source3 = new TestSource("/f3.dart");
- WorkManager manager = new WorkManager();
- manager.add(source1, SourcePriority.UNKNOWN);
- manager.add(source2, SourcePriority.UNKNOWN);
- manager.add(source3, SourcePriority.UNKNOWN);
- manager.remove(source2);
- WorkManager_WorkIterator iterator = manager.iterator();
- expect(iterator.next(), same(source1));
- expect(iterator.next(), same(source3));
- }
-
- void test_toString_empty() {
- WorkManager manager = new WorkManager();
- expect(manager.toString(), isNotNull);
- }
-
- void test_toString_nonEmpty() {
- WorkManager manager = new WorkManager();
- manager.add(new TestSource(), SourcePriority.HTML);
- manager.add(new TestSource(), SourcePriority.LIBRARY);
- manager.add(new TestSource(), SourcePriority.NORMAL_PART);
- manager.add(new TestSource(), SourcePriority.PRIORITY_PART);
- manager.add(new TestSource(), SourcePriority.UNKNOWN);
- expect(manager.toString(), isNotNull);
- }
-}
-
-class _AnalysisCacheTest_test_setMaxCacheSize implements CacheRetentionPolicy {
- @override
- RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry) =>
- RetentionPriority.LOW;
-}
-
-class _AnalysisContext_sourceChangeDuringResolution
- extends AnalysisContextForTests {
- @override
- DartEntry recordResolveDartLibraryTaskResults(ResolveDartLibraryTask task) {
- ChangeSet changeSet = new ChangeSet();
- changeSet.changedSource(task.librarySource);
- applyChanges(changeSet);
- return super.recordResolveDartLibraryTaskResults(task);
- }
-}
-
-class _AnalysisContextImplTest_test_applyChanges_removeContainer
- implements SourceContainer {
- Source libB;
- _AnalysisContextImplTest_test_applyChanges_removeContainer(this.libB);
- @override
- bool contains(Source source) => source == libB;
-}
-
-class _Source_getContent_throwException extends NonExistingSource {
- _Source_getContent_throwException(String name)
- : super(name, pathos.toUri(name), UriKind.FILE_URI);
-
- @override
- TimestampedData<String> get contents {
- throw 'Read error';
- }
-
- @override
- bool exists() => true;
-}
-
-class _UniversalCachePartitionTest_test_setMaxCacheSize
- implements CacheRetentionPolicy {
- @override
- RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry) =>
- RetentionPriority.LOW;
-}
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index dd9394c..b36d31e 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -2,13 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.incremental_resolver_test;
+library analyzer.test.generated.incremental_resolver_test;
-import 'package:analyzer/src/context/cache.dart' as task;
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisCache;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/incremental_logger.dart' as log;
import 'package:analyzer/src/generated/incremental_resolution_validator.dart';
@@ -3026,22 +3025,12 @@
@override
void reset() {
- if (AnalysisEngine.instance.useTaskModel) {
- analysisContext2 = AnalysisContextFactory.contextWithCore();
- } else {
- analysisContext2 = AnalysisContextFactory.oldContextWithCore();
- }
+ analysisContext2 = AnalysisContextFactory.contextWithCore();
}
@override
void resetWithOptions(AnalysisOptions options) {
- if (AnalysisEngine.instance.useTaskModel) {
- analysisContext2 =
- AnalysisContextFactory.contextWithCoreAndOptions(options);
- } else {
- analysisContext2 =
- AnalysisContextFactory.oldContextWithCoreAndOptions(options);
- }
+ AnalysisContextFactory.contextWithCoreAndOptions(options);
}
void setUp() {
@@ -3391,28 +3380,10 @@
int updateEndOld = updateOffset + edit.length;
int updateOldNew = updateOffset + edit.replacement.length;
IncrementalResolver resolver;
- if (AnalysisEngine.instance.useTaskModel) {
- LibrarySpecificUnit lsu = new LibrarySpecificUnit(source, source);
- task.AnalysisCache cache = analysisContext2.analysisCache;
- resolver = new IncrementalResolver(
- null,
- cache.get(source),
- cache.get(lsu),
- unit.element,
- updateOffset,
- updateEndOld,
- updateOldNew);
- } else {
- resolver = new IncrementalResolver(
- (analysisContext2 as AnalysisContextImpl)
- .getReadableSourceEntryOrNull(source),
- null,
- null,
- unit.element,
- updateOffset,
- updateEndOld,
- updateOldNew);
- }
+ LibrarySpecificUnit lsu = new LibrarySpecificUnit(source, source);
+ AnalysisCache cache = analysisContext2.analysisCache;
+ resolver = new IncrementalResolver(cache.get(source), cache.get(lsu),
+ unit.element, updateOffset, updateEndOld, updateOldNew);
bool success = resolver.resolve(newNode);
expect(success, isTrue);
List<AnalysisError> newErrors = analysisContext.computeErrors(source);
@@ -4470,7 +4441,7 @@
// Invalidate VERIFY_ERRORS.
AnalysisCache cache = analysisContext2.analysisCache;
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- task.CacheEntry cacheEntry = cache.get(target);
+ CacheEntry cacheEntry = cache.get(target);
expect(cacheEntry.getValue(VERIFY_ERRORS), hasLength(2));
cacheEntry.setState(VERIFY_ERRORS, CacheState.INVALID);
// Don't run tasks, so don't recompute VERIFY_ERRORS before incremental.
diff --git a/pkg/analyzer/test/generated/incremental_scanner_test.dart b/pkg/analyzer/test/generated/incremental_scanner_test.dart
index 6b72aa6..fad6244 100644
--- a/pkg/analyzer/test/generated/incremental_scanner_test.dart
+++ b/pkg/analyzer/test/generated/incremental_scanner_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.incremental_scanner_test;
+library analyzer.test.generated.incremental_scanner_test;
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/incremental_scanner.dart';
diff --git a/pkg/analyzer/test/generated/java_core_test.dart b/pkg/analyzer/test/generated/java_core_test.dart
index e60e9c1..0a914ec 100644
--- a/pkg/analyzer/test/generated/java_core_test.dart
+++ b/pkg/analyzer/test/generated/java_core_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.java_core_test;
+library analyzer.test.generated.java_core_test;
import 'package:analyzer/src/generated/java_core.dart';
import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/generated/java_io_test.dart b/pkg/analyzer/test/generated/java_io_test.dart
index 2bd611d..0316817 100644
--- a/pkg/analyzer/test/generated/java_io_test.dart
+++ b/pkg/analyzer/test/generated/java_io_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.java_io_test;
+library analyzer.test.generated.java_io_test;
import 'package:analyzer/src/generated/java_io.dart';
import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 719d159..24928c2 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.non_error_resolver_test;
+library analyzer.test.generated.non_error_resolver_test;
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
@@ -262,6 +262,82 @@
verify([source]);
}
+ void test_assert_with_message_await() {
+ resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+ Source source = addSource('''
+import 'dart:async';
+f() async {
+ assert(false, await g());
+}
+Future<String> g() => null;
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_assert_with_message_dynamic() {
+ resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+ Source source = addSource('''
+f() {
+ assert(false, g());
+}
+g() => null;
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_assert_with_message_non_string() {
+ resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+ Source source = addSource('''
+f() {
+ assert(false, 3);
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_assert_with_message_null() {
+ resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+ Source source = addSource('''
+f() {
+ assert(false, null);
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_assert_with_message_string() {
+ resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+ Source source = addSource('''
+f() {
+ assert(false, 'message');
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_assert_with_message_suppresses_unused_var_hint() {
+ resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+ Source source = addSource('''
+f() {
+ String message = 'msg';
+ assert(true, message);
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
void test_assignability_function_expr_rettype_from_typedef_cls() {
// In the code below, the type of (() => f()) has a return type which is
// a class, and that class is inferred from the return type of the typedef
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index d3c995c..574832b 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.parser_test;
+library analyzer.test.generated.parser_test;
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
@@ -16,7 +16,7 @@
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:unittest/unittest.dart';
+import 'package:unittest/unittest.dart' hide Configuration;
import '../reflective_tests.dart';
import '../utils.dart';
@@ -1344,6 +1344,11 @@
parse4("parseStringLiteral", "'\$1'", [ParserErrorCode.MISSING_IDENTIFIER]);
}
+ void test_invalidLiteralInConfiguration() {
+ parse4("parseConfiguration", "if (a == 'x \$y z') 'a.dart'",
+ [ParserErrorCode.INVALID_LITERAL_IN_CONFIGURATION]);
+ }
+
void test_invalidOperator() {
parse3("parseClassMember", <Object>["C"], "void operator ===(x) {}",
[ParserErrorCode.INVALID_OPERATOR]);
@@ -2640,6 +2645,12 @@
static bool parseFunctionBodies = true;
/**
+ * A flag indicating whether conditional directives support should be enabled
+ * for a specific test.
+ */
+ bool enableConditionalDirectives = false;
+
+ /**
* A flag indicating whether generic method support should be enabled for a
* specific test.
*/
@@ -2700,6 +2711,7 @@
// Parse the source.
//
Parser parser = createParser(listener);
+ parser.parseConditionalDirectives = enableConditionalDirectives;
parser.parseGenericMethods = enableGenericMethods;
parser.parseGenericMethodComments = enableGenericMethodComments;
parser.parseFunctionBodies = parseFunctionBodies;
@@ -5158,6 +5170,36 @@
expect(statement.assertKeyword, isNotNull);
expect(statement.leftParenthesis, isNotNull);
expect(statement.condition, isNotNull);
+ expect(statement.comma, isNull);
+ expect(statement.message, isNull);
+ expect(statement.rightParenthesis, isNotNull);
+ expect(statement.semicolon, isNotNull);
+ }
+
+ void test_parseAssertStatement_messageLowPrecedence() {
+ // Using a throw expression as an assert message would be silly in
+ // practice, but it's the lowest precedence expression type, so verifying
+ // that it works should give us high confidence that other expression types
+ // will work as well.
+ AssertStatement statement =
+ parse4('parseAssertStatement', 'assert (x, throw "foo");');
+ expect(statement.assertKeyword, isNotNull);
+ expect(statement.leftParenthesis, isNotNull);
+ expect(statement.condition, isNotNull);
+ expect(statement.comma, isNotNull);
+ expect(statement.message, isNotNull);
+ expect(statement.rightParenthesis, isNotNull);
+ expect(statement.semicolon, isNotNull);
+ }
+
+ void test_parseAssertStatement_messageString() {
+ AssertStatement statement =
+ parse4('parseAssertStatement', 'assert (x, "foo");');
+ expect(statement.assertKeyword, isNotNull);
+ expect(statement.leftParenthesis, isNotNull);
+ expect(statement.condition, isNotNull);
+ expect(statement.comma, isNotNull);
+ expect(statement.message, isNotNull);
expect(statement.rightParenthesis, isNotNull);
expect(statement.semicolon, isNotNull);
}
@@ -7133,6 +7175,54 @@
expect(expression.elseExpression, isNotNull);
}
+ void test_parseConfiguration_noOperator_dottedIdentifier() {
+ Configuration configuration =
+ parse4('parseConfiguration', "if (a.b) 'c.dart'");
+ expect(configuration.ifKeyword, isNotNull);
+ expect(configuration.leftParenthesis, isNotNull);
+ _expectDottedName(configuration.name, ["a", "b"]);
+ expect(configuration.equalToken, isNull);
+ expect(configuration.value, isNull);
+ expect(configuration.rightParenthesis, isNotNull);
+ expect(configuration.libraryUri, isNotNull);
+ }
+
+ void test_parseConfiguration_noOperator_simpleIdentifier() {
+ Configuration configuration =
+ parse4('parseConfiguration', "if (a) 'b.dart'");
+ expect(configuration.ifKeyword, isNotNull);
+ expect(configuration.leftParenthesis, isNotNull);
+ _expectDottedName(configuration.name, ["a"]);
+ expect(configuration.equalToken, isNull);
+ expect(configuration.value, isNull);
+ expect(configuration.rightParenthesis, isNotNull);
+ expect(configuration.libraryUri, isNotNull);
+ }
+
+ void test_parseConfiguration_operator_dottedIdentifier() {
+ Configuration configuration =
+ parse4('parseConfiguration', "if (a.b == 'c') 'd.dart'");
+ expect(configuration.ifKeyword, isNotNull);
+ expect(configuration.leftParenthesis, isNotNull);
+ _expectDottedName(configuration.name, ["a", "b"]);
+ expect(configuration.equalToken, isNotNull);
+ expect(configuration.value, isNotNull);
+ expect(configuration.rightParenthesis, isNotNull);
+ expect(configuration.libraryUri, isNotNull);
+ }
+
+ void test_parseConfiguration_operator_simpleIdentifier() {
+ Configuration configuration =
+ parse4('parseConfiguration', "if (a == 'b') 'c.dart'");
+ expect(configuration.ifKeyword, isNotNull);
+ expect(configuration.leftParenthesis, isNotNull);
+ _expectDottedName(configuration.name, ["a"]);
+ expect(configuration.equalToken, isNotNull);
+ expect(configuration.value, isNotNull);
+ expect(configuration.rightParenthesis, isNotNull);
+ expect(configuration.libraryUri, isNotNull);
+ }
+
void test_parseConstExpression_instanceCreation() {
InstanceCreationExpression expression =
parse4("parseConstExpression", "const A()");
@@ -7398,6 +7488,16 @@
expect(statement.semicolon, isNotNull);
}
+ void test_parseDottedName_multiple() {
+ DottedName name = parse4("parseDottedName", "a.b.c");
+ _expectDottedName(name, ["a", "b", "c"]);
+ }
+
+ void test_parseDottedName_single() {
+ DottedName name = parse4("parseDottedName", "a");
+ _expectDottedName(name, ["a"]);
+ }
+
void test_parseEmptyStatement() {
EmptyStatement statement = parse4("parseEmptyStatement", ";");
expect(statement.semicolon, isNotNull);
@@ -7454,6 +7554,35 @@
expect(expression.rightOperand, isNotNull);
}
+ void test_parseExportDirective_configuration_multiple() {
+ enableConditionalDirectives = true;
+ ExportDirective directive = parse(
+ "parseExportDirective",
+ <Object>[emptyCommentAndMetadata()],
+ "export 'lib/lib.dart' if (a) 'b.dart' if (c) 'd.dart';");
+ expect(directive.keyword, isNotNull);
+ expect(directive.uri, isNotNull);
+ expect(directive.configurations, hasLength(2));
+ _expectDottedName(directive.configurations[0].name, ['a']);
+ _expectDottedName(directive.configurations[1].name, ['c']);
+ expect(directive.combinators, hasLength(0));
+ expect(directive.semicolon, isNotNull);
+ }
+
+ void test_parseExportDirective_configuration_single() {
+ enableConditionalDirectives = true;
+ ExportDirective directive = parse(
+ "parseExportDirective",
+ <Object>[emptyCommentAndMetadata()],
+ "export 'lib/lib.dart' if (a.b == 'c.dart') '';");
+ expect(directive.keyword, isNotNull);
+ expect(directive.uri, isNotNull);
+ expect(directive.configurations, hasLength(1));
+ _expectDottedName(directive.configurations[0].name, ['a', 'b']);
+ expect(directive.combinators, hasLength(0));
+ expect(directive.semicolon, isNotNull);
+ }
+
void test_parseExportDirective_hide() {
ExportDirective directive = parse(
"parseExportDirective",
@@ -8629,6 +8758,41 @@
expect(clause.implementsKeyword, isNotNull);
}
+ void test_parseImportDirective_configuration_multiple() {
+ enableConditionalDirectives = true;
+ ImportDirective directive = parse(
+ "parseImportDirective",
+ <Object>[emptyCommentAndMetadata()],
+ "import 'lib/lib.dart' if (a) 'b.dart' if (c) 'd.dart';");
+ expect(directive.keyword, isNotNull);
+ expect(directive.uri, isNotNull);
+ expect(directive.configurations, hasLength(2));
+ _expectDottedName(directive.configurations[0].name, ['a']);
+ _expectDottedName(directive.configurations[1].name, ['c']);
+ expect(directive.deferredKeyword, isNull);
+ expect(directive.asKeyword, isNull);
+ expect(directive.prefix, isNull);
+ expect(directive.combinators, hasLength(0));
+ expect(directive.semicolon, isNotNull);
+ }
+
+ void test_parseImportDirective_configuration_single() {
+ enableConditionalDirectives = true;
+ ImportDirective directive = parse(
+ "parseImportDirective",
+ <Object>[emptyCommentAndMetadata()],
+ "import 'lib/lib.dart' if (a.b == 'c.dart') '';");
+ expect(directive.keyword, isNotNull);
+ expect(directive.uri, isNotNull);
+ expect(directive.configurations, hasLength(1));
+ _expectDottedName(directive.configurations[0].name, ['a', 'b']);
+ expect(directive.deferredKeyword, isNull);
+ expect(directive.asKeyword, isNull);
+ expect(directive.prefix, isNull);
+ expect(directive.combinators, hasLength(0));
+ expect(directive.semicolon, isNotNull);
+ }
+
void test_parseImportDirective_deferred() {
ImportDirective directive = parse(
"parseImportDirective",
@@ -11008,6 +11172,17 @@
return invokeParserMethod2("createSyntheticStringLiteral", "", listener);
}
+ void _expectDottedName(DottedName name, List<String> expectedComponents) {
+ int count = expectedComponents.length;
+ NodeList<SimpleIdentifier> components = name.components;
+ expect(components, hasLength(count));
+ for (int i = 0; i < count; i++) {
+ SimpleIdentifier component = components[i];
+ expect(component, isNotNull);
+ expect(component.name, expectedComponents[i]);
+ }
+ }
+
/**
* Invoke the method [Parser.isFunctionDeclaration] with the parser set to the token
* stream produced by scanning the given source.
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index da69a28..c57ca34 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -2,11 +2,11 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.resolver_test;
+library analyzer.test.generated.resolver_test;
import 'dart:collection';
-import 'package:analyzer/src/context/context.dart' as newContext;
+import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/element_resolver.dart';
@@ -44,16 +44,6 @@
runReflectiveTests(ScopeTest);
runReflectiveTests(ElementResolverTest);
runReflectiveTests(InheritanceManagerTest);
- if (!AnalysisEngine.instance.useTaskModel) {
- runReflectiveTests(LibraryElementBuilderTest);
- }
- if (!AnalysisEngine.instance.useTaskModel) {
- runReflectiveTests(LibraryResolver2Test);
- }
- if (!AnalysisEngine.instance.useTaskModel) {
- runReflectiveTests(LibraryResolverTest);
- }
- runReflectiveTests(LibraryTest);
runReflectiveTests(StaticTypeAnalyzerTest);
runReflectiveTests(StaticTypeAnalyzer2Test);
runReflectiveTests(SubtypeManagerTest);
@@ -89,10 +79,6 @@
* Return the context that was created.
*/
static InternalAnalysisContext contextWithCore() {
- if (AnalysisEngine.instance.useTaskModel) {
- NewAnalysisContextForTests context = new NewAnalysisContextForTests();
- return initContextWithCore(context);
- }
AnalysisContextForTests context = new AnalysisContextForTests();
return initContextWithCore(context);
}
@@ -103,11 +89,6 @@
*/
static InternalAnalysisContext contextWithCoreAndOptions(
AnalysisOptions options) {
- if (AnalysisEngine.instance.useTaskModel) {
- NewAnalysisContextForTests context = new NewAnalysisContextForTests();
- context._internalSetAnalysisOptions(options);
- return initContextWithCore(context);
- }
AnalysisContextForTests context = new AnalysisContextForTests();
context._internalSetAnalysisOptions(options);
return initContextWithCore(context);
@@ -212,8 +193,8 @@
'onValue', futureThenR, [futureElement.typeParameters[0]], null);
DartType futureRType = futureElement.type.substitute4([futureThenR.type]);
- MethodElementImpl thenMethod = ElementFactory.methodElementWithParameters(
- futureElement, "then", futureRType, [
+ MethodElementImpl thenMethod = ElementFactory
+ .methodElementWithParameters(futureElement, "then", futureRType, [
ElementFactory.requiredParameter2("onValue", thenOnValue.type),
ElementFactory.namedParameter2("onError", provider.functionType)
]);
@@ -301,8 +282,8 @@
ClassElementImpl htmlDocumentElement =
ElementFactory.classElement("HtmlDocument", documentElement.type);
htmlDocumentElement.methods = <MethodElement>[
- ElementFactory.methodElement(
- "query", elementType, <DartType>[provider.stringType])
+ ElementFactory
+ .methodElement("query", elementType, <DartType>[provider.stringType])
];
htmlUnit.types = <ClassElement>[
ElementFactory.classElement("AnchorElement", elementType),
@@ -322,8 +303,8 @@
ElementFactory.functionElement3("query", elementElement,
<ClassElement>[provider.stringType.element], ClassElement.EMPTY_LIST)
];
- TopLevelVariableElementImpl document = ElementFactory
- .topLevelVariableElement3(
+ TopLevelVariableElementImpl document =
+ ElementFactory.topLevelVariableElement3(
"document", false, true, htmlDocumentElement.type);
htmlUnit.topLevelVariables = <TopLevelVariableElement>[document];
htmlUnit.accessors = <PropertyAccessorElement>[document.getter];
@@ -410,31 +391,11 @@
context.recordLibraryElements(elementMap);
return context;
}
-
- /**
- * Create an analysis context that has a fake core library already resolved.
- * Return the context that was created.
- */
- static AnalysisContextImpl oldContextWithCore() {
- AnalysisContextForTests context = new AnalysisContextForTests();
- return initContextWithCore(context);
- }
-
- /**
- * Create an analysis context that uses the given [options] and has a fake
- * core library already resolved. Return the context that was created.
- */
- static AnalysisContextImpl oldContextWithCoreAndOptions(
- AnalysisOptions options) {
- AnalysisContextForTests context = new AnalysisContextForTests();
- context._internalSetAnalysisOptions(options);
- return initContextWithCore(context);
- }
}
/**
- * Instances of the class `AnalysisContextForTests` implement an analysis context that has a
- * fake SDK that is much smaller and faster for testing purposes.
+ * An analysis context that has a fake SDK that is much smaller and faster for
+ * testing purposes.
*/
class AnalysisContextForTests extends AnalysisContextImpl {
@override
@@ -1303,6 +1264,7 @@
@override
void setUp() {
+ super.setUp();
_listener = new GatheringErrorListener();
_typeProvider = new TestTypeProvider();
_resolver = _createResolver();
@@ -2003,12 +1965,9 @@
definingCompilationUnit.source = source;
_definingLibrary = ElementFactory.library(context, "test");
_definingLibrary.definingCompilationUnit = definingCompilationUnit;
- Library library = new Library(context, _listener, source);
- library.libraryElement = _definingLibrary;
_visitor = new ResolverVisitor(
- library.libraryElement, source, _typeProvider, library.errorListener,
- nameScope: library.libraryScope,
- inheritanceManager: library.inheritanceManager);
+ _definingLibrary, source, _typeProvider, _listener,
+ nameScope: new LibraryScope(_definingLibrary, _listener));
try {
return _visitor.elementResolver;
} catch (exception) {
@@ -3589,6 +3548,36 @@
verify([source]);
}
+ void test_unnecessaryNoSuchMethod_blockBody() {
+ Source source = addSource(r'''
+class A {
+ noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+ mmm();
+ noSuchMethod(y) {
+ return super.noSuchMethod(y);
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNNECESSARY_NO_SUCH_METHOD]);
+ verify([source]);
+ }
+
+ void test_unnecessaryNoSuchMethod_expressionBody() {
+ Source source = addSource(r'''
+class A {
+ noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+ mmm();
+ noSuchMethod(y) => super.noSuchMethod(y);
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNNECESSARY_NO_SUCH_METHOD]);
+ verify([source]);
+ }
+
void test_unnecessaryTypeCheck_null_is_Null() {
Source source = addSource("bool b = null is Null;");
computeLibrarySourceErrors(source);
@@ -3773,6 +3762,22 @@
verify([source]);
}
+ void test_unusedElement_class_isUsed_fieldDeclaration() {
+ enableUnusedElement = true;
+ var src = r'''
+class Foo {
+ _Bar x;
+}
+
+class _Bar {
+}
+''';
+ Source source = addSource(src);
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
void test_unusedElement_class_notUsed_variableDeclaration() {
enableUnusedElement = true;
Source source = addSource(r'''
@@ -4841,7 +4846,7 @@
}
@reflectiveTest
-class InheritanceManagerTest extends EngineTestCase {
+class InheritanceManagerTest {
/**
* The type provider used to access the types.
*/
@@ -4862,7 +4867,6 @@
*/
int _numOfMembersInObject = 0;
- @override
void setUp() {
_typeProvider = new TestTypeProvider();
_inheritanceManager = _createInheritanceManager();
@@ -5099,7 +5103,8 @@
_assertNoErrors(classA);
}
- void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_getter_method() {
+ void
+ test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_getter_method() {
// class I1 { int m(); }
// class I2 { int get m; }
// class A implements I2, I1 {}
@@ -5122,7 +5127,8 @@
[StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
}
- void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_int_str() {
+ void
+ test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_int_str() {
// class I1 { int m(); }
// class I2 { String m(); }
// class A implements I1, I2 {}
@@ -5132,8 +5138,8 @@
ElementFactory.methodElement(methodName, null, [_typeProvider.intType]);
classI1.methods = <MethodElement>[methodM1];
ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElement methodM2 = ElementFactory.methodElement(
- methodName, null, [_typeProvider.stringType]);
+ MethodElement methodM2 = ElementFactory
+ .methodElement(methodName, null, [_typeProvider.stringType]);
classI2.methods = <MethodElement>[methodM2];
ClassElementImpl classA = ElementFactory.classElement2("A");
classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
@@ -5145,7 +5151,8 @@
classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
}
- void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_method_getter() {
+ void
+ test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_method_getter() {
// class I1 { int m(); }
// class I2 { int get m; }
// class A implements I1, I2 {}
@@ -5168,7 +5175,8 @@
[StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
}
- void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_numOfRequiredParams() {
+ void
+ test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_numOfRequiredParams() {
// class I1 { dynamic m(int, [int]); }
// class I2 { dynamic m(int, int, int); }
// class A implements I1, I2 {}
@@ -5217,14 +5225,15 @@
classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
}
- void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_str_int() {
+ void
+ test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_str_int() {
// class I1 { int m(); }
// class I2 { String m(); }
// class A implements I2, I1 {}
ClassElementImpl classI1 = ElementFactory.classElement2("I1");
String methodName = "m";
- MethodElement methodM1 = ElementFactory.methodElement(
- methodName, null, [_typeProvider.stringType]);
+ MethodElement methodM1 = ElementFactory
+ .methodElement(methodName, null, [_typeProvider.stringType]);
classI1.methods = <MethodElement>[methodM1];
ClassElementImpl classI2 = ElementFactory.classElement2("I2");
MethodElement methodM2 =
@@ -5326,7 +5335,8 @@
_assertNoErrors(classA);
}
- void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_getters() {
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_getters() {
// class I1 { int get g; }
// class I2 { num get g; }
// class A implements I1, I2 {}
@@ -5350,7 +5360,8 @@
_assertNoErrors(classA);
}
- void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_methods() {
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_methods() {
// class I1 { dynamic m(int); }
// class I2 { dynamic m(num); }
// class A implements I1, I2 {}
@@ -5384,7 +5395,8 @@
_assertNoErrors(classA);
}
- void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_setters() {
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_setters() {
// class I1 { set s(int); }
// class I2 { set s(num); }
// class A implements I1, I2 {}
@@ -5409,7 +5421,8 @@
_assertNoErrors(classA);
}
- void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_getters() {
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_getters() {
// class A {}
// class B extends A {}
// class C extends B {}
@@ -5448,7 +5461,8 @@
_assertNoErrors(classD);
}
- void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_methods() {
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_methods() {
// class A {}
// class B extends A {}
// class C extends B {}
@@ -5502,7 +5516,8 @@
_assertNoErrors(classD);
}
- void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_setters() {
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_setters() {
// class A {}
// class B extends A {}
// class C extends B {}
@@ -5542,7 +5557,8 @@
_assertNoErrors(classD);
}
- void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods() {
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods() {
// class I1 { int m(); }
// class I2 { int m([int]); }
// class A implements I1, I2 {}
@@ -5569,7 +5585,8 @@
_assertNoErrors(classA);
}
- void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods() {
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods() {
// class I1 { int m(); }
// class I2 { int m([int]); }
// class I3 { int m([int, int]); }
@@ -5614,7 +5631,8 @@
_assertNoErrors(classA);
}
- void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods() {
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods() {
// class I1 { int m(); }
// class I2 { int m(); }
// class I3 { int m([int]); }
@@ -6066,217 +6084,6 @@
}
@reflectiveTest
-class LibraryElementBuilderTest extends EngineTestCase {
- /**
- * The analysis context used to analyze sources.
- */
- InternalAnalysisContext _context;
-
- /**
- * Add a source file to the content provider. The file path should be absolute.
- *
- * @param filePath the path of the file being added
- * @param contents the contents to be returned by the content provider for the specified file
- * @return the source object representing the added file
- */
- Source addSource(String filePath, String contents) {
- Source source = new FileBasedSource(FileUtilities2.createFile(filePath));
- _context.setContents(source, contents);
- return source;
- }
-
- @override
- void setUp() {
- _context = AnalysisContextFactory.contextWithCore();
- }
-
- @override
- void tearDown() {
- _context = null;
- super.tearDown();
- }
-
- void test_accessorsAcrossFiles() {
- Source librarySource = addSource(
- "/lib.dart",
- r'''
-library lib;
-part 'first.dart';
-part 'second.dart';''');
- addSource(
- "/first.dart",
- r'''
-part of lib;
-int get V => 0;''');
- addSource(
- "/second.dart",
- r'''
-part of lib;
-void set V(int v) {}''');
- LibraryElement element = _buildLibrary(librarySource);
- expect(element, isNotNull);
- List<CompilationUnitElement> sourcedUnits = element.parts;
- expect(sourcedUnits, hasLength(2));
- List<PropertyAccessorElement> firstAccessors = sourcedUnits[0].accessors;
- expect(firstAccessors, hasLength(1));
- List<PropertyAccessorElement> secondAccessors = sourcedUnits[1].accessors;
- expect(secondAccessors, hasLength(1));
- expect(secondAccessors[0].variable, same(firstAccessors[0].variable));
- }
-
- void test_empty() {
- Source librarySource = addSource("/lib.dart", "library lib;");
- LibraryElement element = _buildLibrary(librarySource);
- expect(element, isNotNull);
- expect(element.name, "lib");
- expect(element.entryPoint, isNull);
- expect(element.importedLibraries, hasLength(0));
- expect(element.imports, hasLength(0));
- expect(element.library, same(element));
- expect(element.prefixes, hasLength(0));
- expect(element.parts, hasLength(0));
- CompilationUnitElement unit = element.definingCompilationUnit;
- expect(unit, isNotNull);
- expect(unit.name, "lib.dart");
- expect(unit.library, element);
- expect(unit.accessors, hasLength(0));
- expect(unit.functions, hasLength(0));
- expect(unit.functionTypeAliases, hasLength(0));
- expect(unit.types, hasLength(0));
- expect(unit.topLevelVariables, hasLength(0));
- }
-
- void test_libraryElement_docRange() {
- String code = r'''
-/// My dart doc.
-library lib;
-
-class A {}''';
- Source librarySource = addSource("/lib.dart", code);
- LibraryElement element = _buildLibrary(librarySource);
- expect(element, isNotNull);
- SourceRange docRange = element.docRange;
- expect(docRange, isNotNull);
- expect(docRange.offset, code.indexOf('/// My dart doc.'));
- expect(docRange.length, '/// My dart doc.'.length);
- }
-
- void test_missingLibraryDirectiveWithPart() {
- addSource("/a.dart", "part of lib;");
- Source librarySource = addSource("/lib.dart", "part 'a.dart';");
- LibraryElement element = _buildLibrary(
- librarySource, [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]);
- expect(element, isNotNull);
- }
-
- void test_missingPartOfDirective() {
- addSource("/a.dart", "class A {}");
- Source librarySource = addSource(
- "/lib.dart",
- r'''
-library lib;
-
-part 'a.dart';''');
- LibraryElement element =
- _buildLibrary(librarySource, [CompileTimeErrorCode.PART_OF_NON_PART]);
- expect(element, isNotNull);
- }
-
- void test_multipleFiles() {
- Source librarySource = addSource(
- "/lib.dart",
- r'''
-library lib;
-part 'first.dart';
-part 'second.dart';
-
-class A {}''');
- addSource(
- "/first.dart",
- r'''
-part of lib;
-class B {}''');
- addSource(
- "/second.dart",
- r'''
-part of lib;
-class C {}''');
- LibraryElement element = _buildLibrary(librarySource);
- expect(element, isNotNull);
- List<CompilationUnitElement> sourcedUnits = element.parts;
- expect(sourcedUnits, hasLength(2));
- _assertTypes(element.definingCompilationUnit, ["A"]);
- if (sourcedUnits[0].name == "first.dart") {
- _assertTypes(sourcedUnits[0], ["B"]);
- _assertTypes(sourcedUnits[1], ["C"]);
- } else {
- _assertTypes(sourcedUnits[0], ["C"]);
- _assertTypes(sourcedUnits[1], ["B"]);
- }
- }
-
- void test_singleFile() {
- Source librarySource = addSource(
- "/lib.dart",
- r'''
-/// My dart doc.
-library lib;
-
-class A {}''');
- LibraryElement element = _buildLibrary(librarySource);
- expect(element, isNotNull);
- _assertTypes(element.definingCompilationUnit, ["A"]);
- }
-
- /**
- * Ensure that there are elements representing all of the types in the given array of type names.
- *
- * @param unit the compilation unit containing the types
- * @param typeNames the names of the types that should be found
- */
- void _assertTypes(CompilationUnitElement unit, List<String> typeNames) {
- expect(unit, isNotNull);
- List<ClassElement> types = unit.types;
- expect(types, hasLength(typeNames.length));
- for (ClassElement type in types) {
- expect(type, isNotNull);
- String actualTypeName = type.displayName;
- bool wasExpected = false;
- for (String expectedTypeName in typeNames) {
- if (expectedTypeName == actualTypeName) {
- wasExpected = true;
- }
- }
- if (!wasExpected) {
- fail("Found unexpected type $actualTypeName");
- }
- }
- }
-
- /**
- * Build the element model for the library whose defining compilation unit has the given source.
- *
- * @param librarySource the source of the defining compilation unit for the library
- * @param expectedErrorCodes the errors that are expected to be found while building the element
- * model
- * @return the element model that was built for the library
- * @throws Exception if the element model could not be built
- */
- LibraryElement _buildLibrary(Source librarySource,
- [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
- LibraryResolver resolver = new LibraryResolver(_context);
- LibraryElementBuilder builder = new LibraryElementBuilder(
- resolver.analysisContext, resolver.errorListener);
- Library library = resolver.createLibrary(librarySource);
- LibraryElement element = builder.buildLibrary(library);
- GatheringErrorListener listener = new GatheringErrorListener();
- listener.addAll2(resolver.errorListener);
- listener.assertErrorsWithCodes(expectedErrorCodes);
- return element;
- }
-}
-
-@reflectiveTest
class LibraryImportScopeTest extends ResolverTestCase {
void test_conflictingImports() {
AnalysisContext context = AnalysisContextFactory.contextWithCore();
@@ -6457,104 +6264,6 @@
}
@reflectiveTest
-class LibraryResolver2Test extends ResolverTestCase {
- LibraryResolver2 _resolver;
-
- Source _coreLibrarySource;
-
- Source _asyncLibrarySource;
-
- @override
- void setUp() {
- super.setUp();
- _resolver = new LibraryResolver2(analysisContext2);
- _coreLibrarySource =
- analysisContext2.sourceFactory.forUri(DartSdk.DART_CORE);
- _asyncLibrarySource =
- analysisContext2.sourceFactory.forUri(DartSdk.DART_ASYNC);
- }
-
- void test_imports_relative() {
- Source sourceA = addSource(r'''
-library libA;
-import 'libB.dart';
-class A {}''');
- Source sourceB = addNamedSource(
- "/libB.dart",
- r'''
-library libB;
-import 'test.dart
-class B {}''');
- List<ResolvableLibrary> cycle = new List<ResolvableLibrary>();
- ResolvableLibrary coreLib = _createResolvableLibrary(_coreLibrarySource);
- coreLib.libraryElement = analysisContext2
- .computeLibraryElement(_coreLibrarySource) as LibraryElementImpl;
- ResolvableLibrary asyncLib = _createResolvableLibrary(_asyncLibrarySource);
- asyncLib.libraryElement = analysisContext2
- .computeLibraryElement(_asyncLibrarySource) as LibraryElementImpl;
- ResolvableLibrary libA = _createResolvableLibrary(sourceA);
- ResolvableLibrary libB = _createResolvableLibrary(sourceB);
- libA.importedLibraries = <ResolvableLibrary>[coreLib, asyncLib, libB];
- libB.importedLibraries = <ResolvableLibrary>[coreLib, asyncLib, libA];
- cycle.add(libA);
- cycle.add(libB);
- LibraryElement library = _resolver.resolveLibrary(sourceA, cycle);
- List<LibraryElement> importedLibraries = library.importedLibraries;
- assertNamedElements(importedLibraries, ["dart.core", "libB"]);
- }
-
- ResolvableLibrary _createResolvableLibrary(Source source) {
- CompilationUnit unit = analysisContext2.parseCompilationUnit(source);
- ResolvableLibrary resolvableLibrary = new ResolvableLibrary(source);
- resolvableLibrary.resolvableCompilationUnits = <ResolvableCompilationUnit>[
- new ResolvableCompilationUnit(source, unit)
- ];
- return resolvableLibrary;
- }
-}
-
-@reflectiveTest
-class LibraryResolverTest extends ResolverTestCase {
- LibraryResolver _resolver;
-
- @override
- void setUp() {
- super.setUp();
- _resolver = new LibraryResolver(analysisContext2);
- }
-
- void test_imports_dart_html() {
- Source source = addSource(r'''
-library libA;
-import 'dart:html';
-class A {}''');
- LibraryElement library = _resolver.resolveLibrary(source, true);
- List<LibraryElement> importedLibraries = library.importedLibraries;
- assertNamedElements(importedLibraries, ["dart.core", "dart.dom.html"]);
- }
-
- void test_imports_none() {
- Source source = addSource(r'''
-library libA;
-class A {}''');
- LibraryElement library = _resolver.resolveLibrary(source, true);
- List<LibraryElement> importedLibraries = library.importedLibraries;
- assertNamedElements(importedLibraries, ["dart.core"]);
- }
-
- void test_imports_relative() {
- addNamedSource("/libB.dart", "library libB;");
- Source source = addSource(r'''
-library libA;
-import 'libB.dart';
-class A {}''');
- LibraryElement library = _resolver.resolveLibrary(source, true);
- List<LibraryElement> importedLibraries = library.importedLibraries;
- assertNamedElements(importedLibraries, ["dart.core", "libB"]);
- }
-}
-
-@reflectiveTest
class LibraryScopeTest extends ResolverTestCase {
void test_creation_empty() {
LibraryElement definingLibrary = createDefaultTestLibrary();
@@ -6591,112 +6300,6 @@
}
@reflectiveTest
-class LibraryTest extends EngineTestCase {
- /**
- * The error listener to which all errors will be reported.
- */
- GatheringErrorListener _errorListener;
-
- /**
- * The analysis context to pass in to all libraries created by the tests.
- */
- InternalAnalysisContext _analysisContext;
-
- /**
- * The library used by the tests.
- */
- Library _library;
-
- @override
- void setUp() {
- _analysisContext = AnalysisContextFactory.contextWithCore();
- _errorListener = new GatheringErrorListener();
- _library = _createLibrary("/lib.dart");
- }
-
- @override
- void tearDown() {
- _errorListener = null;
- _analysisContext = null;
- _library = null;
- super.tearDown();
- }
-
- void test_getExplicitlyImportsCore() {
- expect(_library.explicitlyImportsCore, isFalse);
- _errorListener.assertNoErrors();
- }
-
- void test_getExports() {
- expect(_library.exports, hasLength(0));
- _errorListener.assertNoErrors();
- }
-
- void test_getImports() {
- expect(_library.imports, hasLength(0));
- _errorListener.assertNoErrors();
- }
-
- void test_getImportsAndExports() {
- _library.importedLibraries = <Library>[_createLibrary("/imported.dart")];
- _library.exportedLibraries = <Library>[_createLibrary("/exported.dart")];
- expect(_library.importsAndExports, hasLength(2));
- _errorListener.assertNoErrors();
- }
-
- void test_getLibraryScope() {
- LibraryElementImpl element = new LibraryElementImpl.forNode(
- _analysisContext, AstFactory.libraryIdentifier2(["lib"]));
- element.definingCompilationUnit =
- new CompilationUnitElementImpl("lib.dart");
- _library.libraryElement = element;
- expect(_library.libraryScope, isNotNull);
- _errorListener.assertNoErrors();
- }
-
- void test_getLibrarySource() {
- expect(_library.librarySource, isNotNull);
- }
-
- void test_setExplicitlyImportsCore() {
- _library.explicitlyImportsCore = true;
- expect(_library.explicitlyImportsCore, isTrue);
- _errorListener.assertNoErrors();
- }
-
- void test_setExportedLibraries() {
- Library exportLibrary = _createLibrary("/exported.dart");
- _library.exportedLibraries = <Library>[exportLibrary];
- List<Library> exports = _library.exports;
- expect(exports, hasLength(1));
- expect(exports[0], same(exportLibrary));
- _errorListener.assertNoErrors();
- }
-
- void test_setImportedLibraries() {
- Library importLibrary = _createLibrary("/imported.dart");
- _library.importedLibraries = <Library>[importLibrary];
- List<Library> imports = _library.imports;
- expect(imports, hasLength(1));
- expect(imports[0], same(importLibrary));
- _errorListener.assertNoErrors();
- }
-
- void test_setLibraryElement() {
- LibraryElementImpl element = new LibraryElementImpl.forNode(
- _analysisContext, AstFactory.libraryIdentifier2(["lib"]));
- _library.libraryElement = element;
- expect(_library.libraryElement, same(element));
- }
-
- Library _createLibrary(String definingCompilationUnitPath) => new Library(
- _analysisContext,
- _errorListener,
- new FileBasedSource(
- FileUtilities2.createFile(definingCompilationUnitPath)));
-}
-
-@reflectiveTest
class MemberMapTest {
/**
* The null type.
@@ -6742,61 +6345,6 @@
}
}
-/**
- * An analysis context that has a fake SDK that is much smaller and faster for
- * testing purposes.
- */
-class NewAnalysisContextForTests extends newContext.AnalysisContextImpl {
- @override
- void set analysisOptions(AnalysisOptions options) {
- AnalysisOptions currentOptions = analysisOptions;
- bool needsRecompute = currentOptions.analyzeFunctionBodiesPredicate !=
- options.analyzeFunctionBodiesPredicate ||
- currentOptions.generateImplicitErrors !=
- options.generateImplicitErrors ||
- currentOptions.generateSdkErrors != options.generateSdkErrors ||
- currentOptions.dart2jsHint != options.dart2jsHint ||
- (currentOptions.hint && !options.hint) ||
- currentOptions.preserveComments != options.preserveComments ||
- currentOptions.enableStrictCallChecks != options.enableStrictCallChecks;
- if (needsRecompute) {
- fail(
- "Cannot set options that cause the sources to be reanalyzed in a test context");
- }
- super.analysisOptions = options;
- }
-
- @override
- bool exists(Source source) =>
- super.exists(source) || sourceFactory.dartSdk.context.exists(source);
-
- @override
- TimestampedData<String> getContents(Source source) {
- if (source.isInSystemLibrary) {
- return sourceFactory.dartSdk.context.getContents(source);
- }
- return super.getContents(source);
- }
-
- @override
- int getModificationStamp(Source source) {
- if (source.isInSystemLibrary) {
- return sourceFactory.dartSdk.context.getModificationStamp(source);
- }
- return super.getModificationStamp(source);
- }
-
- /**
- * Set the analysis options, even if they would force re-analysis. This method should only be
- * invoked before the fake SDK is initialized.
- *
- * @param options the analysis options to be set
- */
- void _internalSetAnalysisOptions(AnalysisOptions options) {
- super.analysisOptions = options;
- }
-}
-
@reflectiveTest
class NonHintCodeTest extends ResolverTestCase {
void test_deadCode_deadBlock_conditionalElse_debugConst() {
@@ -7581,6 +7129,67 @@
verify([source]);
}
+ void test_unnecessaryNoSuchMethod_blockBody_notReturnStatement() {
+ Source source = addSource(r'''
+class A {
+ noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+ mmm();
+ noSuchMethod(y) {
+ print(y);
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unnecessaryNoSuchMethod_blockBody_notSingleStatement() {
+ Source source = addSource(r'''
+class A {
+ noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+ mmm();
+ noSuchMethod(y) {
+ print(y);
+ return super.noSuchMethod(y);
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unnecessaryNoSuchMethod_expressionBody_notNoSuchMethod() {
+ Source source = addSource(r'''
+class A {
+ noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+ mmm();
+ noSuchMethod(y) => super.hashCode;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unnecessaryNoSuchMethod_expressionBody_notSuper() {
+ Source source = addSource(r'''
+class A {
+ noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+ mmm();
+ noSuchMethod(y) => 42;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
void test_unusedImport_annotationOnDirective() {
Source source = addSource(r'''
library L;
@@ -8427,6 +8036,7 @@
@override
void setUp() {
+ super.setUp();
reset();
}
@@ -9724,7 +9334,9 @@
expect(declarations, hasLength(2));
Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
.variables
- .variables[0].name.staticElement;
+ .variables[0]
+ .name
+ .staticElement;
EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
PropertyInducingElement, expectedElement);
expectedElement = (expectedElement as PropertyInducingElement).getter;
@@ -9915,7 +9527,9 @@
expect(declarations, hasLength(2));
Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
.variables
- .variables[0].name.staticElement;
+ .variables[0]
+ .name
+ .staticElement;
EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
PropertyInducingElement, expectedElement);
expectedElement = (expectedElement as PropertyInducingElement).getter;
@@ -10363,6 +9977,7 @@
@override
void setUp() {
+ super.setUp();
_listener = new GatheringErrorListener();
_typeProvider = new TestTypeProvider();
_analyzer = _createAnalyzer();
@@ -11630,12 +11245,9 @@
LibraryElementImpl definingLibrary =
new LibraryElementImpl.forNode(context, null);
definingLibrary.definingCompilationUnit = definingCompilationUnit;
- Library library = new Library(context, _listener, source);
- library.libraryElement = definingLibrary;
_visitor = new ResolverVisitor(
- library.libraryElement, source, _typeProvider, library.errorListener,
- nameScope: library.libraryScope,
- inheritanceManager: library.inheritanceManager);
+ definingLibrary, source, _typeProvider, _listener,
+ nameScope: new LibraryScope(definingLibrary, _listener));
_visitor.overrideManager.enterScope();
try {
return _visitor.typeAnalyzer;
@@ -12140,17 +11752,17 @@
TypeAssertions _assertions;
AsserterBuilder<Element, DartType> _hasElement;
AsserterBuilder<DartType, DartType> _isType;
- AsserterBuilder2<Asserter<DartType>, Asserter<DartType>,
- DartType> _isFunction2Of;
- AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>,
- DartType> _isInstantiationOf;
+ AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, DartType>
+ _isFunction2Of;
+ AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>, DartType>
+ _isInstantiationOf;
Asserter<DartType> _isInt;
Asserter<DartType> _isNum;
Asserter<DartType> _isString;
Asserter<DartType> _isDynamic;
AsserterBuilder<Asserter<DartType>, InterfaceType> _isListOf;
- AsserterBuilder2<Asserter<DartType>, Asserter<DartType>,
- InterfaceType> _isMapOf;
+ AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, InterfaceType>
+ _isMapOf;
@override
void setUp() {
@@ -12594,7 +12206,7 @@
List<int> l0 = [];
}
''');
- LibraryElement library = resolve2(source);
+ resolve2(source);
assertNoErrors(source);
verify([source]);
}
@@ -13153,9 +12765,6 @@
}
void test_genericFunction() {
- if (!AnalysisEngine.instance.useTaskModel) {
- return;
- }
_resolveTestUnit(r'/*=T*/ f/*<T>*/(/*=T*/ x) => null;');
SimpleIdentifier f = _findIdentifier('f');
FunctionElementImpl e = f.staticElement;
@@ -13168,10 +12777,113 @@
expect(ft.toString(), '(String) → String');
}
- void test_genericMethod() {
- if (!AnalysisEngine.instance.useTaskModel) {
- return;
+ void test_genericFunction_bounds() {
+ _resolveTestUnit(r'/*=T*/ f/*<T extends num>*/(/*=T*/ x) => null;');
+ SimpleIdentifier f = _findIdentifier('f');
+ FunctionElementImpl e = f.staticElement;
+ expect(e.typeParameters.toString(), '[T extends num]');
+ expect(e.type.boundTypeParameters.toString(), '[T extends num]');
+ expect(e.type.typeParameters.toString(), '[]');
+ expect(e.type.toString(), '<T extends num>(T) → T');
+ }
+
+ void test_genericFunction_static() {
+ _resolveTestUnit(r'''
+class C<E> {
+ static /*=T*/ f/*<T>*/(/*=T*/ x) => null;
+}
+''');
+ SimpleIdentifier f = _findIdentifier('f');
+ MethodElementImpl e = f.staticElement;
+ expect(e.typeParameters.toString(), '[T]');
+ expect(e.type.boundTypeParameters.toString(), '[T]');
+ // TODO(jmesserly): we could get rid of this {E/E} substitution, but it's
+ // probably harmless, as E won't be used in the function (error verifier
+ // checks this), and {E/E} is a no-op anyway.
+ expect(e.type.typeParameters.toString(), '[E]');
+ expect(e.type.typeArguments.toString(), '[E]');
+ expect(e.type.toString(), '<T>(T) → T');
+
+ FunctionType ft = e.type.instantiate([typeProvider.stringType]);
+ expect(ft.toString(), '(String) → String');
+ }
+
+ void test_genericFunction_typedef() {
+ String code = r'''
+typedef T F<T>(T x);
+F f0;
+
+class C {
+ static F f1;
+ F f2;
+ void g(F f3) {
+ F f4;
+ f0(3);
+ f1(3);
+ f2(3);
+ f3(3);
+ f4(3);
+ }
+}
+
+class D<S> {
+ static F f1;
+ F f2;
+ void g(F f3) {
+ F f4;
+ f0(3);
+ f1(3);
+ f2(3);
+ f3(3);
+ f4(3);
+ }
+}
+''';
+ _resolveTestUnit(code);
+
+ {
+ List<Statement> statements =
+ AstFinder.getStatementsInMethod(testUnit, "C", "g");
+
+ ExpressionStatement exps0 = statements[1];
+ ExpressionStatement exps1 = statements[2];
+ ExpressionStatement exps2 = statements[3];
+ ExpressionStatement exps3 = statements[4];
+ ExpressionStatement exps4 = statements[5];
+ Expression exp0 = exps0.expression;
+ Expression exp1 = exps1.expression;
+ Expression exp2 = exps2.expression;
+ Expression exp3 = exps3.expression;
+ Expression exp4 = exps4.expression;
+ expect(exp0.staticType, typeProvider.dynamicType);
+ expect(exp1.staticType, typeProvider.dynamicType);
+ expect(exp2.staticType, typeProvider.dynamicType);
+ expect(exp3.staticType, typeProvider.dynamicType);
+ expect(exp4.staticType, typeProvider.dynamicType);
}
+ {
+ List<Statement> statements =
+ AstFinder.getStatementsInMethod(testUnit, "D", "g");
+
+ ExpressionStatement exps0 = statements[1];
+ ExpressionStatement exps1 = statements[2];
+ ExpressionStatement exps2 = statements[3];
+ ExpressionStatement exps3 = statements[4];
+ ExpressionStatement exps4 = statements[5];
+ Expression exp0 = exps0.expression;
+ Expression exp1 = exps1.expression;
+ Expression exp2 = exps2.expression;
+ Expression exp3 = exps3.expression;
+ Expression exp4 = exps4.expression;
+ expect(exp0.staticType, typeProvider.dynamicType);
+ expect(exp1.staticType, typeProvider.dynamicType);
+ expect(exp2.staticType, typeProvider.dynamicType);
+ expect(exp3.staticType, typeProvider.dynamicType);
+ expect(exp4.staticType, typeProvider.dynamicType);
+ }
+ }
+
+ void test_genericMethod() {
_resolveTestUnit(r'''
class C<E> {
List/*<T>*/ f/*<T>*/(E e) => null;
@@ -13196,10 +12908,27 @@
expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
}
+ void test_genericMethod_explicitTypeParams() {
+ _resolveTestUnit(r'''
+class C<E> {
+ List/*<T>*/ f/*<T>*/(E e) => null;
+}
+main() {
+ C<String> cOfString;
+ var x = cOfString.f/*<int>*/('hi');
+}
+''');
+ SimpleIdentifier f = _findIdentifier('f/*<int>*/');
+ FunctionType ft = f.staticType;
+ expect(ft.toString(), '(String) → List<int>');
+ expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
+
+ SimpleIdentifier x = _findIdentifier('x');
+ expect(x.staticType,
+ typeProvider.listType.substitute4([typeProvider.intType]));
+ }
+
void test_genericMethod_functionTypedParameter() {
- if (!AnalysisEngine.instance.useTaskModel) {
- return;
- }
_resolveTestUnit(r'''
class C<E> {
List/*<T>*/ f/*<T>*/(/*=T*/ f(E e)) => null;
@@ -13223,6 +12952,28 @@
expect(ft.toString(), '((String) → int) → List<int>');
}
+ void test_genericMethod_implicitDynamic() {
+ // Regression test for:
+ // https://github.com/dart-lang/sdk/issues/25100#issuecomment-162047588
+ // These should not cause any hints or warnings.
+ _resolveTestUnit(r'''
+class List<E> {
+ /*=T*/ map/*<T>*/(/*=T*/ f(E e)) => null;
+}
+void foo() {
+ List list = null;
+ list.map((e) => e);
+ list.map((e) => 3);
+}''');
+
+ SimpleIdentifier map1 = _findIdentifier('map((e) => e);');
+ expect(map1.staticType.toString(), '((dynamic) → dynamic) → dynamic');
+ expect(map1.propagatedType, isNull);
+ SimpleIdentifier map2 = _findIdentifier('map((e) => 3);');
+ expect(map2.staticType.toString(), '((dynamic) → int) → int');
+ expect(map2.propagatedType, isNull);
+ }
+
void test_genericMethod_nestedCapture() {
_resolveTestUnit(r'''
class C<T> {
@@ -13255,6 +13006,98 @@
expect(f.staticType.toString(), '<S>(S) → dynamic');
}
+ void test_genericMethod_override() {
+ _resolveTestUnit(r'''
+class C {
+ /*=T*/ f/*<T>*/(/*=T*/ x) => null;
+}
+class D extends C {
+ /*=T*/ f/*<T>*/(/*=T*/ x) => null; // from D
+}
+''');
+ SimpleIdentifier f =
+ _findIdentifier('f/*<T>*/(/*=T*/ x) => null; // from D');
+ MethodElementImpl e = f.staticElement;
+ expect(e.typeParameters.toString(), '[T]');
+ expect(e.type.boundTypeParameters.toString(), '[T]');
+ expect(e.type.toString(), '<T>(T) → T');
+
+ FunctionType ft = e.type.instantiate([typeProvider.stringType]);
+ expect(ft.toString(), '(String) → String');
+ }
+
+ void test_genericMethod_override_bounds() {
+ _resolveTestUnit(r'''
+class A {}
+class B extends A {}
+class C {
+ /*=T*/ f/*<T extends B>*/(/*=T*/ x) => null;
+}
+class D extends C {
+ /*=T*/ f/*<T extends A>*/(/*=T*/ x) => null;
+}
+''');
+ }
+
+ void test_genericMethod_override_invalidReturnType() {
+ Source source = addSource(r'''
+class C {
+ Iterable/*<T>*/ f/*<T>*/(/*=T*/ x) => null;
+}
+class D extends C {
+ String f/*<S>*/(/*=S*/ x) => null;
+}''');
+ // TODO(jmesserly): we can't use assertErrors because STRONG_MODE_* errors
+ // from CodeChecker don't have working equality.
+ List<AnalysisError> errors = analysisContext2.computeErrors(source);
+ expect(errors.map((e) => e.errorCode.name), [
+ 'INVALID_METHOD_OVERRIDE_RETURN_TYPE',
+ 'STRONG_MODE_INVALID_METHOD_OVERRIDE'
+ ]);
+ expect(errors[0].message, contains('Iterable<S>'),
+ reason: 'errors should be in terms of the type parameters '
+ 'at the error location');
+ verify([source]);
+ }
+
+ void test_genericMethod_override_invalidTypeParamBounds() {
+ Source source = addSource(r'''
+class A {}
+class B extends A {}
+class C {
+ /*=T*/ f/*<T extends A>*/(/*=T*/ x) => null;
+}
+class D extends C {
+ /*=T*/ f/*<T extends B>*/(/*=T*/ x) => null;
+}''');
+ // TODO(jmesserly): this is modified code from assertErrors, which we can't
+ // use directly because STRONG_MODE_* errors don't have working equality.
+ List<AnalysisError> errors = analysisContext2.computeErrors(source);
+ expect(errors.map((e) => e.errorCode.name), [
+ 'STRONG_MODE_INVALID_METHOD_OVERRIDE',
+ 'INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND'
+ ]);
+ verify([source]);
+ }
+
+ void test_genericMethod_override_invalidTypeParamCount() {
+ Source source = addSource(r'''
+class C {
+ /*=T*/ f/*<T>*/(/*=T*/ x) => null;
+}
+class D extends C {
+ /*=S*/ f/*<T, S>*/(/*=T*/ x) => null;
+}''');
+ // TODO(jmesserly): we can't use assertErrors because STRONG_MODE_* errors
+ // from CodeChecker don't have working equality.
+ List<AnalysisError> errors = analysisContext2.computeErrors(source);
+ expect(errors.map((e) => e.errorCode.name), [
+ 'STRONG_MODE_INVALID_METHOD_OVERRIDE',
+ 'INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS'
+ ]);
+ verify([source]);
+ }
+
void test_pseudoGeneric_max_doubleDouble() {
String code = r'''
import 'dart:math';
@@ -13525,9 +13368,6 @@
}
void test_localVariableInference_transitive_field_inferred_lexical() {
- if (!AnalysisEngine.instance.useTaskModel) {
- return;
- }
String code = r'''
class A {
final x = 3;
@@ -13544,9 +13384,6 @@
}
void test_localVariableInference_transitive_field_inferred_reversed() {
- if (!AnalysisEngine.instance.useTaskModel) {
- return;
- }
String code = r'''
class A {
f() {
@@ -13617,9 +13454,6 @@
}
void test_localVariableInference_transitive_toplevel_inferred_lexical() {
- if (!AnalysisEngine.instance.useTaskModel) {
- return;
- }
String code = r'''
final x = 3;
main() {
@@ -13632,9 +13466,6 @@
}
void test_localVariableInference_transitive_toplevel_inferred_reversed() {
- if (!AnalysisEngine.instance.useTaskModel) {
- return;
- }
String code = r'''
main() {
var v = x;
@@ -13672,7 +13503,7 @@
}
@reflectiveTest
-class SubtypeManagerTest extends EngineTestCase {
+class SubtypeManagerTest {
/**
* The inheritance manager being tested.
*/
@@ -13683,9 +13514,7 @@
*/
CompilationUnitElementImpl _definingCompilationUnit;
- @override
void setUp() {
- super.setUp();
AnalysisContext context = AnalysisContextFactory.contextWithCore();
FileBasedSource source =
new FileBasedSource(FileUtilities2.createFile("/test.dart"));
@@ -14131,8 +13960,6 @@
}
void test_finalPropertyInducingVariable_classMember_instance() {
- // TODO(scheglov) remove after switching to the task model
- if (!AnalysisEngine.instance.useTaskModel) return;
addNamedSource(
"/lib.dart",
r'''
@@ -14149,8 +13976,6 @@
}
void test_finalPropertyInducingVariable_classMember_instance_inherited() {
- // TODO(scheglov) remove after switching to the task model
- if (!AnalysisEngine.instance.useTaskModel) return;
addNamedSource(
"/lib.dart",
r'''
@@ -14168,9 +13993,8 @@
code, typeProvider.dynamicType, typeProvider.intType);
}
- void test_finalPropertyInducingVariable_classMember_instance_propagatedTarget() {
- // TODO(scheglov) remove after switching to the task model
- if (!AnalysisEngine.instance.useTaskModel) return;
+ void
+ test_finalPropertyInducingVariable_classMember_instance_propagatedTarget() {
addNamedSource(
"/lib.dart",
r'''
@@ -14189,8 +14013,6 @@
}
void test_finalPropertyInducingVariable_classMember_instance_unprefixed() {
- // TODO(scheglov) remove after switching to the task model
- if (!AnalysisEngine.instance.useTaskModel) return;
String code = r'''
class A {
final v = 0;
@@ -14203,8 +14025,6 @@
}
void test_finalPropertyInducingVariable_classMember_static() {
- // TODO(scheglov) remove after switching to the task model
- if (!AnalysisEngine.instance.useTaskModel) return;
addNamedSource(
"/lib.dart",
r'''
@@ -14221,8 +14041,6 @@
}
void test_finalPropertyInducingVariable_topLevelVariable_prefixed() {
- // TODO(scheglov) remove after switching to the task model
- if (!AnalysisEngine.instance.useTaskModel) return;
addNamedSource("/lib.dart", "final V = 0;");
String code = r'''
import 'lib.dart' as p;
@@ -14234,8 +14052,6 @@
}
void test_finalPropertyInducingVariable_topLevelVariable_simple() {
- // TODO(scheglov) remove after switching to the task model
- if (!AnalysisEngine.instance.useTaskModel) return;
addNamedSource("/lib.dart", "final V = 0;");
String code = r'''
import 'lib.dart';
@@ -14397,7 +14213,8 @@
expect(vParameter.identifier.propagatedType, same(stringType));
}
- void test_functionExpression_asInvocationArgument_functionExpressionInvocation() {
+ void
+ test_functionExpression_asInvocationArgument_functionExpressionInvocation() {
String code = r'''
main() {
(f(String value)) {} ((v) {
@@ -15571,24 +15388,23 @@
}
@reflectiveTest
-class TypeResolverVisitorTest extends EngineTestCase {
+class TypeResolverVisitorTest {
/**
* The error listener to which errors will be reported.
*/
GatheringErrorListener _listener;
/**
- * The object representing the information about the library in which the types are being
- * resolved.
- */
- Library _library;
-
- /**
* The type provider used to access the types.
*/
TestTypeProvider _typeProvider;
/**
+ * The library scope in which types are to be resolved.
+ */
+ LibraryScope libraryScope;
+
+ /**
* The visitor used to resolve types needed to form the type hierarchy.
*/
TypeResolverVisitor _visitor;
@@ -15613,22 +15429,20 @@
_listener.assertNoErrors();
}
- @override
void setUp() {
_listener = new GatheringErrorListener();
InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
Source librarySource =
new FileBasedSource(FileUtilities2.createFile("/lib.dart"));
- _library = new Library(context, _listener, librarySource);
LibraryElementImpl element = new LibraryElementImpl.forNode(
context, AstFactory.libraryIdentifier2(["lib"]));
element.definingCompilationUnit =
new CompilationUnitElementImpl("lib.dart");
- _library.libraryElement = element;
_typeProvider = new TestTypeProvider();
- _visitor = new TypeResolverVisitor(_library.libraryElement, librarySource,
- _typeProvider, _library.errorListener,
- nameScope: _library.libraryScope);
+ libraryScope = new LibraryScope(element, _listener);
+ _visitor = new TypeResolverVisitor(
+ element, librarySource, _typeProvider, _listener,
+ nameScope: libraryScope);
}
void test_visitCatchClause_exception() {
@@ -16188,7 +16002,7 @@
void _resolveNode(AstNode node, [List<Element> definedElements]) {
if (definedElements != null) {
for (Element element in definedElements) {
- _library.libraryScope.define(element);
+ libraryScope.define(element);
}
}
node.accept(_visitor);
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index a0c7355..d0d8949 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.scanner_test;
+library analyzer.test.generated.scanner_test;
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/scanner.dart';
diff --git a/pkg/analyzer/test/generated/source_factory_test.dart b/pkg/analyzer/test/generated/source_factory_test.dart
index c16f1f8..e9dfd94 100644
--- a/pkg/analyzer/test/generated/source_factory_test.dart
+++ b/pkg/analyzer/test/generated/source_factory_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.generated.source_factory;
+library analyzer.test.generated.test.generated.source_factory;
import 'dart:convert';
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index d98f837..2c1e2d2 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.static_type_warning_code_test;
+library analyzer.test.generated.static_type_warning_code_test;
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
@@ -58,6 +58,30 @@
assertErrors(source, [StaticWarningCode.AMBIGUOUS_IMPORT]);
}
+ void test_assert_message_suppresses_type_promotion() {
+ // If a variable is assigned to inside the expression for an assert
+ // message, type promotion should be suppressed, just as it would be if the
+ // assignment occurred outside an assert statement. (Note that it is a
+ // dubious practice for the computation of an assert message to have side
+ // effects, since it is only evaluated if the assert fails).
+ resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+ Source source = addSource('''
+class C {
+ void foo() {}
+}
+
+f(Object x) {
+ if (x is C) {
+ x.foo();
+ assert(true, () { x = new C(); return 'msg'; }());
+ }
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
+ // Do not verify since `x.foo()` fails to resolve.
+ }
+
void test_await_flattened() {
Source source = addSource('''
import 'dart:async';
@@ -1098,7 +1122,8 @@
verify([source]);
}
- void test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_mutated() {
+ void
+ test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_mutated() {
Source source = addSource(r'''
callMe(f()) { f(); }
main(Object p) {
@@ -1127,7 +1152,8 @@
assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
}
- void test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_after() {
+ void
+ test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_after() {
Source source = addSource(r'''
callMe(f()) { f(); }
main(Object p) {
@@ -1138,7 +1164,8 @@
assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
}
- void test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_before() {
+ void
+ test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_before() {
Source source = addSource(r'''
callMe(f()) { f(); }
main(Object p) {
@@ -1418,6 +1445,18 @@
assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
}
+ void test_undefinedGetter_typeLiteral_cascadeTarget() {
+ Source source = addSource(r'''
+class T {
+ static int get foo => 42;
+}
+main() {
+ T..foo;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
+ }
+
void test_undefinedGetter_typeLiteral_conditionalAccess() {
// When applied to a type literal, the conditional access operator '?.'
// cannot be used to access instance getters of Type.
@@ -1589,6 +1628,19 @@
assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
}
+ void test_undefinedMethod_typeLiteral_cascadeTarget() {
+ Source source = addSource('''
+class T {
+ static void foo() {}
+}
+main() {
+ T..foo();
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
+ }
+
void test_undefinedMethod_typeLiteral_conditionalAccess() {
// When applied to a type literal, the conditional access operator '?.'
// cannot be used to access instance methods of Type.
@@ -1689,6 +1741,18 @@
assertErrors(source, [StaticTypeWarningCode.UNDEFINED_SETTER]);
}
+ void test_undefinedSetter_typeLiteral_cascadeTarget() {
+ Source source = addSource(r'''
+class T {
+ static void set foo(_) {}
+}
+main() {
+ T..foo = 42;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_SETTER]);
+ }
+
void test_undefinedSetter_void() {
Source source = addSource(r'''
class T {
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index f48528e..eb6aa8b 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.static_warning_code_test;
+library analyzer.test.generated.static_warning_code_test;
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/source_io.dart';
diff --git a/pkg/analyzer/test/generated/test_all.dart b/pkg/analyzer/test/generated/test_all.dart
index 0a9a727..48bbfb2 100644
--- a/pkg/analyzer/test/generated/test_all.dart
+++ b/pkg/analyzer/test/generated/test_all.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.generated;
+library analyzer.test.generated.test_all;
import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 20cc0e2..b3e9215 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.test_support;
+library analyzer.test.generated.test_support;
import 'dart:collection';
@@ -13,6 +13,8 @@
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
import 'package:unittest/unittest.dart';
import 'resolver_test.dart';
@@ -91,7 +93,13 @@
return null;
}
- void setUp() {}
+ void setUp() {
+ List<Plugin> plugins = <Plugin>[];
+ plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+ plugins.add(AnalysisEngine.instance.commandLinePlugin);
+ plugins.add(AnalysisEngine.instance.optionsPlugin);
+ new ExtensionManager().processPlugins(plugins);
+ }
void tearDown() {}
@@ -530,19 +538,9 @@
}
@override
- void logError2(String message, Object exception) {
- errorCount++;
- }
-
- @override
void logInformation(String message, [CaughtException exception]) {
infoCount++;
}
-
- @override
- void logInformation2(String message, Object exception) {
- infoCount++;
- }
}
class TestSource extends Source {
@@ -557,10 +555,6 @@
*/
bool generateExceptionOnRead = false;
- @override
- int get modificationStamp =>
- generateExceptionOnRead ? -1 : _modificationStamp;
-
/**
* The number of times that the contents of this source have been requested.
*/
@@ -586,10 +580,15 @@
}
int get hashCode => 0;
+
bool get isInSystemLibrary {
return false;
}
+ @override
+ int get modificationStamp =>
+ generateExceptionOnRead ? -1 : _modificationStamp;
+
String get shortName {
return _name;
}
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index e4501be..cd16dcf 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -4,7 +4,7 @@
// Tests related to the [TypeSystem] class.
-library engine.type_system_test;
+library analyzer.test.generated.type_system_test;
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -66,7 +66,8 @@
ElementFactory.methodElement("call", objectType, <DartType>[intType]);
classBottom.methods = <MethodElement>[methodBottom];
- DartType top = TypeBuilder.functionType(<DartType>[intType], objectType);
+ DartType top =
+ TypeBuilder.function(required: <DartType>[intType], result: objectType);
InterfaceType bottom = classBottom.type;
_checkIsStrictAssignableTo(bottom, top);
@@ -117,14 +118,14 @@
}
void test_isAssignableTo_fuzzy_arrows() {
- FunctionType top =
- TypeBuilder.functionType(<DartType>[dynamicType], objectType);
- FunctionType left =
- TypeBuilder.functionType(<DartType>[objectType], objectType);
- FunctionType right =
- TypeBuilder.functionType(<DartType>[dynamicType], bottomType);
- FunctionType bottom =
- TypeBuilder.functionType(<DartType>[objectType], bottomType);
+ FunctionType top = TypeBuilder.function(
+ required: <DartType>[dynamicType], result: objectType);
+ FunctionType left = TypeBuilder.function(
+ required: <DartType>[objectType], result: objectType);
+ FunctionType right = TypeBuilder.function(
+ required: <DartType>[dynamicType], result: bottomType);
+ FunctionType bottom = TypeBuilder.function(
+ required: <DartType>[objectType], result: bottomType);
_checkCrossLattice(top, left, right, bottom);
}
@@ -166,23 +167,36 @@
}
void test_isAssignableTo_named_optional() {
- DartType r = TypeBuilder.functionType(<DartType>[intType], intType);
- DartType o = TypeBuilder.functionType(<DartType>[], intType,
- optional: <DartType>[intType]);
- DartType n = TypeBuilder.functionType(<DartType>[], intType,
- named: <String, DartType>{'x': intType});
- DartType rr =
- TypeBuilder.functionType(<DartType>[intType, intType], intType);
- DartType ro = TypeBuilder.functionType(<DartType>[intType], intType,
- optional: <DartType>[intType]);
- DartType rn = TypeBuilder.functionType(<DartType>[intType], intType,
- named: <String, DartType>{'x': intType});
- DartType oo = TypeBuilder.functionType(<DartType>[], intType,
- optional: <DartType>[intType, intType]);
- DartType nn = TypeBuilder.functionType(<DartType>[], intType,
- named: <String, DartType>{'x': intType, 'y': intType});
- DartType nnn = TypeBuilder.functionType(<DartType>[], intType,
- named: <String, DartType>{'x': intType, 'y': intType, 'z': intType});
+ DartType r =
+ TypeBuilder.function(required: <DartType>[intType], result: intType);
+ DartType o = TypeBuilder.function(
+ required: <DartType>[], optional: <DartType>[intType], result: intType);
+ DartType n = TypeBuilder.function(
+ required: <DartType>[],
+ named: <String, DartType>{'x': intType},
+ result: intType);
+ DartType rr = TypeBuilder.function(
+ required: <DartType>[intType, intType], result: intType);
+ DartType ro = TypeBuilder.function(
+ required: <DartType>[intType],
+ optional: <DartType>[intType],
+ result: intType);
+ DartType rn = TypeBuilder.function(
+ required: <DartType>[intType],
+ named: <String, DartType>{'x': intType},
+ result: intType);
+ DartType oo = TypeBuilder.function(
+ required: <DartType>[],
+ optional: <DartType>[intType, intType],
+ result: intType);
+ DartType nn = TypeBuilder.function(
+ required: <DartType>[],
+ named: <String, DartType>{'x': intType, 'y': intType},
+ result: intType);
+ DartType nnn = TypeBuilder.function(
+ required: <DartType>[],
+ named: <String, DartType>{'x': intType, 'y': intType, 'z': intType},
+ result: intType);
_checkGroups(r,
interassignable: [r, o, ro, rn, oo], unrelated: [n, rr, nn, nnn]);
@@ -220,20 +234,22 @@
void test_isAssignableTo_simple_function() {
FunctionType top =
- TypeBuilder.functionType(<DartType>[intType], objectType);
- FunctionType left = TypeBuilder.functionType(<DartType>[intType], intType);
- FunctionType right =
- TypeBuilder.functionType(<DartType>[objectType], objectType);
+ TypeBuilder.function(required: <DartType>[intType], result: objectType);
+ FunctionType left =
+ TypeBuilder.function(required: <DartType>[intType], result: intType);
+ FunctionType right = TypeBuilder.function(
+ required: <DartType>[objectType], result: objectType);
FunctionType bottom =
- TypeBuilder.functionType(<DartType>[objectType], intType);
+ TypeBuilder.function(required: <DartType>[objectType], result: intType);
_checkCrossLattice(top, left, right, bottom);
}
void test_isAssignableTo_void_functions() {
- FunctionType top = TypeBuilder.functionType(<DartType>[intType], voidType);
+ FunctionType top =
+ TypeBuilder.function(required: <DartType>[intType], result: voidType);
FunctionType bottom =
- TypeBuilder.functionType(<DartType>[objectType], intType);
+ TypeBuilder.function(required: <DartType>[objectType], result: intType);
_checkEquivalent(bottom, top);
}
@@ -320,9 +336,11 @@
void test_boundedByAnotherTypeParameter() {
// <TFrom, TTo extends Iterable<TFrom>>(TFrom) -> TTo
- var tFrom = _typeParameter('TFrom');
- var tTo = _typeParameter('TTo', iterableType.substitute4([tFrom]));
- var cast = _functionType([tFrom, tTo], [tFrom], tTo);
+ var tFrom = TypeBuilder.variable('TFrom');
+ var tTo =
+ TypeBuilder.variable('TTo', bound: iterableType.substitute4([tFrom]));
+ var cast = TypeBuilder.function(
+ types: [tFrom, tTo], required: [tFrom], result: tTo);
expect(_inferCall(cast, [stringType]), [
stringType,
iterableType.substitute4([stringType])
@@ -340,11 +358,11 @@
foo.supertype = clonable.type.substitute4([foo.type]);
// <S extends Clonable<S>>
- var s = _typeParameter('S');
+ var s = TypeBuilder.variable('S');
(s.element as TypeParameterElementImpl).bound =
clonable.type.substitute4([s]);
// (S, S) -> S
- var clone = _functionType([s], [s, s], s);
+ var clone = TypeBuilder.function(types: [s], required: [s, s], result: s);
expect(_inferCall(clone, [foo.type, foo.type]), [foo.type]);
// Something invalid...
@@ -355,141 +373,133 @@
void test_genericCastFunction() {
// <TFrom, TTo>(TFrom) -> TTo
- var tFrom = _typeParameter('TFrom');
- var tTo = _typeParameter('TTo');
- var cast = _functionType([tFrom, tTo], [tFrom], tTo);
+ var tFrom = TypeBuilder.variable('TFrom');
+ var tTo = TypeBuilder.variable('TTo');
+ var cast = TypeBuilder.function(
+ types: [tFrom, tTo], required: [tFrom], result: tTo);
expect(_inferCall(cast, [intType]), [intType, dynamicType]);
}
void test_genericCastFunctionWithUpperBound() {
// <TFrom, TTo extends TFrom>(TFrom) -> TTo
- var tFrom = _typeParameter('TFrom');
- var tTo = _typeParameter('TTo', tFrom);
- var cast = _functionType([tFrom, tTo], [tFrom], tTo);
+ var tFrom = TypeBuilder.variable('TFrom');
+ var tTo = TypeBuilder.variable('TTo', bound: tFrom);
+ var cast = TypeBuilder.function(
+ types: [tFrom, tTo], required: [tFrom], result: tTo);
expect(_inferCall(cast, [intType]), [intType, intType]);
}
void test_parametersToFunctionParam() {
// <T>(f(T t)) -> T
- var t = _typeParameter('T');
- var cast = _functionType([
+ var t = TypeBuilder.variable('T');
+ var cast = TypeBuilder.function(types: [
t
- ], [
- _functionType([], [t], dynamicType)
- ], t);
+ ], required: [
+ TypeBuilder.function(required: [t], result: dynamicType)
+ ], result: t);
expect(
_inferCall(cast, [
- _functionType([], [numType], dynamicType)
+ TypeBuilder.function(required: [numType], result: dynamicType)
]),
[numType]);
}
void test_parametersUseLeastUpperBound() {
// <T>(T x, T y) -> T
- var t = _typeParameter('T');
- var cast = _functionType([t], [t, t], t);
+ var t = TypeBuilder.variable('T');
+ var cast = TypeBuilder.function(types: [t], required: [t, t], result: t);
expect(_inferCall(cast, [intType, doubleType]), [numType]);
}
void test_parameterTypeUsesUpperBound() {
// <T extends num>(T) -> dynamic
- var t = _typeParameter('T', numType);
- var f = _functionType([t], [t], dynamicType);
+ var t = TypeBuilder.variable('T', bound: numType);
+ var f =
+ TypeBuilder.function(types: [t], required: [t], result: dynamicType);
expect(_inferCall(f, [intType]), [intType]);
}
void test_returnFunctionWithGenericParameter() {
// <T>(T -> T) -> (T -> void)
- var t = _typeParameter('T');
- var f = _functionType([
+ var t = TypeBuilder.variable('T');
+ var f = TypeBuilder.function(types: [
t
- ], [
- _functionType([], [t], t)
- ], _functionType([], [t], voidType));
+ ], required: [
+ TypeBuilder.function(required: [t], result: t)
+ ], result: TypeBuilder.function(required: [t], result: voidType));
expect(
_inferCall(f, [
- _functionType([], [numType], intType)
+ TypeBuilder.function(required: [numType], result: intType)
]),
[numType]);
}
void test_returnFunctionWithGenericParameterAndReturn() {
// <T>(T -> T) -> (T -> T)
- var t = _typeParameter('T');
- var f = _functionType([
+ var t = TypeBuilder.variable('T');
+ var f = TypeBuilder.function(types: [
t
- ], [
- _functionType([], [t], t)
- ], _functionType([], [t], t));
+ ], required: [
+ TypeBuilder.function(required: [t], result: t)
+ ], result: TypeBuilder.function(required: [t], result: t));
expect(
_inferCall(f, [
- _functionType([], [numType], intType)
+ TypeBuilder.function(required: [numType], result: intType)
]),
[numType]);
}
void test_returnFunctionWithGenericReturn() {
// <T>(T -> T) -> (() -> T)
- var t = _typeParameter('T');
- var f = _functionType([
+ var t = TypeBuilder.variable('T');
+ var f = TypeBuilder.function(types: [
t
- ], [
- _functionType([], [t], t)
- ], _functionType([], [], t));
+ ], required: [
+ TypeBuilder.function(required: [t], result: t)
+ ], result: TypeBuilder.function(required: [], result: t));
expect(
_inferCall(f, [
- _functionType([], [numType], intType)
+ TypeBuilder.function(required: [numType], result: intType)
]),
[intType]);
}
void test_unifyParametersToFunctionParam() {
// <T>(f(T t), g(T t)) -> T
- var t = _typeParameter('T');
- var cast = _functionType([
+ var t = TypeBuilder.variable('T');
+ var cast = TypeBuilder.function(types: [
t
- ], [
- _functionType([], [t], dynamicType),
- _functionType([], [t], dynamicType)
- ], t);
+ ], required: [
+ TypeBuilder.function(required: [t], result: dynamicType),
+ TypeBuilder.function(required: [t], result: dynamicType)
+ ], result: t);
expect(
_inferCall(cast, [
- _functionType([], [intType], dynamicType),
- _functionType([], [doubleType], dynamicType)
+ TypeBuilder.function(required: [intType], result: dynamicType),
+ TypeBuilder.function(required: [doubleType], result: dynamicType)
]),
[dynamicType]);
}
void test_unusedReturnTypeIsDynamic() {
// <T>() -> T
- var t = _typeParameter('T');
- var f = _functionType([t], [], t);
+ var t = TypeBuilder.variable('T');
+ var f = TypeBuilder.function(types: [t], required: [], result: t);
expect(_inferCall(f, []), [dynamicType]);
}
void test_unusedReturnTypeWithUpperBound() {
// <T extends num>() -> T
- var t = _typeParameter('T', numType);
- var f = _functionType([t], [], t);
+ var t = TypeBuilder.variable('T', bound: numType);
+ var f = TypeBuilder.function(types: [t], required: [], result: t);
expect(_inferCall(f, []), [numType]);
}
- FunctionTypeImpl _functionType(
- List<DartType> typeParams, List<DartType> params, DartType result) {
- FunctionElementImpl f = ElementFactory.functionElement8(params, result);
- f.typeParameters =
- new List<TypeParameterElement>.from(typeParams.map((t) => t.element));
- return f.type = new FunctionTypeImpl(f);
- }
-
List<DartType> _inferCall(FunctionTypeImpl ft, List<DartType> arguments) {
FunctionType inferred = typeSystem.inferCallFromArguments(
typeProvider, ft, ft.parameters.map((p) => p.type).toList(), arguments);
return inferred.typeArguments;
}
-
- TypeParameterType _typeParameter(String name, [DartType bound]) =>
- ElementFactory.typeParameterWithType(name, bound).type;
}
@reflectiveTest
@@ -513,7 +523,7 @@
typeSystem = new StrongTypeSystemImpl();
}
- void test_isSubtypeOf_bottom_isBottom() {
+ void test_bottom_isBottom() {
DartType interfaceType = ElementFactory.classElement2('A', []).type;
List<DartType> equivalents = <DartType>[bottomType];
List<DartType> supertypes = <DartType>[
@@ -529,19 +539,20 @@
_checkGroups(bottomType, equivalents: equivalents, supertypes: supertypes);
}
- void test_isSubtypeOf_call_method() {
+ void test_call_method() {
ClassElementImpl classBottom = ElementFactory.classElement2("Bottom");
MethodElement methodBottom =
ElementFactory.methodElement("call", objectType, <DartType>[intType]);
classBottom.methods = <MethodElement>[methodBottom];
- DartType top = TypeBuilder.functionType(<DartType>[intType], objectType);
+ DartType top =
+ TypeBuilder.function(required: <DartType>[intType], result: objectType);
InterfaceType bottom = classBottom.type;
_checkIsStrictSubtypeOf(bottom, top);
}
- void test_isSubtypeOf_classes() {
+ void test_classes() {
ClassElement classTop = ElementFactory.classElement2("A");
ClassElement classLeft = ElementFactory.classElement("B", classTop.type);
ClassElement classRight = ElementFactory.classElement("C", classTop.type);
@@ -555,7 +566,7 @@
_checkLattice(top, left, right, bottom);
}
- void test_isSubtypeOf_double() {
+ void test_double() {
List<DartType> equivalents = <DartType>[doubleType];
List<DartType> supertypes = <DartType>[numType];
List<DartType> unrelated = <DartType>[intType];
@@ -563,7 +574,7 @@
equivalents: equivalents, supertypes: supertypes, unrelated: unrelated);
}
- void test_isSubtypeOf_dynamic_isTop() {
+ void test_dynamic_isTop() {
DartType interfaceType = ElementFactory.classElement2('A', []).type;
List<DartType> equivalents = <DartType>[dynamicType, objectType];
List<DartType> subtypes = <DartType>[
@@ -578,20 +589,98 @@
_checkGroups(dynamicType, equivalents: equivalents, subtypes: subtypes);
}
- void test_isSubtypeOf_fuzzy_arrows() {
- FunctionType top =
- TypeBuilder.functionType(<DartType>[dynamicType], objectType);
- FunctionType left =
- TypeBuilder.functionType(<DartType>[objectType], objectType);
- FunctionType right =
- TypeBuilder.functionType(<DartType>[dynamicType], bottomType);
- FunctionType bottom =
- TypeBuilder.functionType(<DartType>[objectType], bottomType);
+ void test_fuzzy_arrows() {
+ FunctionType top = TypeBuilder.function(
+ required: <DartType>[dynamicType], result: objectType);
+ FunctionType left = TypeBuilder.function(
+ required: <DartType>[objectType], result: objectType);
+ FunctionType right = TypeBuilder.function(
+ required: <DartType>[dynamicType], result: bottomType);
+ FunctionType bottom = TypeBuilder.function(
+ required: <DartType>[objectType], result: bottomType);
_checkLattice(top, left, right, bottom);
}
- void test_isSubtypeOf_generics() {
+ void test_genericFunction_generic_monomorphic() {
+ DartType s = TypeBuilder.variable("S");
+ DartType t = TypeBuilder.variable("T", bound: s);
+ DartType u = TypeBuilder.variable("U", bound: intType);
+ DartType v = TypeBuilder.variable("V", bound: u);
+
+ _checkIsStrictSubtypeOf(
+ TypeBuilder.function(types: [s, t], required: [s], result: t),
+ TypeBuilder.function(required: [dynamicType], result: dynamicType));
+
+ _checkIsNotSubtypeOf(
+ TypeBuilder.function(types: [u, v], required: [u], result: v),
+ TypeBuilder.function(required: [objectType], result: objectType));
+
+ _checkIsStrictSubtypeOf(
+ TypeBuilder.function(types: [u, v], required: [u], result: v),
+ TypeBuilder.function(required: [intType], result: intType));
+ }
+
+ void test_genericFunction_simple() {
+ DartType s = TypeBuilder.variable("S");
+ DartType t = TypeBuilder.variable("T");
+
+ _checkEquivalent(
+ TypeBuilder.function(types: [t]), TypeBuilder.function(types: [s]));
+
+ _checkEquivalent(TypeBuilder.function(types: [t], required: [t], result: t),
+ TypeBuilder.function(types: [s], required: [s], result: s));
+ }
+
+ void test_genericFunction_simple_bounded() {
+ DartType s = TypeBuilder.variable("S");
+ DartType t = TypeBuilder.variable("T", bound: s);
+ DartType u = TypeBuilder.variable("U");
+ DartType v = TypeBuilder.variable("V", bound: u);
+
+ _checkEquivalent(TypeBuilder.function(types: [s, t]),
+ TypeBuilder.function(types: [u, v]));
+
+ _checkEquivalent(
+ TypeBuilder.function(types: [s, t], required: [s], result: t),
+ TypeBuilder.function(types: [u, v], required: [u], result: v));
+
+ {
+ DartType top =
+ TypeBuilder.function(types: [s, t], required: [t], result: s);
+ DartType left =
+ TypeBuilder.function(types: [u, v], required: [u], result: u);
+ DartType right =
+ TypeBuilder.function(types: [u, v], required: [v], result: v);
+ DartType bottom =
+ TypeBuilder.function(types: [s, t], required: [s], result: t);
+ _checkLattice(top, left, right, bottom);
+ }
+ }
+
+ void test_genericFunction_simple_fBounded() {
+ ClassElementImpl AClass = ElementFactory.classElement2('A', ["Q"]);
+ InterfaceType AType = AClass.type;
+ ClassElementImpl BClass = ElementFactory.classElement2('B', ["R"]);
+ BClass.supertype = AType.substitute4([BClass.typeParameters[0].type]);
+ InterfaceType BType = BClass.type;
+
+ DartType s = TypeBuilder.variable("S");
+ (s.element as TypeParameterElementImpl).bound = AType.substitute4([s]);
+ DartType t = TypeBuilder.variable("T", bound: s);
+ DartType u = TypeBuilder.variable("U");
+ (u.element as TypeParameterElementImpl).bound = BType.substitute4([u]);
+ DartType v = TypeBuilder.variable("V", bound: u);
+
+ _checkIsStrictSubtypeOf(
+ TypeBuilder.function(types: [s]), TypeBuilder.function(types: [u]));
+
+ _checkIsStrictSubtypeOf(
+ TypeBuilder.function(types: [s, t], required: [s], result: t),
+ TypeBuilder.function(types: [u, v], required: [u], result: v));
+ }
+
+ void test_generics() {
ClassElementImpl LClass = ElementFactory.classElement2('L', ["T"]);
InterfaceType LType = LClass.type;
ClassElementImpl MClass = ElementFactory.classElement2('M', ["T"]);
@@ -608,7 +697,7 @@
_checkLattice(top, left, right, bottom);
}
- void test_isSubtypeOf_int() {
+ void test_int() {
List<DartType> equivalents = <DartType>[intType];
List<DartType> supertypes = <DartType>[numType];
List<DartType> unrelated = <DartType>[doubleType];
@@ -616,24 +705,37 @@
equivalents: equivalents, supertypes: supertypes, unrelated: unrelated);
}
- void test_isSubtypeOf_named_optional() {
- DartType r = TypeBuilder.functionType(<DartType>[intType], intType);
- DartType o = TypeBuilder.functionType(<DartType>[], intType,
- optional: <DartType>[intType]);
- DartType n = TypeBuilder.functionType(<DartType>[], intType,
- named: <String, DartType>{'x': intType});
- DartType rr =
- TypeBuilder.functionType(<DartType>[intType, intType], intType);
- DartType ro = TypeBuilder.functionType(<DartType>[intType], intType,
- optional: <DartType>[intType]);
- DartType rn = TypeBuilder.functionType(<DartType>[intType], intType,
- named: <String, DartType>{'x': intType});
- DartType oo = TypeBuilder.functionType(<DartType>[], intType,
- optional: <DartType>[intType, intType]);
- DartType nn = TypeBuilder.functionType(<DartType>[], intType,
- named: <String, DartType>{'x': intType, 'y': intType});
- DartType nnn = TypeBuilder.functionType(<DartType>[], intType,
- named: <String, DartType>{'x': intType, 'y': intType, 'z': intType});
+ void test_named_optional() {
+ DartType r =
+ TypeBuilder.function(required: <DartType>[intType], result: intType);
+ DartType o = TypeBuilder.function(
+ required: <DartType>[], optional: <DartType>[intType], result: intType);
+ DartType n = TypeBuilder.function(
+ required: <DartType>[],
+ named: <String, DartType>{'x': intType},
+ result: intType);
+ DartType rr = TypeBuilder.function(
+ required: <DartType>[intType, intType], result: intType);
+ DartType ro = TypeBuilder.function(
+ required: <DartType>[intType],
+ optional: <DartType>[intType],
+ result: intType);
+ DartType rn = TypeBuilder.function(
+ required: <DartType>[intType],
+ named: <String, DartType>{'x': intType},
+ result: intType);
+ DartType oo = TypeBuilder.function(
+ required: <DartType>[],
+ optional: <DartType>[intType, intType],
+ result: intType);
+ DartType nn = TypeBuilder.function(
+ required: <DartType>[],
+ named: <String, DartType>{'x': intType, 'y': intType},
+ result: intType);
+ DartType nnn = TypeBuilder.function(
+ required: <DartType>[],
+ named: <String, DartType>{'x': intType, 'y': intType, 'z': intType},
+ result: intType);
_checkGroups(r,
equivalents: [r],
@@ -663,7 +765,7 @@
equivalents: [nnn], subtypes: [], unrelated: [r, o, rr, ro, rn, oo]);
}
- void test_isSubtypeOf_num() {
+ void test_num() {
List<DartType> equivalents = <DartType>[numType];
List<DartType> supertypes = <DartType>[];
List<DartType> unrelated = <DartType>[stringType];
@@ -675,29 +777,31 @@
subtypes: subtypes);
}
- // Regression test for https://github.com/dart-lang/sdk/issues/25069
- void test_isSubtypeOf_simple_function_void() {
- FunctionType functionType =
- TypeBuilder.functionType(<DartType>[intType], objectType);
- _checkIsNotSubtypeOf(voidType, functionType);
- }
-
- void test_isSubtypeOf_simple_function() {
+ void test_simple_function() {
FunctionType top =
- TypeBuilder.functionType(<DartType>[intType], objectType);
- FunctionType left = TypeBuilder.functionType(<DartType>[intType], intType);
- FunctionType right =
- TypeBuilder.functionType(<DartType>[objectType], objectType);
+ TypeBuilder.function(required: <DartType>[intType], result: objectType);
+ FunctionType left =
+ TypeBuilder.function(required: <DartType>[intType], result: intType);
+ FunctionType right = TypeBuilder.function(
+ required: <DartType>[objectType], result: objectType);
FunctionType bottom =
- TypeBuilder.functionType(<DartType>[objectType], intType);
+ TypeBuilder.function(required: <DartType>[objectType], result: intType);
_checkLattice(top, left, right, bottom);
}
- void test_isSubtypeOf_void_functions() {
- FunctionType top = TypeBuilder.functionType(<DartType>[intType], voidType);
+ /// Regression test for https://github.com/dart-lang/sdk/issues/25069
+ void test_simple_function_void() {
+ FunctionType functionType =
+ TypeBuilder.function(required: <DartType>[intType], result: objectType);
+ _checkIsNotSubtypeOf(voidType, functionType);
+ }
+
+ void test_void_functions() {
+ FunctionType top =
+ TypeBuilder.function(required: <DartType>[intType], result: voidType);
FunctionType bottom =
- TypeBuilder.functionType(<DartType>[objectType], intType);
+ TypeBuilder.function(required: <DartType>[objectType], result: intType);
_checkIsStrictSubtypeOf(bottom, top);
}
@@ -774,14 +878,25 @@
}
class TypeBuilder {
- static FunctionType functionType(
- List<DartType> parameters, DartType returnType,
- {List<DartType> optional, Map<String, DartType> named}) {
- return ElementFactory
- .functionElement8(parameters, returnType,
- optional: optional, named: named)
- .type;
+ static FunctionTypeImpl function(
+ {List<DartType> types,
+ List<DartType> required,
+ List<DartType> optional,
+ Map<String, DartType> named,
+ DartType result}) {
+ result = result ?? VoidTypeImpl.instance;
+ required = required ?? [];
+ FunctionElementImpl f = ElementFactory.functionElement8(required, result,
+ optional: optional, named: named);
+ if (types != null) {
+ f.typeParameters =
+ new List<TypeParameterElement>.from(types.map((t) => t.element));
+ }
+ return f.type = new FunctionTypeImpl(f);
}
+
+ static TypeParameterType variable(String name, {DartType bound}) =>
+ ElementFactory.typeParameterWithType(name, bound).type;
}
@reflectiveTest
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index c156aac..bd5876b 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.utilities_test;
+library analyzer.test.generated.utilities_test;
import 'dart:collection';
@@ -2109,6 +2109,12 @@
Expression get(AssertStatement node) => node.condition;
}
+class Getter_NodeReplacerTest_test_assertStatement_2
+ implements NodeReplacerTest_Getter {
+ @override
+ Expression get(AssertStatement node) => node.message;
+}
+
class Getter_NodeReplacerTest_test_assignmentExpression
implements NodeReplacerTest_Getter {
@override
@@ -3460,9 +3466,10 @@
}
void test_assertStatement() {
- AssertStatement node =
- AstFactory.assertStatement(AstFactory.booleanLiteral(true));
+ AssertStatement node = AstFactory.assertStatement(
+ AstFactory.booleanLiteral(true), AstFactory.string2('foo'));
_assertReplace(node, new Getter_NodeReplacerTest_test_assertStatement());
+ _assertReplace(node, new Getter_NodeReplacerTest_test_assertStatement_2());
}
void test_assignmentExpression() {
diff --git a/pkg/analyzer/test/instrumentation/instrumentation_test.dart b/pkg/analyzer/test/instrumentation/instrumentation_test.dart
index ac8755e..a938d4d 100644
--- a/pkg/analyzer/test/instrumentation/instrumentation_test.dart
+++ b/pkg/analyzer/test/instrumentation/instrumentation_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.instrumentation;
+library analyzer.test.instrumentation.instrumentation_test;
import 'dart:async';
diff --git a/pkg/analyzer/test/instrumentation/test_all.dart b/pkg/analyzer/test/instrumentation/test_all.dart
index f9bfc2d..46bb206 100644
--- a/pkg/analyzer/test/instrumentation/test_all.dart
+++ b/pkg/analyzer/test/instrumentation/test_all.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.instrumentation.test_all;
+library analyzer.test.instrumentation.test_all;
import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/parse_compilation_unit_test.dart b/pkg/analyzer/test/parse_compilation_unit_test.dart
index 71e4838..c5313da 100644
--- a/pkg/analyzer/test/parse_compilation_unit_test.dart
+++ b/pkg/analyzer/test/parse_compilation_unit_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.parse.compilation.unit;
+library analyzer.test.parse_compilation_unit_test;
import 'package:analyzer/analyzer.dart';
import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/reflective_tests.dart b/pkg/analyzer/test/reflective_tests.dart
index 8180cf7..24c36cb 100644
--- a/pkg/analyzer/test/reflective_tests.dart
+++ b/pkg/analyzer/test/reflective_tests.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library reflective_tests;
+library analyzer.test.reflective_tests;
@MirrorsUsed(metaTargets: 'ReflectiveTest')
import 'dart:mirrors';
diff --git a/pkg/analyzer/test/source/analysis_options_provider_test.dart b/pkg/analyzer/test/source/analysis_options_provider_test.dart
index 92b8cfc..d71304b 100644
--- a/pkg/analyzer/test/source/analysis_options_provider_test.dart
+++ b/pkg/analyzer/test/source/analysis_options_provider_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.source.analysis_options_provider;
+library analyzer.test.source.analysis_options_provider_test;
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/analysis_options_provider.dart';
diff --git a/pkg/analyzer/test/source/embedder_test.dart b/pkg/analyzer/test/source/embedder_test.dart
index ee50643..c152773 100644
--- a/pkg/analyzer/test/source/embedder_test.dart
+++ b/pkg/analyzer/test/source/embedder_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.source.embedder;
+library analyzer.test.source.embedder_test;
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/embedder.dart';
diff --git a/pkg/analyzer/test/source/error_processor_test.dart b/pkg/analyzer/test/source/error_processor_test.dart
new file mode 100644
index 0000000..3c3facb
--- /dev/null
+++ b/pkg/analyzer/test/source/error_processor_test.dart
@@ -0,0 +1,150 @@
+// 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 analyzer.test.source.error_processor;
+
+import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/task/options.dart';
+import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
+import 'package:unittest/unittest.dart';
+import 'package:yaml/src/yaml_node.dart';
+
+import '../generated/test_support.dart';
+import '../utils.dart';
+
+main() {
+ AnalysisError invalid_assignment =
+ new AnalysisError(new TestSource(), 0, 1, HintCode.INVALID_ASSIGNMENT, [
+ ['x'],
+ ['y']
+ ]);
+
+ AnalysisError missing_return =
+ new AnalysisError(new TestSource(), 0, 1, HintCode.MISSING_RETURN, [
+ ['x']
+ ]);
+
+ AnalysisError unused_local_variable = new AnalysisError(
+ new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
+ ['x']
+ ]);
+
+ AnalysisError use_of_void_result =
+ new AnalysisError(new TestSource(), 0, 1, HintCode.USE_OF_VOID_RESULT, [
+ ['x']
+ ]);
+
+ initializeTestEnvironment();
+ oneTimeSetup();
+
+ setUp(() {
+ context = new TestContext();
+ });
+
+ group('ErrorProcessorTest', () {
+ test('configureOptions', () {
+ configureOptions('''
+analyzer:
+ errors:
+ invalid_assignment: error # severity ERROR
+ missing_return: false # ignore
+ unused_local_variable: true # skipped
+ use_of_void_result: unsupported_action # skipped
+''');
+ expect(getProcessor(invalid_assignment).severity, ErrorSeverity.ERROR);
+ expect(getProcessor(missing_return).severity, isNull);
+ expect(getProcessor(unused_local_variable), isNull);
+ expect(getProcessor(use_of_void_result), isNull);
+ });
+ });
+
+ group('ErrorConfigTest', () {
+ var config = '''
+analyzer:
+ errors:
+ invalid_assignment: unsupported_action # should be skipped
+ missing_return: false
+ unused_local_variable: error
+''';
+
+ group('processing', () {
+ test('yaml map', () {
+ var options = optionsProvider.getOptionsFromString(config);
+ var errorConfig = new ErrorConfig(options['analyzer']['errors']);
+ expect(errorConfig.processors, hasLength(2));
+
+ // ignore
+ var missingReturnProcessor = errorConfig.processors
+ .firstWhere((p) => p.appliesTo(missing_return));
+ expect(missingReturnProcessor.severity, isNull);
+
+ // error
+ var unusedLocalProcessor = errorConfig.processors
+ .firstWhere((p) => p.appliesTo(unused_local_variable));
+ expect(unusedLocalProcessor.severity, ErrorSeverity.ERROR);
+
+ // skip
+ var invalidAssignmentProcessor = errorConfig.processors.firstWhere(
+ (p) => p.appliesTo(invalid_assignment),
+ orElse: () => null);
+ expect(invalidAssignmentProcessor, isNull);
+ });
+ test('string map', () {
+ var options = {
+ 'invalid_assignment': 'unsupported_action', // should be skipped
+ 'missing_return': 'false',
+ 'unused_local_variable': 'error'
+ };
+ var errorConfig = new ErrorConfig(options);
+ expect(errorConfig.processors, hasLength(2));
+
+ // ignore
+ var missingReturnProcessor = errorConfig.processors
+ .firstWhere((p) => p.appliesTo(missing_return));
+ expect(missingReturnProcessor.severity, isNull);
+
+ // error
+ var unusedLocalProcessor = errorConfig.processors
+ .firstWhere((p) => p.appliesTo(unused_local_variable));
+ expect(unusedLocalProcessor.severity, ErrorSeverity.ERROR);
+
+ // skip
+ var invalidAssignmentProcessor = errorConfig.processors.firstWhere(
+ (p) => p.appliesTo(invalid_assignment),
+ orElse: () => null);
+ expect(invalidAssignmentProcessor, isNull);
+ });
+ });
+ });
+}
+
+TestContext context;
+
+AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider();
+ErrorProcessor processor;
+
+void configureOptions(String options) {
+ Map<String, YamlNode> optionMap =
+ optionsProvider.getOptionsFromString(options);
+ configureContextOptions(context, optionMap);
+}
+
+ErrorProcessor getProcessor(AnalysisError error) =>
+ ErrorProcessor.getProcessor(context, error);
+
+void oneTimeSetup() {
+ List<Plugin> plugins = <Plugin>[];
+ plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+ plugins.add(AnalysisEngine.instance.commandLinePlugin);
+ plugins.add(AnalysisEngine.instance.optionsPlugin);
+ ExtensionManager manager = new ExtensionManager();
+ manager.processPlugins(plugins);
+}
+
+class TestContext extends AnalysisContextImpl {}
diff --git a/pkg/analyzer/test/source/package_map_provider_test.dart b/pkg/analyzer/test/source/package_map_provider_test.dart
index 3701630..f02b60a 100644
--- a/pkg/analyzer/test/source/package_map_provider_test.dart
+++ b/pkg/analyzer/test/source/package_map_provider_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.package.map.provider;
+library analyzer.test.source.package_map_provider_test;
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
diff --git a/pkg/analyzer/test/source/package_map_resolver_test.dart b/pkg/analyzer/test/source/package_map_resolver_test.dart
index caf88da..0017961 100644
--- a/pkg/analyzer/test/source/package_map_resolver_test.dart
+++ b/pkg/analyzer/test/source/package_map_resolver_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.source.package_map_resolver;
+library analyzer.test.source.package_map_resolver_test;
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
diff --git a/pkg/analyzer/test/source/path_filter_test.dart b/pkg/analyzer/test/source/path_filter_test.dart
index a7e58fb..1cada77 100644
--- a/pkg/analyzer/test/source/path_filter_test.dart
+++ b/pkg/analyzer/test/source/path_filter_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.source.path_filter;
+library analyzer.test.source.path_filter_test;
import 'package:analyzer/source/path_filter.dart';
import 'package:path/path.dart';
diff --git a/pkg/analyzer/test/source/sdk_ext_test.dart b/pkg/analyzer/test/source/sdk_ext_test.dart
index 01416af..dbb7425 100644
--- a/pkg/analyzer/test/source/sdk_ext_test.dart
+++ b/pkg/analyzer/test/source/sdk_ext_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.source.sdk_ext;
+library analyzer.test.source.sdk_ext_test;
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/sdk_ext.dart';
diff --git a/pkg/analyzer/test/source/test_all.dart b/pkg/analyzer/test/source/test_all.dart
index c47b329..725d23e 100644
--- a/pkg/analyzer/test/source/test_all.dart
+++ b/pkg/analyzer/test/source/test_all.dart
@@ -2,13 +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.
-library test.source;
+library analyzer.test.source.test_all;
import 'package:unittest/unittest.dart';
import '../utils.dart';
import 'analysis_options_provider_test.dart' as analysis_options_provider_test;
import 'embedder_test.dart' as embedder_test;
+import 'error_processor_test.dart' as error_processor_test;
import 'package_map_provider_test.dart' as package_map_provider_test;
import 'package_map_resolver_test.dart' as package_map_resolver_test;
import 'path_filter_test.dart' as path_filter_test;
@@ -20,6 +21,7 @@
group('source', () {
analysis_options_provider_test.main();
embedder_test.main();
+ error_processor_test.main();
package_map_provider_test.main();
package_map_resolver_test.main();
path_filter_test.main();
diff --git a/pkg/analyzer/test/src/context/abstract_context.dart b/pkg/analyzer/test/src/context/abstract_context.dart
index 135fd42..33f782b 100644
--- a/pkg/analyzer/test/src/context/abstract_context.dart
+++ b/pkg/analyzer/test/src/context/abstract_context.dart
@@ -2,19 +2,20 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.task.abstract_context_test;
+library analyzer.test.src.context.abstract_context;
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart'
- hide AnalysisCache, AnalysisContextImpl, AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/task/driver.dart';
import 'package:analyzer/task/model.dart';
+import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
import 'package:unittest/unittest.dart';
import 'mock_sdk.dart';
@@ -124,6 +125,14 @@
}
void setUp() {
+ List<Plugin> plugins = <Plugin>[];
+ plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+ plugins.add(AnalysisEngine.instance.commandLinePlugin);
+ plugins.add(AnalysisEngine.instance.optionsPlugin);
+
+ ExtensionManager manager = new ExtensionManager();
+ manager.processPlugins(plugins);
+
prepareAnalysisContext();
}
diff --git a/pkg/analyzer/test/src/context/cache_test.dart b/pkg/analyzer/test/src/context/cache_test.dart
index 0962474..37bd49c 100644
--- a/pkg/analyzer/test/src/context/cache_test.dart
+++ b/pkg/analyzer/test/src/context/cache_test.dart
@@ -2,15 +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.
-library test.src.task.driver_test;
+library analyzer.test.src.context.cache_test;
import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/generated/engine.dart'
- show
- AnalysisContext,
- CacheState,
- InternalAnalysisContext,
- RetentionPriority;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/sdk_io.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -34,9 +29,7 @@
runReflectiveTests(ResultDataTest);
}
-AnalysisCache createCache(
- {AnalysisContext context,
- RetentionPriority policy: RetentionPriority.LOW}) {
+AnalysisCache createCache({AnalysisContext context}) {
CachePartition partition = new UniversalCachePartition(context);
return new AnalysisCache(<CachePartition>[partition]);
}
@@ -1121,9 +1114,7 @@
}
class _InternalAnalysisContextMock extends TypedMock
- implements InternalAnalysisContext {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+ implements InternalAnalysisContext {}
/**
* Keep the given [keepDescriptor], invalidate all the other results.
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index 5fd7926..ca87671 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.context.context_test;
+library analyzer.test.src.context.context_test;
import 'dart:async';
@@ -13,24 +13,7 @@
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart'
- show
- AnalysisContext,
- AnalysisContextStatistics,
- AnalysisDelta,
- AnalysisEngine,
- AnalysisErrorInfo,
- AnalysisLevel,
- AnalysisNotScheduledError,
- AnalysisOptions,
- AnalysisOptionsImpl,
- AnalysisResult,
- ApplyChangesStatus,
- CacheState,
- ChangeNotice,
- ChangeSet,
- IncrementalAnalysisCache,
- TimestampedData;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -854,7 +837,7 @@
}
void test_exists_true() {
- expect(context.exists(new AnalysisContextImplTest_Source_exists_true()),
+ expect(context.exists(new _AnalysisContextImplTest_Source_exists_true()),
isTrue);
}
@@ -1314,7 +1297,7 @@
int stamp = 42;
expect(
context.getModificationStamp(
- new AnalysisContextImplTest_Source_getModificationStamp_fromSource(
+ new _AnalysisContextImplTest_Source_getModificationStamp_fromSource(
stamp)),
stamp);
}
@@ -1322,7 +1305,7 @@
void test_getModificationStamp_overridden() {
int stamp = 42;
Source source =
- new AnalysisContextImplTest_Source_getModificationStamp_overridden(
+ new _AnalysisContextImplTest_Source_getModificationStamp_overridden(
stamp);
context.setContents(source, "");
expect(stamp != context.getModificationStamp(source), isTrue);
@@ -1382,16 +1365,6 @@
expect(context.getSourcesWithFullName(filePath), unorderedEquals(expected));
}
- void test_getStatistics() {
- AnalysisContextStatistics statistics = context.statistics;
- expect(statistics, isNotNull);
- // The following lines are fragile.
- // The values depend on the number of libraries in the SDK.
-// assertLength(0, statistics.getCacheRows());
-// assertLength(0, statistics.getExceptions());
-// assertLength(0, statistics.getSources());
- }
-
void test_handleContentsChanged() {
ContentCache contentCache = new ContentCache();
context.contentCache = contentCache;
@@ -2727,6 +2700,27 @@
}
}
+class _AnalysisContextImplTest_Source_exists_true extends TestSource {
+ @override
+ bool exists() => true;
+}
+
+class _AnalysisContextImplTest_Source_getModificationStamp_fromSource
+ extends TestSource {
+ int stamp;
+ _AnalysisContextImplTest_Source_getModificationStamp_fromSource(this.stamp);
+ @override
+ int get modificationStamp => stamp;
+}
+
+class _AnalysisContextImplTest_Source_getModificationStamp_overridden
+ extends TestSource {
+ int stamp;
+ _AnalysisContextImplTest_Source_getModificationStamp_overridden(this.stamp);
+ @override
+ int get modificationStamp => stamp;
+}
+
class _AnalysisContextImplTest_test_applyChanges_removeContainer
implements SourceContainer {
Source libB;
diff --git a/pkg/analyzer/test/src/context/mock_sdk.dart b/pkg/analyzer/test/src/context/mock_sdk.dart
index ad1c2f6..f9ce626 100644
--- a/pkg/analyzer/test/src/context/mock_sdk.dart
+++ b/pkg/analyzer/test/src/context/mock_sdk.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.mock_sdk;
+library analyzer.test.src.context.mock_sdk;
import 'package:analyzer/file_system/file_system.dart' as resource;
import 'package:analyzer/file_system/memory_file_system.dart' as resource;
@@ -321,6 +321,13 @@
}
}
+class _MockSdkFile {
+ final String path;
+ final String content;
+
+ const _MockSdkFile(this.path, this.content);
+}
+
class _MockSdkLibrary implements SdkLibrary {
final String shortName;
final String path;
@@ -354,13 +361,6 @@
UnimplementedError get unimplemented => new UnimplementedError();
}
-class _MockSdkFile {
- final String path;
- final String content;
-
- const _MockSdkFile(this.path, this.content);
-}
-
/**
* An [AnalysisContextImpl] that only contains sources for a Dart SDK.
*/
@@ -374,8 +374,7 @@
if (factory == null) {
return super.createCacheFromSourceFactory(factory);
}
- return new AnalysisCache(<CachePartition>[
- AnalysisEngine.instance.partitionManager_new.forSdk(sdk)
- ]);
+ return new AnalysisCache(
+ <CachePartition>[AnalysisEngine.instance.partitionManager.forSdk(sdk)]);
}
}
diff --git a/pkg/analyzer/test/src/context/test_all.dart b/pkg/analyzer/test/src/context/test_all.dart
index bbd021d..301b13c 100644
--- a/pkg/analyzer/test/src/context/test_all.dart
+++ b/pkg/analyzer/test/src/context/test_all.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.context.test_all;
+library analyzer.test.src.context.test_all;
import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/src/mock_sdk.dart b/pkg/analyzer/test/src/mock_sdk.dart
index d4f6ac1..4641b07 100644
--- a/pkg/analyzer/test/src/mock_sdk.dart
+++ b/pkg/analyzer/test/src/mock_sdk.dart
@@ -2,11 +2,11 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.mock_sdk;
+library analyzer.test.src.mock_sdk;
import 'package:analyzer/file_system/file_system.dart' as resource;
import 'package:analyzer/file_system/memory_file_system.dart' as resource;
-import 'package:analyzer/src/context/context.dart' as newContext;
+import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -201,11 +201,7 @@
@override
AnalysisContext get context {
if (_analysisContext == null) {
- if (AnalysisEngine.instance.useTaskModel) {
- _analysisContext = new newContext.SdkAnalysisContext();
- } else {
- _analysisContext = new SdkAnalysisContext();
- }
+ _analysisContext = new SdkAnalysisContext();
SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
_analysisContext.sourceFactory = factory;
ChangeSet changeSet = new ChangeSet();
diff --git a/pkg/analyzer/test/src/plugin/plugin_config_test.dart b/pkg/analyzer/test/src/plugin/plugin_config_test.dart
index cc06b96..2c9fa04 100644
--- a/pkg/analyzer/test/src/plugin/plugin_config_test.dart
+++ b/pkg/analyzer/test/src/plugin/plugin_config_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.plugin.plugin_config_test;
+library analyzer.test.src.plugin.plugin_config_test;
import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:analyzer/src/plugin/plugin_configuration.dart';
diff --git a/pkg/analyzer/test/src/summary/summary_test.dart b/pkg/analyzer/test/src/summary/summary_test.dart
index be2844e..e6107e4 100644
--- a/pkg/analyzer/test/src/summary/summary_test.dart
+++ b/pkg/analyzer/test/src/summary/summary_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.serialization.elements_test;
+library analyzer.test.src.summary.summary_test;
import 'dart:typed_data';
@@ -67,6 +67,7 @@
@override
void setUp() {
+ super.setUp();
AnalysisOptionsImpl options = new AnalysisOptionsImpl();
options.enableGenericMethods = true;
resetWithOptions(options);
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index dcb6980..09d71ad 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.task.dart_test;
+library analyzer.test.src.task.dart_test;
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/generated/ast.dart';
@@ -47,7 +47,6 @@
runReflectiveTests(ComputePropagableVariableDependenciesTaskTest);
runReflectiveTests(ContainingLibrariesTaskTest);
runReflectiveTests(DartErrorsTaskTest);
- runReflectiveTests(ErrorFilterTest);
runReflectiveTests(EvaluateUnitConstantsTaskTest);
runReflectiveTests(GatherUsedImportedElementsTaskTest);
runReflectiveTests(GatherUsedLocalElementsTaskTest);
@@ -1116,8 +1115,9 @@
computeResult(target, CONSTANT_VALUE,
matcher: isComputeConstantValueTask);
expect(outputs[CONSTANT_VALUE], same(target));
- EvaluationResultImpl evaluationResult = (annotation.elementAnnotation
- as ElementAnnotationImpl).evaluationResult;
+ EvaluationResultImpl evaluationResult =
+ (annotation.elementAnnotation as ElementAnnotationImpl)
+ .evaluationResult;
return evaluationResult;
}
}
@@ -1285,8 +1285,9 @@
for (String otherVariableName in otherVariables) {
PropertyInducingElement otherVariableElement =
AstFinder.getTopLevelVariableElement(unit, otherVariableName);
- _expectCircularityError((otherVariableElement
- as TopLevelVariableElementImpl).evaluationResult);
+ _expectCircularityError(
+ (otherVariableElement as TopLevelVariableElementImpl)
+ .evaluationResult);
}
}
@@ -1426,6 +1427,62 @@
expect(outputs[LIBRARY_CYCLE], hasLength(1));
}
+ void test_library_cycle_override_inference_incremental() {
+ enableStrongMode();
+ Source lib1Source = newSource(
+ '/my_lib1.dart',
+ '''
+library my_lib1;
+import 'my_lib3.dart';
+''');
+ Source lib2Source = newSource(
+ '/my_lib2.dart',
+ '''
+library my_lib2;
+import 'my_lib1.dart';
+''');
+ Source lib3Source = newSource(
+ '/my_lib3.dart',
+ '''
+library my_lib3;
+import 'my_lib2.dart';
+
+class A {
+ int foo(int x) => null;
+}
+class B extends A {
+ foo(x) => null;
+}
+''');
+ AnalysisTarget lib1Target = new LibrarySpecificUnit(lib1Source, lib1Source);
+ AnalysisTarget lib2Target = new LibrarySpecificUnit(lib2Source, lib2Source);
+ AnalysisTarget lib3Target = new LibrarySpecificUnit(lib3Source, lib3Source);
+
+ computeResult(lib1Target, RESOLVED_UNIT);
+ computeResult(lib2Target, RESOLVED_UNIT);
+ computeResult(lib3Target, RESOLVED_UNIT);
+ CompilationUnit unit = outputs[RESOLVED_UNIT];
+ ClassElement b = unit.declarations[1].element;
+ expect(b.getMethod('foo').returnType.toString(), 'int');
+
+ // add a dummy edit.
+ context.setContents(
+ lib1Source,
+ '''
+library my_lib1;
+import 'my_lib3.dart';
+var foo = 123;
+''');
+
+ computeResult(lib1Target, RESOLVED_UNIT);
+ computeResult(lib2Target, RESOLVED_UNIT);
+ computeResult(lib3Target, RESOLVED_UNIT);
+ unit = outputs[RESOLVED_UNIT];
+ b = unit.declarations[1].element;
+ expect(b.getMethod('foo').returnType.toString(), 'int',
+ reason: 'edit should not affect member inference');
+ }
+
void test_library_cycle_incremental_partial() {
enableStrongMode();
Source lib1Source = newSource(
@@ -1962,32 +2019,6 @@
}
@reflectiveTest
-class ErrorFilterTest extends _AbstractDartTaskTest {
- @override
- setUp() {
- super.setUp();
- context.setConfigurationData(CONFIGURED_ERROR_FILTERS, [
- (AnalysisError error) => error.errorCode.name == 'INVALID_ASSIGNMENT'
- ]);
- }
-
- test_error_filters() {
- AnalysisTarget library = newSource(
- '/test.dart',
- '''
-main() {
- int x = ""; // INVALID_ASSIGNMENT (suppressed)
- // UNUSED_LOCAL_VARIABLE
-}''');
- computeResult(library, DART_ERRORS, matcher: isDartErrorsTask);
- expect(outputs, hasLength(1));
- List<AnalysisError> errors = outputs[DART_ERRORS];
- expect(errors, hasLength(1));
- expect(errors.first.errorCode, HintCode.UNUSED_LOCAL_VARIABLE);
- }
-}
-
-@reflectiveTest
class EvaluateUnitConstantsTaskTest extends _AbstractDartTaskTest {
test_perform() {
Source source = newSource(
@@ -3879,8 +3910,9 @@
VariableElement tau =
AstFinder.getTopLevelVariable(unit, 'tau').name.staticElement;
Expression piFirstUse = (AstFinder
- .getTopLevelVariable(unit, 'tau')
- .initializer as ConditionalExpression).condition;
+ .getTopLevelVariable(unit, 'tau')
+ .initializer as ConditionalExpression)
+ .condition;
expect(piFirstUse.staticType, context.typeProvider.boolType);
expect(piFirst.type, context.typeProvider.boolType);
diff --git a/pkg/analyzer/test/src/task/dart_work_manager_test.dart b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
index a10cfef..7938cc9 100644
--- a/pkg/analyzer/test/src/task/dart_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.task.dart_work_manager_test;
+library analyzer.test.src.task.dart_work_manager_test;
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/generated/ast.dart';
@@ -210,8 +210,8 @@
}
void test_applyPriorityTargets_isLibrary_computeErrors() {
- when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(true);
- when(context.shouldErrorsBeAnalyzed(source3, null)).thenReturn(true);
+ when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(true);
+ when(context.shouldErrorsBeAnalyzed(source3)).thenReturn(true);
entry1.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
entry2.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
entry3.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
@@ -234,8 +234,8 @@
}
void test_applyPriorityTargets_isLibrary_computeUnit() {
- when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(false);
- when(context.shouldErrorsBeAnalyzed(source3, null)).thenReturn(false);
+ when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(false);
+ when(context.shouldErrorsBeAnalyzed(source3)).thenReturn(false);
entry1.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
entry2.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
entry3.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
@@ -593,8 +593,8 @@
entry1.setValue(SCAN_ERRORS, <AnalysisError>[error1], []);
entry1.setValue(PARSE_ERRORS, <AnalysisError>[error2], []);
// PARSED_UNIT is ready, set errors
- manager.resultsComputed(
- source1, {PARSED_UNIT: AstFactory.compilationUnit()});
+ manager
+ .resultsComputed(source1, {PARSED_UNIT: AstFactory.compilationUnit()});
// all of the errors are included
ChangeNoticeImpl notice = context.getNotice(source1);
expect(notice.errors, unorderedEquals([error1, error2]));
@@ -611,8 +611,7 @@
expect(cache.getState(part1, CONTAINING_LIBRARIES), CacheState.VALID);
// configure AnalysisContext mock
when(context.prioritySources).thenReturn(<Source>[]);
- when(context.shouldErrorsBeAnalyzed(anyObject, anyObject))
- .thenReturn(false);
+ when(context.shouldErrorsBeAnalyzed(anyObject)).thenReturn(false);
// library1 parts
manager.resultsComputed(library1, {
INCLUDED_PARTS: [part1, part2],
@@ -705,7 +704,7 @@
void test_resultsComputed_sourceKind_isLibrary() {
manager.unknownSourceQueue.addAll([source1, source2, source3]);
when(context.prioritySources).thenReturn(<Source>[]);
- when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(true);
+ when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(true);
manager.resultsComputed(source2, {SOURCE_KIND: SourceKind.LIBRARY});
expect_librarySourceQueue([source2]);
expect_unknownSourceQueue([source1, source3]);
@@ -714,7 +713,7 @@
void test_resultsComputed_sourceKind_isLibrary_isPriority_computeErrors() {
manager.unknownSourceQueue.addAll([source1, source2, source3]);
when(context.prioritySources).thenReturn(<Source>[source2]);
- when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(true);
+ when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(true);
manager.resultsComputed(source2, {SOURCE_KIND: SourceKind.LIBRARY});
expect_unknownSourceQueue([source1, source3]);
expect(manager.priorityResultQueue,
@@ -724,7 +723,7 @@
void test_resultsComputed_sourceKind_isLibrary_isPriority_computeUnit() {
manager.unknownSourceQueue.addAll([source1, source2, source3]);
when(context.prioritySources).thenReturn(<Source>[source2]);
- when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(false);
+ when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(false);
manager.resultsComputed(source2, {SOURCE_KIND: SourceKind.LIBRARY});
expect_unknownSourceQueue([source1, source3]);
expect(
@@ -762,13 +761,9 @@
}
}
-class _DartSdkMock extends TypedMock implements DartSdk {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _DartSdkMock extends TypedMock implements DartSdk {}
-class _DartWorkManagerMock extends TypedMock implements DartWorkManager {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _DartWorkManagerMock extends TypedMock implements DartWorkManager {}
class _InternalAnalysisContextMock extends TypedMock
implements InternalAnalysisContext {
@@ -800,20 +795,15 @@
return _pendingNotices.putIfAbsent(
source, () => new ChangeNoticeImpl(source));
}
-
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
-class _SourceFactoryMock extends TypedMock implements SourceFactory {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _SourceFactoryMock extends TypedMock implements SourceFactory {}
class _SourceMock extends TypedMock implements Source {
final String shortName;
_SourceMock(this.shortName);
@override
String get fullName => '/' + shortName;
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
@override
String toString() => fullName;
}
diff --git a/pkg/analyzer/test/src/task/driver_test.dart b/pkg/analyzer/test/src/task/driver_test.dart
index 9560dc8..e135d99 100644
--- a/pkg/analyzer/test/src/task/driver_test.dart
+++ b/pkg/analyzer/test/src/task/driver_test.dart
@@ -2,16 +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.
-library test.src.task.driver_test;
+library analyzer.test.src.task.driver_test;
import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/generated/engine.dart'
- hide
- AnalysisCache,
- AnalysisContextImpl,
- AnalysisTask,
- UniversalCachePartition,
- WorkManager;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/task/driver.dart';
import 'package:analyzer/src/task/inputs.dart';
@@ -761,8 +755,6 @@
}
return entry;
}
-
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
/**
@@ -788,6 +780,4 @@
}
}
-class _WorkManagerMock extends TypedMock implements WorkManager {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _WorkManagerMock extends TypedMock implements WorkManager {}
diff --git a/pkg/analyzer/test/src/task/general_test.dart b/pkg/analyzer/test/src/task/general_test.dart
index b335664..da4c462 100644
--- a/pkg/analyzer/test/src/task/general_test.dart
+++ b/pkg/analyzer/test/src/task/general_test.dart
@@ -2,10 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.task.general_test;
+library analyzer.test.src.task.general_test;
-import 'package:analyzer/src/generated/engine.dart'
- hide AnalysisTask, GetContentTask;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/task/general.dart';
import 'package:analyzer/task/general.dart';
@@ -81,6 +80,4 @@
}
}
-class _MockContext extends TypedMock implements AnalysisContext {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _MockContext extends TypedMock implements AnalysisContext {}
diff --git a/pkg/analyzer/test/src/task/html_test.dart b/pkg/analyzer/test/src/task/html_test.dart
index 0806e90..c8f1f97 100644
--- a/pkg/analyzer/test/src/task/html_test.dart
+++ b/pkg/analyzer/test/src/task/html_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.task.html_test;
+library analyzer.test.src.task.html_test;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/task/html.dart';
@@ -303,15 +303,22 @@
<title>test page</title>
</head>
<body>
- <h1>Test</h1>
+ <h1 myAttr='my value'>Test</h1>
</body>
</html>
''';
AnalysisTarget target = newSource('/test.html', code);
computeResult(target, HTML_DOCUMENT);
expect(task, isParseHtmlTask);
- expect(outputs[HTML_DOCUMENT], isNotNull);
expect(outputs[HTML_DOCUMENT_ERRORS], isEmpty);
+ // HTML_DOCUMENT
+ {
+ Document document = outputs[HTML_DOCUMENT];
+ expect(document, isNotNull);
+ // verify that attributes are not lower-cased
+ Element element = document.body.getElementsByTagName('h1').single;
+ expect(element.attributes['myAttr'], 'my value');
+ }
// LINE_INFO
{
LineInfo lineInfo = outputs[LINE_INFO];
diff --git a/pkg/analyzer/test/src/task/html_work_manager_test.dart b/pkg/analyzer/test/src/task/html_work_manager_test.dart
index 0785f97..8d1d168 100644
--- a/pkg/analyzer/test/src/task/html_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/html_work_manager_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.task.html_work_manager_test;
+library analyzer.test.src.task.html_work_manager_test;
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/generated/engine.dart'
@@ -110,8 +110,8 @@
}
void test_applyPriorityTargets() {
- when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(true);
- when(context.shouldErrorsBeAnalyzed(source3, null)).thenReturn(true);
+ when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(true);
+ when(context.shouldErrorsBeAnalyzed(source3)).thenReturn(true);
manager.priorityResultQueue.add(new TargetedResult(source1, HTML_ERRORS));
manager.priorityResultQueue.add(new TargetedResult(source2, HTML_ERRORS));
// -source1 +source3
@@ -346,6 +346,4 @@
return _pendingNotices.putIfAbsent(
source, () => new ChangeNoticeImpl(source));
}
-
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
diff --git a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
index b495be7..a331255 100644
--- a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
+++ b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.task.incremental_element_builder_test;
+library analyzer.test.src.task.incremental_element_builder_test;
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
diff --git a/pkg/analyzer/test/src/task/inputs_test.dart b/pkg/analyzer/test/src/task/inputs_test.dart
index 3943a99..be97598 100644
--- a/pkg/analyzer/test/src/task/inputs_test.dart
+++ b/pkg/analyzer/test/src/task/inputs_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.task.inputs_test;
+library analyzer.test.src.task.inputs_test;
import 'package:analyzer/src/task/inputs.dart';
import 'package:analyzer/src/task/model.dart';
@@ -37,6 +37,7 @@
ConstantTaskInputBuilder builder;
void setUp() {
+ super.setUp();
builder = new ConstantTaskInputBuilder(input);
}
@@ -555,7 +556,7 @@
}
@reflectiveTest
-class ObjectToListTaskInputBuilderTest extends EngineTestCase {
+class ObjectToListTaskInputBuilderTest {
static final AnalysisTarget target = new TestSource();
static final ResultDescriptorImpl result =
new ResultDescriptorImpl('result', null);
@@ -705,7 +706,7 @@
}
@reflectiveTest
-class SimpleTaskInputBuilderTest extends EngineTestCase {
+class SimpleTaskInputBuilderTest {
static final AnalysisTarget target = new TestSource();
static final ResultDescriptorImpl result =
new ResultDescriptorImpl('result', null);
diff --git a/pkg/analyzer/test/src/task/manager_test.dart b/pkg/analyzer/test/src/task/manager_test.dart
index 783c015..e78cba4 100644
--- a/pkg/analyzer/test/src/task/manager_test.dart
+++ b/pkg/analyzer/test/src/task/manager_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.task.manager_test;
+library analyzer.test.src.task.manager_test;
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/task/manager.dart';
diff --git a/pkg/analyzer/test/src/task/model_test.dart b/pkg/analyzer/test/src/task/model_test.dart
index 00cdcfa..4db1ee2 100644
--- a/pkg/analyzer/test/src/task/model_test.dart
+++ b/pkg/analyzer/test/src/task/model_test.dart
@@ -2,9 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.task.model_test;
+library analyzer.test.src.task.model_test;
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/task/model.dart';
import 'package:analyzer/task/model.dart';
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index eacff89..6d35a3e 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -2,11 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.task.options_test;
+library analyzer.test.src.task.options_test;
import 'package:analyzer/analyzer.dart';
import 'package:analyzer/source/analysis_options_provider.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisContextImpl;
+import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/task/general.dart';
@@ -68,30 +69,36 @@
expect(analysisOptions.enableSuperMixins, true);
}
- test_configure_error_filters() {
+ test_configure_error_processors() {
configureContext('''
analyzer:
errors:
invalid_assignment: ignore
- unused_local_variable: ignore
+ unused_local_variable: error
''');
- List<ErrorFilter> filters =
- context.getConfigurationData(CONFIGURED_ERROR_FILTERS);
- expect(filters, hasLength(2));
+ List<ErrorProcessor> processors =
+ context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+ expect(processors, hasLength(2));
- var unused_error = new AnalysisError(
+ var unused_local = new AnalysisError(
new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
['x']
]);
- var invalid_assignment_error =
+ var invalid_assignment =
new AnalysisError(new TestSource(), 0, 1, HintCode.INVALID_ASSIGNMENT, [
['x'],
['y']
]);
- expect(filters.any((filter) => filter(unused_error)), isTrue);
- expect(filters.any((filter) => filter(invalid_assignment_error)), isTrue);
+ // ignore
+ var invalidAssignment =
+ processors.firstWhere((p) => p.appliesTo(invalid_assignment));
+ expect(invalidAssignment.severity, isNull);
+
+ // error
+ var unusedLocal = processors.firstWhere((p) => p.appliesTo(unused_local));
+ expect(unusedLocal.severity, ErrorSeverity.ERROR);
}
test_configure_strong_mode() {
diff --git a/pkg/analyzer/test/src/task/options_work_manager_test.dart b/pkg/analyzer/test/src/task/options_work_manager_test.dart
index 424a729..cf6cac0 100644
--- a/pkg/analyzer/test/src/task/options_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/options_work_manager_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.task.options_work_manager_test;
+library analyzer.test.src.task.options_work_manager_test;
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/generated/engine.dart'
@@ -111,8 +111,8 @@
}
void test_applyPriorityTargets() {
- when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(true);
- when(context.shouldErrorsBeAnalyzed(source3, null)).thenReturn(true);
+ when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(true);
+ when(context.shouldErrorsBeAnalyzed(source3)).thenReturn(true);
manager.priorityResultQueue
.add(new TargetedResult(source1, ANALYSIS_OPTIONS_ERRORS));
manager.priorityResultQueue
@@ -136,8 +136,8 @@
source1, 1, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
AnalysisError error2 = new AnalysisError(
source1, 2, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
- entry1.setValue(
- ANALYSIS_OPTIONS_ERRORS, <AnalysisError>[error1, error2], []);
+ entry1
+ .setValue(ANALYSIS_OPTIONS_ERRORS, <AnalysisError>[error1, error2], []);
List<AnalysisError> errors = manager.getErrors(source1);
expect(errors, unorderedEquals([error1, error2]));
@@ -233,8 +233,8 @@
source1, 2, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
LineInfo lineInfo = new LineInfo([0]);
entry1.setValue(LINE_INFO, lineInfo, []);
- entry1.setValue(
- ANALYSIS_OPTIONS_ERRORS, <AnalysisError>[error1, error2], []);
+ entry1
+ .setValue(ANALYSIS_OPTIONS_ERRORS, <AnalysisError>[error1, error2], []);
// RESOLVED_UNIT is ready, set errors
manager.resultsComputed(source1, {ANALYSIS_OPTIONS_ERRORS: null});
// all of the errors are included
@@ -282,6 +282,4 @@
@override
ChangeNoticeImpl getNotice(Source source) =>
_pendingNotices.putIfAbsent(source, () => new ChangeNoticeImpl(source));
-
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index a1170ef..b896776 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -5,7 +5,7 @@
// TODO(jmesserly): this file needs to be refactored, it's a port from
// package:dev_compiler's tests
/// General type checking tests
-library test.src.task.strong.checker_test;
+library analyzer.test.src.task.strong.checker_test;
import 'package:unittest/unittest.dart';
@@ -247,7 +247,7 @@
class B extends A {
B() : super(/*severe:STATIC_TYPE_ERROR*/"hello");
- B.c2(int x, String y) : super.c2(/*severe:STATIC_TYPE_ERROR*/y,
+ B.c2(int x, String y) : super.c2(/*severe:STATIC_TYPE_ERROR*/y,
/*severe:STATIC_TYPE_ERROR*/x);
B.c3(num x, Object y) : super.c3(x, /*info:DOWN_CAST_IMPLICIT*/y);
@@ -1351,6 +1351,49 @@
'''
});
+ testChecker('generic class method override', {
+ '/main.dart': '''
+ class A {}
+ class B extends A {}
+
+ class Base<T extends B> {
+ T foo() => null;
+ }
+
+ class Derived<S extends A> extends Base<B> {
+ /*severe:INVALID_METHOD_OVERRIDE*/S foo() => null;
+ }
+
+ class Derived2<S extends B> extends Base<B> {
+ S foo() => null;
+ }
+ '''
+ });
+
+ testChecker('generic method override', {
+ '/main.dart': '''
+ class Future<T> {
+ /*=S*/ then/*<S>*/(/*=S*/ onValue(T t)) => null;
+ }
+
+ class DerivedFuture<T> extends Future<T> {
+ /*=S*/ then/*<S>*/(/*=S*/ onValue(T t)) => null;
+ }
+
+ class DerivedFuture2<A> extends Future<A> {
+ /*=B*/ then/*<B>*/(/*=B*/ onValue(A a)) => null;
+ }
+
+ class DerivedFuture3<T> extends Future<T> {
+ /*=S*/ then/*<S>*/(Object onValue(T t)) => null;
+ }
+
+ class DerivedFuture4<A> extends Future<A> {
+ /*=B*/ then/*<B>*/(Object onValue(A a)) => null;
+ }
+ '''
+ });
+
testChecker('unary operators', {
'/main.dart': '''
class A {
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 8fe4b37..a643e3b 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -5,7 +5,7 @@
// TODO(jmesserly): this file needs to be refactored, it's a port from
// package:dev_compiler's tests
/// Tests for type inference.
-library test.src.task.strong.inferred_type_test;
+library analyzer.test.src.task.strong.inferred_type_test;
import 'package:unittest/unittest.dart';
@@ -349,6 +349,36 @@
'''
});
+ testChecker('infer list literal nested in map literal', {
+ '/main.dart': r'''
+class Resource {}
+class Folder extends Resource {}
+
+Resource getResource(String str) => null;
+
+class Foo<T> {
+ Foo(T t);
+}
+
+main() {
+ // List inside map
+ var map = <String, List<Folder>>{
+ 'pkgA': /*info:INFERRED_TYPE_LITERAL*/[/*info:DOWN_CAST_IMPLICIT*/getResource('/pkgA/lib/')],
+ 'pkgB': /*info:INFERRED_TYPE_LITERAL*/[/*info:DOWN_CAST_IMPLICIT*/getResource('/pkgB/lib/')]
+ };
+ // Also try map inside list
+ var list = <Map<String, Folder>>[
+ /*info:INFERRED_TYPE_LITERAL*/{ 'pkgA': /*info:DOWN_CAST_IMPLICIT*/getResource('/pkgA/lib/') },
+ /*info:INFERRED_TYPE_LITERAL*/{ 'pkgB': /*info:DOWN_CAST_IMPLICIT*/getResource('/pkgB/lib/') },
+ ];
+ // Instance creation too
+ var foo = new Foo<List<Folder>>(
+ /*info:INFERRED_TYPE_LITERAL*/[/*info:DOWN_CAST_IMPLICIT*/getResource('/pkgA/lib/')]
+ );
+}
+ '''
+ });
+
// but flags can enable this behavior.
testChecker('infer if complex expressions read possibly inferred field', {
'/a.dart': '''
@@ -1120,6 +1150,63 @@
}
''';
testChecker('infer downwards', {'/main.dart': code});
+
+ testChecker('infer if value types match context', {'/main.dart': r'''
+class DartType {}
+typedef void Asserter<T>(T type);
+typedef Asserter<T> AsserterBuilder<S, T>(S arg);
+
+Asserter<DartType> _isInt;
+Asserter<DartType> _isString;
+
+abstract class C {
+ static AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf;
+ static AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf;
+
+ AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+ AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
+
+ method(AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf) {
+ assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+ assertBOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+ assertCOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+ assertDOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+ assertEOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+ }
+}
+
+abstract class G<T> {
+ AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+ AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
+
+ method(AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf) {
+ assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+ this.assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+ this.assertDOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+ assertEOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+ }
+}
+
+AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf;
+AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf;
+
+main() {
+ AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+ assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+ assertBOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+ assertCOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+ C.assertBOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+ C.assertCOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+
+ C c;
+ c.assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+ c.assertDOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+
+ G<int> g;
+ g.assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+ g.assertDOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+}
+ '''});
});
group('downwards inference on function arguments', () {
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 360f6c1..b325909c 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -4,381 +4,33 @@
// TODO(jmesserly): this file needs to be refactored, it's a port from
// package:dev_compiler's tests
-library test.src.task.strong.strong_test_helper;
+library analyzer.test.src.task.strong.strong_test_helper;
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/context/context.dart' show SdkAnalysisContext;
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart' hide SdkAnalysisContext;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/type_system.dart';
import 'package:analyzer/src/task/strong/checker.dart';
-import 'package:analyzer/src/task/strong/rules.dart';
-import 'package:logging/logging.dart'; // TODO(jmesserly): remove
-import 'package:source_span/source_span.dart'; // TODO(jmesserly): remove
+import 'package:logging/logging.dart';
+import 'package:source_span/source_span.dart';
import 'package:unittest/unittest.dart';
-/// Run the checker on a program with files contents as indicated in
-/// [testFiles].
-///
-/// This function makes several assumptions to make it easier to describe error
-/// expectations:
-///
-/// * a file named `/main.dart` exists in [testFiles].
-/// * all expected failures are listed in the source code using comments
-/// immediately in front of the AST node that should contain the error.
-/// * errors are formatted as a token `level:Type`, where `level` is the
-/// logging level were the error would be reported at, and `Type` is the
-/// concrete subclass of [StaticInfo] that denotes the error.
-///
-/// For example, to check that an assignment produces a warning about a boxing
-/// conversion, you can describe the test as follows:
-///
-/// testChecker({
-/// '/main.dart': '''
-/// testMethod() {
-/// dynamic x = /*warning:Box*/3;
-/// }
-/// '''
-/// });
-///
-void testChecker(String name, Map<String, String> testFiles) {
- test(name, () {
- expect(testFiles.containsKey('/main.dart'), isTrue,
- reason: '`/main.dart` is missing in testFiles');
+const String GREEN_COLOR = '\u001b[32m';
- var provider = new MemoryResourceProvider();
- testFiles.forEach((key, value) {
- var scheme = 'package:';
- if (key.startsWith(scheme)) {
- key = '/packages/${key.substring(scheme.length)}';
- }
- provider.newFile(key, value);
- });
- var uriResolver = new TestUriResolver(provider);
- // Enable task model strong mode
- AnalysisEngine.instance.useTaskModel = true;
- var context = AnalysisEngine.instance.createAnalysisContext();
- context.analysisOptions.strongMode = true;
- context.analysisOptions.strongModeHints = true;
+const String NO_COLOR = '\u001b[0m';
- context.sourceFactory = new SourceFactory([
- new MockDartSdk(mockSdkSources, reportMissing: true).resolver,
- uriResolver
- ]);
+const String _CYAN_COLOR = '\u001b[36m';
- // Run the checker on /main.dart.
- Source mainSource = uriResolver.resolveAbsolute(new Uri.file('/main.dart'));
- var initialLibrary =
- context.resolveCompilationUnit2(mainSource, mainSource);
+const String _MAGENTA_COLOR = '\u001b[35m';
- var collector = new _ErrorCollector();
- var checker = new CodeChecker(
- new TypeRules(context.typeProvider), collector,
- hints: true);
+const String _RED_COLOR = '\u001b[31m';
- // Extract expectations from the comments in the test files, and
- // check that all errors we emit are included in the expected map.
- var allLibraries = reachableLibraries(initialLibrary.element.library);
- for (var lib in allLibraries) {
- for (var unit in lib.units) {
- var errors = <AnalysisError>[];
- collector.errors = errors;
-
- var source = unit.source;
- if (source.uri.scheme == 'dart') continue;
-
- var librarySource = context.getLibrariesContaining(source).single;
- var resolved = context.resolveCompilationUnit2(source, librarySource);
- var analyzerErrors = context
- .getErrors(source)
- .errors
- .where((error) =>
- error.errorCode.name.startsWith('STRONG_MODE_INFERRED_TYPE'))
- .toList();
- errors.addAll(analyzerErrors);
- checker.visitCompilationUnit(resolved);
-
- new _ExpectedErrorVisitor(errors).validate(resolved);
- }
- }
- });
-}
-
-class _ErrorCollector implements AnalysisErrorListener {
- List<AnalysisError> errors;
- final bool hints;
- _ErrorCollector({this.hints: true});
-
- void onError(AnalysisError error) {
- // Unless DDC hints are requested, filter them out.
- var HINT = ErrorSeverity.INFO.ordinal;
- if (hints || error.errorCode.errorSeverity.ordinal > HINT) {
- errors.add(error);
- }
- }
-}
-
-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('/packages/' + uri.path) as File)
- .createSource(uri);
- }
- return super.resolveAbsolute(uri, actualUri);
- }
-}
-
-class _ExpectedErrorVisitor extends UnifyingAstVisitor {
- final Set<AnalysisError> _actualErrors;
- CompilationUnit _unit;
- String _unitSourceCode;
-
- _ExpectedErrorVisitor(List<AnalysisError> actualErrors)
- : _actualErrors = new Set.from(actualErrors);
-
- validate(CompilationUnit unit) {
- _unit = unit;
- // This reads the file. Only safe because tests use MemoryFileSystem.
- _unitSourceCode = unit.element.source.contents.data;
-
- // Visit the compilation unit.
- unit.accept(this);
-
- if (_actualErrors.isNotEmpty) {
- var actualMsgs = _actualErrors.map(_formatActualError).join('\n');
- fail('Unexpected errors reported by checker:\n\n$actualMsgs');
- }
- }
-
- visitNode(AstNode node) {
- var token = node.beginToken;
- var comment = token.precedingComments;
- // Use error marker found in an immediately preceding comment,
- // and attach it to the outermost expression that starts at that token.
- if (comment != null) {
- while (comment.next != null) {
- comment = comment.next;
- }
- if (comment.end == token.offset && node.parent.beginToken != token) {
- var commentText = '$comment';
- var start = commentText.lastIndexOf('/*');
- var end = commentText.lastIndexOf('*/');
- if (start != -1 && end != -1) {
- expect(start, lessThan(end));
- var errors = commentText.substring(start + 2, end).split(',');
- var expectations =
- errors.map(_ErrorExpectation.parse).where((x) => x != null);
-
- for (var e in expectations) _expectError(node, e);
- }
- }
- }
- return super.visitNode(node);
- }
-
- void _expectError(AstNode node, _ErrorExpectation expected) {
- // See if we can find the expected error in our actual errors
- for (var actual in _actualErrors) {
- if (actual.offset == node.offset && actual.length == node.length) {
- var actualMsg = _formatActualError(actual);
- expect(_actualErrorLevel(actual), expected.level,
- reason: 'expected different error code at:\n\n$actualMsg');
- expect(errorCodeName(actual.errorCode), expected.typeName,
- reason: 'expected different error type at:\n\n$actualMsg');
-
- // We found it. Stop the search.
- _actualErrors.remove(actual);
- return;
- }
- }
-
- var span = _createSpan(node.offset, node.length);
- var levelName = expected.level.name.toLowerCase();
- var msg = span.message(expected.typeName, color: colorOf(levelName));
- fail('expected error was not reported at:\n\n$levelName: $msg');
- }
-
- Level _actualErrorLevel(AnalysisError actual) {
- return const <ErrorSeverity, Level>{
- ErrorSeverity.ERROR: Level.SEVERE,
- ErrorSeverity.WARNING: Level.WARNING,
- ErrorSeverity.INFO: Level.INFO
- }[actual.errorCode.errorSeverity];
- }
-
- String _formatActualError(AnalysisError actual) {
- var span = _createSpan(actual.offset, actual.length);
- var levelName = _actualErrorLevel(actual).name.toLowerCase();
- var msg = span.message(actual.message, color: colorOf(levelName));
- return '$levelName: [${errorCodeName(actual.errorCode)}] $msg';
- }
-
- SourceSpan _createSpan(int offset, int len) {
- return createSpanHelper(_unit.lineInfo, offset, offset + len,
- _unit.element.source, _unitSourceCode);
- }
-}
-
-SourceLocation locationForOffset(LineInfo lineInfo, Uri uri, int offset) {
- var loc = lineInfo.getLocation(offset);
- return new SourceLocation(offset,
- sourceUrl: uri, line: loc.lineNumber - 1, column: loc.columnNumber - 1);
-}
-
-SourceSpanWithContext createSpanHelper(
- LineInfo lineInfo, int start, int end, Source source, String content) {
- var startLoc = locationForOffset(lineInfo, source.uri, start);
- var endLoc = locationForOffset(lineInfo, source.uri, end);
-
- var lineStart = startLoc.offset - startLoc.column;
- // Find the end of the line. This is not exposed directly on LineInfo, but
- // we can find it pretty easily.
- // TODO(jmesserly): for now we do the simple linear scan. Ideally we can get
- // some help from the LineInfo API.
- int lineEnd = endLoc.offset;
- int lineNum = lineInfo.getLocation(lineEnd).lineNumber;
- while (lineEnd < content.length &&
- lineInfo.getLocation(++lineEnd).lineNumber == lineNum);
-
- var text = content.substring(start, end);
- var lineText = content.substring(lineStart, lineEnd);
- return new SourceSpanWithContext(startLoc, endLoc, text, lineText);
-}
-
-/// Describes an expected message that should be produced by the checker.
-class _ErrorExpectation {
- final Level level;
- final String typeName;
- _ErrorExpectation(this.level, this.typeName);
-
- static _ErrorExpectation _parse(String descriptor) {
- var tokens = descriptor.split(':');
- expect(tokens.length, 2, reason: 'invalid error descriptor');
- var name = tokens[0].toUpperCase();
- var typeName = tokens[1];
-
- var level =
- Level.LEVELS.firstWhere((l) => l.name == name, orElse: () => null);
- expect(level, isNotNull,
- reason: 'invalid level in error descriptor: `${tokens[0]}`');
- expect(typeName, isNotNull,
- reason: 'invalid type in error descriptor: ${tokens[1]}');
- return new _ErrorExpectation(level, typeName);
- }
-
- static _ErrorExpectation parse(String descriptor) {
- descriptor = descriptor.trim();
- var tokens = descriptor.split(' ');
- if (tokens.length == 1) return _parse(tokens[0]);
- expect(tokens.length, 4, reason: 'invalid error descriptor');
- expect(tokens[1], "should", reason: 'invalid error descriptor');
- expect(tokens[2], "be", reason: 'invalid error descriptor');
- if (tokens[0] == "pass") return null;
- // TODO(leafp) For now, we just use whatever the current expectation is,
- // eventually we could do more automated reporting here.
- return _parse(tokens[0]);
- }
-
- String toString() => '$level $typeName';
-}
-
-/// Dart SDK which contains a mock implementation of the SDK libraries. May be
-/// used to speed up execution when most of the core libraries is not needed.
-class MockDartSdk implements DartSdk {
- final Map<Uri, _MockSdkSource> _sources = {};
- final bool reportMissing;
- final Map<String, SdkLibrary> _libs = {};
- final String sdkVersion = '0';
- List<String> get uris => _sources.keys.map((uri) => '$uri').toList();
- final AnalysisContext context = new SdkAnalysisContext();
- DartUriResolver _resolver;
- DartUriResolver get resolver => _resolver;
-
- MockDartSdk(Map<String, String> sources, {this.reportMissing}) {
- sources.forEach((uriString, contents) {
- var uri = Uri.parse(uriString);
- _sources[uri] = new _MockSdkSource(uri, contents);
- _libs[uriString] = new SdkLibraryImpl(uri.path)
- ..setDart2JsLibrary()
- ..setVmLibrary();
- });
- _resolver = new DartUriResolver(this);
- context.sourceFactory = new SourceFactory([_resolver]);
- }
-
- List<SdkLibrary> get sdkLibraries => _libs.values.toList();
- SdkLibrary getSdkLibrary(String dartUri) => _libs[dartUri];
- Source mapDartUri(String dartUri) => _getSource(Uri.parse(dartUri));
-
- Source fromEncoding(UriKind kind, Uri uri) {
- if (kind != UriKind.DART_URI) {
- throw new UnsupportedError('expected dart: uri kind, got $kind.');
- }
- return _getSource(uri);
- }
-
- Source _getSource(Uri uri) {
- var src = _sources[uri];
- if (src == null) {
- if (reportMissing) print('warning: missing mock for $uri.');
- _sources[uri] =
- src = new _MockSdkSource(uri, 'library dart.${uri.path};');
- }
- return src;
- }
-
- @override
- Source fromFileUri(Uri uri) {
- throw new UnsupportedError('MockDartSdk.fromFileUri');
- }
-}
-
-class _MockSdkSource implements Source {
- /// Absolute URI which this source can be imported from.
- final Uri uri;
- final String _contents;
-
- _MockSdkSource(this.uri, this._contents);
-
- bool exists() => true;
-
- int get hashCode => uri.hashCode;
-
- final int modificationStamp = 1;
-
- TimestampedData<String> get contents =>
- new TimestampedData(modificationStamp, _contents);
-
- String get encoding => "${uriKind.encoding}$uri";
-
- Source get source => this;
-
- String get fullName => shortName;
-
- String get shortName => uri.path;
-
- UriKind get uriKind => UriKind.DART_URI;
-
- bool get isInSystemLibrary => true;
-
- Source resolveRelative(Uri relativeUri) =>
- throw new UnsupportedError('not expecting relative urls in dart: mocks');
-
- Uri resolveRelativeUri(Uri relativeUri) =>
- throw new UnsupportedError('not expecting relative urls in dart: mocks');
-}
-
-// TODO(jmesserly): can we reuse the same mock SDK as Analyzer tests?
/// Sample mock SDK sources.
final Map<String, String> mockSdkSources = {
// The list of types below is derived from:
@@ -466,6 +118,58 @@
''',
};
+/// Returns an ANSII color escape sequence corresponding to [levelName]. Colors
+/// are defined for: severe, error, warning, or info. Returns null if the level
+/// name is not recognized.
+String colorOf(String levelName) {
+ levelName = levelName.toLowerCase();
+ if (levelName == 'shout' || levelName == 'severe' || levelName == 'error') {
+ return _RED_COLOR;
+ }
+ if (levelName == 'warning') return _MAGENTA_COLOR;
+ if (levelName == 'info') return _CYAN_COLOR;
+ return null;
+}
+
+SourceSpanWithContext createSpanHelper(
+ LineInfo lineInfo, int start, int end, Source source, String content) {
+ var startLoc = locationForOffset(lineInfo, source.uri, start);
+ var endLoc = locationForOffset(lineInfo, source.uri, end);
+
+ var lineStart = startLoc.offset - startLoc.column;
+ // Find the end of the line. This is not exposed directly on LineInfo, but
+ // we can find it pretty easily.
+ // TODO(jmesserly): for now we do the simple linear scan. Ideally we can get
+ // some help from the LineInfo API.
+ int lineEnd = endLoc.offset;
+ int lineNum = lineInfo.getLocation(lineEnd).lineNumber;
+ while (lineEnd < content.length &&
+ lineInfo.getLocation(++lineEnd).lineNumber == lineNum);
+
+ var text = content.substring(start, end);
+ var lineText = content.substring(lineStart, lineEnd);
+ return new SourceSpanWithContext(startLoc, endLoc, text, lineText);
+}
+
+String errorCodeName(ErrorCode errorCode) {
+ var name = errorCode.name;
+ final prefix = 'STRONG_MODE_';
+ if (name.startsWith(prefix)) {
+ return name.substring(prefix.length);
+ } else {
+ // TODO(jmesserly): this is for backwards compat, but not sure it's very
+ // useful to log this.
+ return 'AnalyzerMessage';
+ }
+}
+
+// TODO(jmesserly): can we reuse the same mock SDK as Analyzer tests?
+SourceLocation locationForOffset(LineInfo lineInfo, Uri uri, int offset) {
+ var loc = lineInfo.getLocation(offset);
+ return new SourceLocation(offset,
+ sourceUrl: uri, line: loc.lineNumber - 1, column: loc.columnNumber - 1);
+}
+
/// Returns all libraries transitively imported or exported from [start].
List<LibraryElement> reachableLibraries(LibraryElement start) {
var results = <LibraryElement>[];
@@ -481,33 +185,339 @@
return results;
}
-String errorCodeName(ErrorCode errorCode) {
- var name = errorCode.name;
- final prefix = 'STRONG_MODE_';
- if (name.startsWith(prefix)) {
- return name.substring(prefix.length);
- } else {
- // TODO(jmesserly): this is for backwards compat, but not sure it's very
- // useful to log this.
- return 'AnalyzerMessage';
+/// Run the checker on a program with files contents as indicated in
+/// [testFiles].
+///
+/// This function makes several assumptions to make it easier to describe error
+/// expectations:
+///
+/// * a file named `/main.dart` exists in [testFiles].
+/// * all expected failures are listed in the source code using comments
+/// immediately in front of the AST node that should contain the error.
+/// * errors are formatted as a token `level:Type`, where `level` is the
+/// logging level were the error would be reported at, and `Type` is the
+/// concrete subclass of [StaticInfo] that denotes the error.
+///
+/// For example, to check that an assignment produces a warning about a boxing
+/// conversion, you can describe the test as follows:
+///
+/// testChecker({
+/// '/main.dart': '''
+/// testMethod() {
+/// dynamic x = /*warning:Box*/3;
+/// }
+/// '''
+/// });
+///
+void testChecker(String name, Map<String, String> testFiles) {
+ test(name, () {
+ AnalysisEngine.instance.processRequiredPlugins();
+ expect(testFiles.containsKey('/main.dart'), isTrue,
+ reason: '`/main.dart` is missing in testFiles');
+
+ var provider = new MemoryResourceProvider();
+ testFiles.forEach((key, value) {
+ var scheme = 'package:';
+ if (key.startsWith(scheme)) {
+ key = '/packages/${key.substring(scheme.length)}';
+ }
+ provider.newFile(key, value);
+ });
+ var uriResolver = new TestUriResolver(provider);
+ // Enable task model strong mode
+ var context = AnalysisEngine.instance.createAnalysisContext();
+ context.analysisOptions.strongMode = true;
+ context.analysisOptions.strongModeHints = true;
+
+ context.sourceFactory = new SourceFactory([
+ new MockDartSdk(mockSdkSources, reportMissing: true).resolver,
+ uriResolver
+ ]);
+
+ // Run the checker on /main.dart.
+ Source mainSource = uriResolver.resolveAbsolute(new Uri.file('/main.dart'));
+ var initialLibrary =
+ context.resolveCompilationUnit2(mainSource, mainSource);
+
+ var collector = new _ErrorCollector();
+ var checker = new CodeChecker(context.typeProvider,
+ new StrongTypeSystemImpl(), collector,
+ hints: true);
+
+ // Extract expectations from the comments in the test files, and
+ // check that all errors we emit are included in the expected map.
+ var allLibraries = reachableLibraries(initialLibrary.element.library);
+ for (var lib in allLibraries) {
+ for (var unit in lib.units) {
+ var errors = <AnalysisError>[];
+ collector.errors = errors;
+
+ var source = unit.source;
+ if (source.uri.scheme == 'dart') continue;
+
+ var librarySource = context.getLibrariesContaining(source).single;
+ var resolved = context.resolveCompilationUnit2(source, librarySource);
+ var analyzerErrors = context
+ .getErrors(source)
+ .errors
+ .where((error) =>
+ error.errorCode.name.startsWith('STRONG_MODE_INFERRED_TYPE'))
+ .toList();
+ errors.addAll(analyzerErrors);
+ checker.visitCompilationUnit(resolved);
+
+ new _ExpectedErrorVisitor(errors).validate(resolved);
+ }
+ }
+ });
+}
+
+/// Dart SDK which contains a mock implementation of the SDK libraries. May be
+/// used to speed up execution when most of the core libraries is not needed.
+class MockDartSdk implements DartSdk {
+ final Map<Uri, _MockSdkSource> _sources = {};
+ final bool reportMissing;
+ final Map<String, SdkLibrary> _libs = {};
+ final String sdkVersion = '0';
+ final AnalysisContext context = new SdkAnalysisContext();
+ DartUriResolver _resolver;
+ MockDartSdk(Map<String, String> sources, {this.reportMissing}) {
+ sources.forEach((uriString, contents) {
+ var uri = Uri.parse(uriString);
+ _sources[uri] = new _MockSdkSource(uri, contents);
+ _libs[uriString] = new SdkLibraryImpl(uri.path)
+ ..setDart2JsLibrary()
+ ..setVmLibrary();
+ });
+ _resolver = new DartUriResolver(this);
+ context.sourceFactory = new SourceFactory([_resolver]);
+ }
+ DartUriResolver get resolver => _resolver;
+
+ List<SdkLibrary> get sdkLibraries => _libs.values.toList();
+
+ List<String> get uris => _sources.keys.map((uri) => '$uri').toList();
+ Source fromEncoding(UriKind kind, Uri uri) {
+ if (kind != UriKind.DART_URI) {
+ throw new UnsupportedError('expected dart: uri kind, got $kind.');
+ }
+ return _getSource(uri);
+ }
+
+ @override
+ Source fromFileUri(Uri uri) {
+ throw new UnsupportedError('MockDartSdk.fromFileUri');
+ }
+
+ SdkLibrary getSdkLibrary(String dartUri) => _libs[dartUri];
+
+ Source mapDartUri(String dartUri) => _getSource(Uri.parse(dartUri));
+
+ Source _getSource(Uri uri) {
+ var src = _sources[uri];
+ if (src == null) {
+ if (reportMissing) print('warning: missing mock for $uri.');
+ _sources[uri] =
+ src = new _MockSdkSource(uri, 'library dart.${uri.path};');
+ }
+ return src;
}
}
-/// Returns an ANSII color escape sequence corresponding to [levelName]. Colors
-/// are defined for: severe, error, warning, or info. Returns null if the level
-/// name is not recognized.
-String colorOf(String levelName) {
- levelName = levelName.toLowerCase();
- if (levelName == 'shout' || levelName == 'severe' || levelName == 'error') {
- return _RED_COLOR;
+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('/packages/' + uri.path) as File)
+ .createSource(uri);
+ }
+ return super.resolveAbsolute(uri, actualUri);
}
- if (levelName == 'warning') return _MAGENTA_COLOR;
- if (levelName == 'info') return _CYAN_COLOR;
- return null;
}
-const String _RED_COLOR = '\u001b[31m';
-const String _MAGENTA_COLOR = '\u001b[35m';
-const String _CYAN_COLOR = '\u001b[36m';
-const String GREEN_COLOR = '\u001b[32m';
-const String NO_COLOR = '\u001b[0m';
+class _ErrorCollector implements AnalysisErrorListener {
+ List<AnalysisError> errors;
+ final bool hints;
+ _ErrorCollector({this.hints: true});
+
+ void onError(AnalysisError error) {
+ // Unless DDC hints are requested, filter them out.
+ var HINT = ErrorSeverity.INFO.ordinal;
+ if (hints || error.errorCode.errorSeverity.ordinal > HINT) {
+ errors.add(error);
+ }
+ }
+}
+
+/// Describes an expected message that should be produced by the checker.
+class _ErrorExpectation {
+ final Level level;
+ final String typeName;
+ _ErrorExpectation(this.level, this.typeName);
+
+ String toString() => '$level $typeName';
+
+ static _ErrorExpectation parse(String descriptor) {
+ descriptor = descriptor.trim();
+ var tokens = descriptor.split(' ');
+ if (tokens.length == 1) return _parse(tokens[0]);
+ expect(tokens.length, 4, reason: 'invalid error descriptor');
+ expect(tokens[1], "should", reason: 'invalid error descriptor');
+ expect(tokens[2], "be", reason: 'invalid error descriptor');
+ if (tokens[0] == "pass") return null;
+ // TODO(leafp) For now, we just use whatever the current expectation is,
+ // eventually we could do more automated reporting here.
+ return _parse(tokens[0]);
+ }
+
+ static _ErrorExpectation _parse(String descriptor) {
+ var tokens = descriptor.split(':');
+ expect(tokens.length, 2, reason: 'invalid error descriptor');
+ var name = tokens[0].toUpperCase();
+ var typeName = tokens[1];
+
+ var level =
+ Level.LEVELS.firstWhere((l) => l.name == name, orElse: () => null);
+ expect(level, isNotNull,
+ reason: 'invalid level in error descriptor: `${tokens[0]}`');
+ expect(typeName, isNotNull,
+ reason: 'invalid type in error descriptor: ${tokens[1]}');
+ return new _ErrorExpectation(level, typeName);
+ }
+}
+
+class _ExpectedErrorVisitor extends UnifyingAstVisitor {
+ final Set<AnalysisError> _actualErrors;
+ CompilationUnit _unit;
+ String _unitSourceCode;
+
+ _ExpectedErrorVisitor(List<AnalysisError> actualErrors)
+ : _actualErrors = new Set.from(actualErrors);
+
+ validate(CompilationUnit unit) {
+ _unit = unit;
+ // This reads the file. Only safe because tests use MemoryFileSystem.
+ _unitSourceCode = unit.element.source.contents.data;
+
+ // Visit the compilation unit.
+ unit.accept(this);
+
+ if (_actualErrors.isNotEmpty) {
+ var actualMsgs = _actualErrors.map(_formatActualError).join('\n');
+ fail('Unexpected errors reported by checker:\n\n$actualMsgs');
+ }
+ }
+
+ visitNode(AstNode node) {
+ var token = node.beginToken;
+ var comment = token.precedingComments;
+ // Use error marker found in an immediately preceding comment,
+ // and attach it to the outermost expression that starts at that token.
+ if (comment != null) {
+ while (comment.next != null) {
+ comment = comment.next;
+ }
+ if (comment.end == token.offset && node.parent.beginToken != token) {
+ var commentText = '$comment';
+ var start = commentText.lastIndexOf('/*');
+ var end = commentText.lastIndexOf('*/');
+ if (start != -1 &&
+ end != -1 &&
+ !commentText.startsWith('/*<', start) &&
+ !commentText.startsWith('/*=', start)) {
+ expect(start, lessThan(end));
+ var errors = commentText.substring(start + 2, end).split(',');
+ var expectations =
+ errors.map(_ErrorExpectation.parse).where((x) => x != null);
+
+ for (var e in expectations) {
+ _expectError(node, e);
+ }
+ }
+ }
+ }
+ return super.visitNode(node);
+ }
+
+ Level _actualErrorLevel(AnalysisError actual) {
+ return const <ErrorSeverity, Level>{
+ ErrorSeverity.ERROR: Level.SEVERE,
+ ErrorSeverity.WARNING: Level.WARNING,
+ ErrorSeverity.INFO: Level.INFO
+ }[actual.errorCode.errorSeverity];
+ }
+
+ SourceSpan _createSpan(int offset, int len) {
+ return createSpanHelper(_unit.lineInfo, offset, offset + len,
+ _unit.element.source, _unitSourceCode);
+ }
+
+ void _expectError(AstNode node, _ErrorExpectation expected) {
+ // See if we can find the expected error in our actual errors
+ for (var actual in _actualErrors) {
+ if (actual.offset == node.offset && actual.length == node.length) {
+ var actualMsg = _formatActualError(actual);
+ expect(_actualErrorLevel(actual), expected.level,
+ reason: 'expected different error code at:\n\n$actualMsg');
+ expect(errorCodeName(actual.errorCode), expected.typeName,
+ reason: 'expected different error type at:\n\n$actualMsg');
+
+ // We found it. Stop the search.
+ _actualErrors.remove(actual);
+ return;
+ }
+ }
+
+ var span = _createSpan(node.offset, node.length);
+ var levelName = expected.level.name.toLowerCase();
+ var msg = span.message(expected.typeName, color: colorOf(levelName));
+ fail('expected error was not reported at:\n\n$levelName: $msg');
+ }
+
+ String _formatActualError(AnalysisError actual) {
+ var span = _createSpan(actual.offset, actual.length);
+ var levelName = _actualErrorLevel(actual).name.toLowerCase();
+ var msg = span.message(actual.message, color: colorOf(levelName));
+ return '$levelName: [${errorCodeName(actual.errorCode)}] $msg';
+ }
+}
+
+class _MockSdkSource implements Source {
+ /// Absolute URI which this source can be imported from.
+ final Uri uri;
+ final String _contents;
+
+ final int modificationStamp = 1;
+
+ _MockSdkSource(this.uri, this._contents);
+
+ TimestampedData<String> get contents =>
+ new TimestampedData(modificationStamp, _contents);
+
+ String get encoding => "${uriKind.encoding}$uri";
+
+ String get fullName => shortName;
+
+ int get hashCode => uri.hashCode;
+
+ bool get isInSystemLibrary => true;
+
+ String get shortName => uri.path;
+
+ Source get source => this;
+
+ UriKind get uriKind => UriKind.DART_URI;
+
+ bool exists() => true;
+
+ Source resolveRelative(Uri relativeUri) =>
+ throw new UnsupportedError('not expecting relative urls in dart: mocks');
+
+ Uri resolveRelativeUri(Uri relativeUri) =>
+ throw new UnsupportedError('not expecting relative urls in dart: mocks');
+}
diff --git a/pkg/analyzer/test/src/task/strong_mode_test.dart b/pkg/analyzer/test/src/task/strong_mode_test.dart
index ff87d92..64db1a5 100644
--- a/pkg/analyzer/test/src/task/strong_mode_test.dart
+++ b/pkg/analyzer/test/src/task/strong_mode_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.task.strong_mode_test;
+library analyzer.test.src.task.strong_mode_test;
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
diff --git a/pkg/analyzer/test/src/task/test_all.dart b/pkg/analyzer/test/src/task/test_all.dart
index ffe976c..41e568e 100644
--- a/pkg/analyzer/test/src/task/test_all.dart
+++ b/pkg/analyzer/test/src/task/test_all.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.task.test_all;
+library analyzer.test.src.task.test_all;
import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/src/task/test_support.dart b/pkg/analyzer/test/src/task/test_support.dart
index e68952b..6db9c95 100644
--- a/pkg/analyzer/test/src/task/test_support.dart
+++ b/pkg/analyzer/test/src/task/test_support.dart
@@ -2,9 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.task.test_support;
+library analyzer.test.src.task.test_support;
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/task/model.dart';
diff --git a/pkg/analyzer/test/src/test_all.dart b/pkg/analyzer/test/src/test_all.dart
index f9ad08a..b97bc81 100644
--- a/pkg/analyzer/test/src/test_all.dart
+++ b/pkg/analyzer/test/src/test_all.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.test_all;
+library analyzer.test.src.test_all;
import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/src/util/absolute_path_test.dart b/pkg/analyzer/test/src/util/absolute_path_test.dart
index 0f195c2..98b38c5 100644
--- a/pkg/analyzer/test/src/util/absolute_path_test.dart
+++ b/pkg/analyzer/test/src/util/absolute_path_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.analyzer.src.util.absolute_path;
+library analyzer.test.src.util.absolute_path_test;
import 'package:analyzer/src/util/absolute_path.dart';
import 'package:unittest/unittest.dart';
@@ -18,7 +18,7 @@
@reflectiveTest
class AbsolutePathContextPosixTest {
- AbsolutePathContext context = new AbsolutePathContext(r'/');
+ AbsolutePathContext context = new AbsolutePathContext(false);
void test_append() {
expect(context.append(r'/path/to', r'foo.dart'), r'/path/to/foo.dart');
@@ -38,6 +38,28 @@
expect(context.dirname(r'/'), r'/');
}
+ void test_isValid_absolute() {
+ expect(context.isValid(r'/foo/bar'), isTrue);
+ expect(context.isValid(r'/foo'), isTrue);
+ expect(context.isValid(r'/'), isTrue);
+ expect(context.isValid(r''), isFalse);
+ expect(context.isValid(r'foo/bar'), isFalse);
+ }
+
+ void test_isValid_normalized() {
+ expect(context.isValid(r'/foo/bar'), isTrue);
+ expect(context.isValid(r'/foo/..bar'), isTrue);
+ expect(context.isValid(r'/foo/.bar/baz'), isTrue);
+ expect(context.isValid(r'/foo/...'), isTrue);
+ expect(context.isValid(r'/foo/bar..'), isTrue);
+ expect(context.isValid(r'/foo/.../bar'), isTrue);
+ expect(context.isValid(r'/foo/.bar/.'), isFalse);
+ expect(context.isValid(r'/foo/bar/../baz'), isFalse);
+ expect(context.isValid(r'/foo/bar/..'), isFalse);
+ expect(context.isValid(r'/foo/./bar'), isFalse);
+ expect(context.isValid(r'/.'), isFalse);
+ }
+
void test_isWithin() {
expect(context.isWithin(r'/root/path', r'/root/path/a'), isTrue);
expect(context.isWithin(r'/root/path', r'/root/other'), isFalse);
@@ -57,7 +79,7 @@
@reflectiveTest
class AbsolutePathContextWindowsTest {
- AbsolutePathContext context = new AbsolutePathContext(r'\');
+ AbsolutePathContext context = new AbsolutePathContext(true);
void test_append() {
expect(context.append(r'C:\path\to', r'foo.dart'), r'C:\path\to\foo.dart');
@@ -77,6 +99,30 @@
expect(context.dirname(r'C:\'), r'C:\');
}
+ void test_isValid_absolute() {
+ expect(context.isValid(r'C:\foo\bar'), isTrue);
+ expect(context.isValid(r'c:\foo\bar'), isTrue);
+ expect(context.isValid(r'D:\foo\bar'), isTrue);
+ expect(context.isValid(r'C:\foo'), isTrue);
+ expect(context.isValid(r'C:\'), isTrue);
+ expect(context.isValid(r''), isFalse);
+ expect(context.isValid(r'foo\bar'), isFalse);
+ }
+
+ void test_isValid_normalized() {
+ expect(context.isValid(r'C:\foo\bar'), isTrue);
+ expect(context.isValid(r'C:\foo\..bar'), isTrue);
+ expect(context.isValid(r'C:\foo\.bar\baz'), isTrue);
+ expect(context.isValid(r'C:\foo\...'), isTrue);
+ expect(context.isValid(r'C:\foo\bar..'), isTrue);
+ expect(context.isValid(r'C:\foo\...\bar'), isTrue);
+ expect(context.isValid(r'C:\foo\.bar\.'), isFalse);
+ expect(context.isValid(r'C:\foo\bar\..\baz'), isFalse);
+ expect(context.isValid(r'C:\foo\bar\..'), isFalse);
+ expect(context.isValid(r'C:\foo\.\bar'), isFalse);
+ expect(context.isValid(r'C:\.'), isFalse);
+ }
+
void test_isWithin() {
expect(context.isWithin(r'C:\root\path', r'C:\root\path\a'), isTrue);
expect(context.isWithin(r'C:\root\path', r'C:\root\other'), isFalse);
diff --git a/pkg/analyzer/test/src/util/asserts_test.dart b/pkg/analyzer/test/src/util/asserts_test.dart
index a504e43..a3587d3 100644
--- a/pkg/analyzer/test/src/util/asserts_test.dart
+++ b/pkg/analyzer/test/src/util/asserts_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.util.asserts;
+library analyzer.test.src.util.asserts_test;
import 'package:analyzer/src/util/asserts.dart';
import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/src/util/glob_test.dart b/pkg/analyzer/test/src/util/glob_test.dart
index 8ebc04f..c27ff7e 100644
--- a/pkg/analyzer/test/src/util/glob_test.dart
+++ b/pkg/analyzer/test/src/util/glob_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.analyzer.src.util.glob;
+library analyzer.test.src.util.glob_test;
import 'package:analyzer/src/util/glob.dart';
import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/src/util/lru_map_test.dart b/pkg/analyzer/test/src/util/lru_map_test.dart
index ef580a0..f460b10 100644
--- a/pkg/analyzer/test/src/util/lru_map_test.dart
+++ b/pkg/analyzer/test/src/util/lru_map_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.util.lru_map;
+library analyzer.test.src.util.lru_map_test;
import 'package:analyzer/src/util/lru_map.dart';
import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/src/util/test_all.dart b/pkg/analyzer/test/src/util/test_all.dart
index 6d44df6..d992264 100644
--- a/pkg/analyzer/test/src/util/test_all.dart
+++ b/pkg/analyzer/test/src/util/test_all.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.src.util;
+library analyzer.test.src.util.test_all;
import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/src/util/yaml_test.dart b/pkg/analyzer/test/src/util/yaml_test.dart
index 6cf00cc..feb812b 100644
--- a/pkg/analyzer/test/src/util/yaml_test.dart
+++ b/pkg/analyzer/test/src/util/yaml_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.util.yaml;
+library analyzer.src.test.util.yaml_test;
import 'package:analyzer/src/util/yaml.dart';
import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/test_all.dart b/pkg/analyzer/test/test_all.dart
index c21cc3f..8155789 100644
--- a/pkg/analyzer/test/test_all.dart
+++ b/pkg/analyzer/test/test_all.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.engine;
+library analyzer.test.test_all;
import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/tool/task_dependency_graph/check_test.dart b/pkg/analyzer/tool/task_dependency_graph/check_test.dart
index 3d64a85..c689d63 100644
--- a/pkg/analyzer/tool/task_dependency_graph/check_test.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/check_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library task_dependency_graph.check_test;
+library analyzer.tool.task_dependency_graph.check_test;
import 'dart:io';
diff --git a/pkg/analyzer/tool/task_dependency_graph/generate.dart b/pkg/analyzer/tool/task_dependency_graph/generate.dart
index daac102..2886352 100644
--- a/pkg/analyzer/tool/task_dependency_graph/generate.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/generate.dart
@@ -15,7 +15,7 @@
* of exactly one task.
* - Convert this tool to use package_config to find the package map.
*/
-library task_dependency_graph.generate;
+library analyzer.tool.task_dependency_graph.generate;
import 'dart:io' hide File;
import 'dart:io' as io;
@@ -120,6 +120,7 @@
* Generate the task dependency graph and return it as a [String].
*/
String generateFileContents() {
+ AnalysisEngine.instance.processRequiredPlugins();
List<String> lines = <String>[];
resourceProvider = PhysicalResourceProvider.INSTANCE;
DartSdk sdk = DirectoryBasedDartSdk.defaultSdk;
diff --git a/pkg/analyzer_cli/README.md b/pkg/analyzer_cli/README.md
index 1652184..947e730 100644
--- a/pkg/analyzer_cli/README.md
+++ b/pkg/analyzer_cli/README.md
@@ -6,10 +6,6 @@
DartPad, code editors, and IDEs such as WebStorm use the same
analysis engine that dartanalyzer uses.
-If you want to _contribute_ to the dartanalyzer project, see the
-[contributor docs](https://github.com/dart-lang/analyzer_cli/blob/master/CONTRIBUTOR.md).
-This page contains information about _using_ the dartanalyzer command-line tool.
-
## Basic usage
Run the analyzer from the top directory of the package.
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index 32d5f37..e48d78c 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -20,11 +20,11 @@
import 'package:analyzer_cli/src/error_formatter.dart';
import 'package:analyzer_cli/src/options.dart';
-DirectoryBasedDartSdk sdk;
-
/// The maximum number of sources for which AST structures should be kept in the cache.
const int _maxCacheSize = 512;
+DirectoryBasedDartSdk sdk;
+
int currentTimeMillis() => new DateTime.now().millisecondsSinceEpoch;
/// Analyzes single library [File].
@@ -278,26 +278,10 @@
}
@override
- void logError2(String message, Object exception) {
- errorSink.writeln(message);
- if (exception != null) {
- errorSink.writeln(exception.toString());
- }
- }
-
- @override
void logInformation(String message, [CaughtException exception]) {
outSink.writeln(message);
if (exception != null) {
outSink.writeln(exception);
}
}
-
- @override
- void logInformation2(String message, Object exception) {
- outSink.writeln(message);
- if (exception != null) {
- outSink.writeln(exception.toString());
- }
- }
}
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 752cb1e..f69e935 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -35,6 +35,7 @@
import 'package:package_config/packages_file.dart' as pkgfile show parse;
import 'package:package_config/src/packages_impl.dart' show MapPackages;
import 'package:path/path.dart' as path;
+import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
import 'package:yaml/yaml.dart';
@@ -500,12 +501,14 @@
void _processPlugins() {
List<Plugin> plugins = <Plugin>[];
+ plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+ plugins.add(AnalysisEngine.instance.commandLinePlugin);
+ plugins.add(AnalysisEngine.instance.optionsPlugin);
plugins.add(linterPlugin);
plugins.addAll(_userDefinedPlugins);
- AnalysisEngine.instance.userDefinedPlugins = plugins;
- // This ensures that AE extension manager processes plugins.
- AnalysisEngine.instance.taskManager;
+ ExtensionManager manager = new ExtensionManager();
+ manager.processPlugins(plugins);
}
/// Analyze a single source.
diff --git a/pkg/analyzer_cli/test/all.dart b/pkg/analyzer_cli/test/all.dart
index 5b08f58..03f1b14 100644
--- a/pkg/analyzer_cli/test/all.dart
+++ b/pkg/analyzer_cli/test/all.dart
@@ -2,14 +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 'driver_test.dart' as driver;
import 'error_test.dart' as error;
import 'options_test.dart' as options;
import 'plugin_manager_test.dart' as plugin_manager;
import 'reporter_test.dart' as reporter;
-import 'sdk_ext_test.dart' as sdk_ext;
-import 'strong_mode_test.dart' as strong_mode;
import 'super_mixin_test.dart' as super_mixin;
+//import 'driver_test.dart' as driver;
+//import 'sdk_ext_test.dart' as sdk_ext;
+//import 'strong_mode_test.dart' as strong_mode;
main() {
// TODO(pq): fix tests to run safely on the bots
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index f313355..e6bd812 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -24,7 +24,18 @@
// TODO(pq): fix tests to run safely on the bots
// https://github.com/dart-lang/sdk/issues/25001
main() {}
-_main() {
+const emptyOptionsFile = 'test/data/empty_options.yaml';
+
+/// Start a driver for the given [source], optionally providing additional
+/// [args] and an [options] file path. The value of [options] defaults to
+/// an empty options file to avoid unwanted configuration from an otherwise
+/// discovered options file.
+void drive(String source,
+ {String options: emptyOptionsFile,
+ List<String> args: const <String>[]}) =>
+ new Driver().start(['--options', options, source]..addAll(args));
+
+not_main() {
group('Driver', () {
StringSink savedOutSink, savedErrorSink;
int savedExitCode;
@@ -286,15 +297,18 @@
});
test('filters', () {
- var filters =
- driver.context.getConfigurationData(CONFIGURED_ERROR_FILTERS);
- expect(filters, hasLength(1));
+ var processors =
+ driver.context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+ expect(processors, hasLength(1));
- var unused_error = new AnalysisError(
+ var unused_local_variable = new AnalysisError(
new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
['x']
]);
- expect(filters.any((filter) => filter(unused_error)), isTrue);
+
+ var unusedLocalVariable =
+ processors.firstWhere((p) => p.appliesTo(unused_local_variable));
+ expect(unusedLocalVariable.severity, isNull);
});
test('language config', () {
@@ -430,17 +444,6 @@
});
}
-const emptyOptionsFile = 'test/data/empty_options.yaml';
-
-/// Start a driver for the given [source], optionally providing additional
-/// [args] and an [options] file path. The value of [options] defaults to
-/// an empty options file to avoid unwanted configuration from an otherwise
-/// discovered options file.
-void drive(String source,
- {String options: emptyOptionsFile,
- List<String> args: const <String>[]}) =>
- new Driver().start(['--options', options, source]..addAll(args));
-
Map<String, YamlNode> parseOptions(String src) =>
new AnalysisOptionsProvider().getOptionsFromString(src);
diff --git a/pkg/analyzer_cli/test/mocks.dart b/pkg/analyzer_cli/test/mocks.dart
index 794521c..7a62bda 100644
--- a/pkg/analyzer_cli/test/mocks.dart
+++ b/pkg/analyzer_cli/test/mocks.dart
@@ -10,42 +10,18 @@
import 'package:analyzer_cli/src/options.dart';
import 'package:typed_mock/typed_mock.dart';
-class MockAnalysisError extends TypedMock implements AnalysisError {
- @override
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockAnalysisError extends TypedMock implements AnalysisError {}
-class MockAnalysisErrorInfo extends TypedMock implements AnalysisErrorInfo {
- @override
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockAnalysisErrorInfo extends TypedMock implements AnalysisErrorInfo {}
-class MockCommandLineOptions extends TypedMock implements CommandLineOptions {
- @override
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockCommandLineOptions extends TypedMock implements CommandLineOptions {}
-class MockErrorCode extends TypedMock implements ErrorCode {
- @override
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockErrorCode extends TypedMock implements ErrorCode {}
-class MockErrorType extends TypedMock implements ErrorType {
- @override
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockErrorType extends TypedMock implements ErrorType {}
-class MockLineInfo extends TypedMock implements LineInfo {
- @override
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockLineInfo extends TypedMock implements LineInfo {}
-class MockLineInfo_Location extends TypedMock implements LineInfo_Location {
- @override
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockLineInfo_Location extends TypedMock implements LineInfo_Location {}
-class MockSource extends TypedMock implements Source {
- @override
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockSource extends TypedMock implements Source {}
diff --git a/pkg/analyzer_cli/test/sdk_ext_test.dart b/pkg/analyzer_cli/test/sdk_ext_test.dart
index 6aa793d..e7aa5ce 100644
--- a/pkg/analyzer_cli/test/sdk_ext_test.dart
+++ b/pkg/analyzer_cli/test/sdk_ext_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.
-
/// Test that sdk extensions are properly detected in various scenarios.
library analyzer_cli.test.sdk_ext;
@@ -17,7 +16,7 @@
// TODO(pq): fix tests to run safely on the bots
// https://github.com/dart-lang/sdk/issues/25001
main() {}
-_main() {
+not_main() {
group('Sdk extensions', () {
StringSink savedOutSink, savedErrorSink;
int savedExitCode;
diff --git a/pkg/analyzer_cli/test/strong_mode_test.dart b/pkg/analyzer_cli/test/strong_mode_test.dart
index 763205a..7060fa8 100644
--- a/pkg/analyzer_cli/test/strong_mode_test.dart
+++ b/pkg/analyzer_cli/test/strong_mode_test.dart
@@ -23,8 +23,8 @@
///
// TODO(pq): fix tests to run safely on the bots
// https://github.com/dart-lang/sdk/issues/25001
-main () {}
-_main() {
+main() {}
+not_main() {
group('--strong', () {
StringSink savedOutSink, savedErrorSink;
int savedExitCode;
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index 556006a..71a2d67 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -116,6 +116,8 @@
useContentSecurityPolicy:
hasOption(options, Flags.useContentSecurityPolicy),
useStartupEmitter: hasOption(options, Flags.fastStartup),
+ enableConditionalDirectives:
+ hasOption(options, Flags.conditionalDirectives),
hasIncrementalSupport:
forceIncrementalSupport ||
hasOption(options, Flags.incrementalSupport),
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 03f274e..f200ebc 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -46,4 +46,7 @@
static const String useCpsIr = '--use-cps-ir';
static const String verbose = '--verbose';
static const String version = '--version';
+
+ // Experimental flags.
+ static const String conditionalDirectives = '--conditional-directives';
}
diff --git a/pkg/compiler/lib/src/common/names.dart b/pkg/compiler/lib/src/common/names.dart
index 79389f5..27b844f 100644
--- a/pkg/compiler/lib/src/common/names.dart
+++ b/pkg/compiler/lib/src/common/names.dart
@@ -112,13 +112,15 @@
static final Selector codeUnitAt =
new Selector.call(const PublicName('codeUnitAt'), CallStructure.ONE_ARG);
+ static final Selector index = new Selector.index();
+
/// List of all the selectors held in static fields.
///
/// These objects are shared between different runs in batch-mode and must
/// thus remain in the [Selector.canonicalizedValues] map.
static final List<Selector> ALL = <Selector>[
cancel, current, iterator, moveNext, noSuchMethod_, toString_,
- hashCode_, compareTo, equals, length, codeUnitAt];
+ hashCode_, compareTo, equals, length, codeUnitAt, index];
}
/// [Uri]s commonly used.
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index fa655c5..3b98b92 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -454,6 +454,7 @@
this.deferredMapUri: null,
this.dumpInfo: false,
bool useStartupEmitter: false,
+ bool enableConditionalDirectives: false,
this.useContentSecurityPolicy: false,
bool hasIncrementalSupport: false,
this.enableExperimentalMirrors: false,
@@ -515,9 +516,12 @@
libraryLoader = new LibraryLoaderTask(this),
serialization = new SerializationTask(this),
scanner = new ScannerTask(this),
- dietParser = new DietParserTask(this),
- parser = new ParserTask(this),
- patchParser = new PatchParserTask(this),
+ dietParser = new DietParserTask(
+ this, enableConditionalDirectives: enableConditionalDirectives),
+ parser = new ParserTask(
+ this, enableConditionalDirectives: enableConditionalDirectives),
+ patchParser = new PatchParserTask(
+ this, enableConditionalDirectives: enableConditionalDirectives),
resolver = new ResolverTask(this, backend.constantCompilerTask),
closureToClassMapper = new closureMapping.ClosureTask(this),
checker = new TypeCheckerTask(this),
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
index 2a7c5c4..945aaba 100644
--- a/pkg/compiler/lib/src/constants/values.dart
+++ b/pkg/compiler/lib/src/constants/values.dart
@@ -502,6 +502,7 @@
final List<ConstantValue> keys;
final List<ConstantValue> values;
final int hashCode;
+ Map<ConstantValue, ConstantValue> _lookupMap;
MapConstantValue(InterfaceType type,
List<ConstantValue> keys,
@@ -539,6 +540,12 @@
int get length => keys.length;
+ ConstantValue lookup(ConstantValue key) {
+ var lookupMap = _lookupMap ??=
+ new Map<ConstantValue, ConstantValue>.fromIterables(keys, values);
+ return lookupMap[key];
+ }
+
accept(ConstantValueVisitor visitor, arg) => visitor.visitMap(this, arg);
String unparse() {
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
index b75af81..a80f2f7 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -702,6 +702,19 @@
target, selector, mask, arguments, sourceInformation);
}
+ ir.Primitive buildStaticNoSuchMethod(Selector selector,
+ List<ir.Primitive> arguments) {
+ Element thrower = program.throwNoSuchMethod;
+ ir.Primitive receiver = buildStringConstant('');
+ ir.Primitive name = buildStringConstant(selector.name);
+ ir.Primitive argumentList = buildListLiteral(null, arguments);
+ ir.Primitive expectedArgumentNames = buildNullConstant();
+ return buildStaticFunctionInvocation(
+ thrower,
+ new CallStructure.unnamed(4),
+ [receiver, name, argumentList, expectedArgumentNames]);
+ }
+
/// Create a [ir.Constant] from [value] and add it to the CPS term.
ir.Constant buildConstant(ConstantValue value,
@@ -1433,11 +1446,18 @@
// TODO(johnniwinther): Extract this as a provided strategy.
if (Elements.isLocal(variableElement)) {
bodyBuilder.buildLocalVariableSet(variableElement, currentValue);
- } else if (Elements.isMalformed(variableElement)) {
- bodyBuilder.buildErroneousInvocation(variableElement,
- new Selector.setter(
- new Name(variableElement.name, variableElement.library)),
- <ir.Primitive>[currentValue]);
+ } else if (Elements.isError(variableElement) ||
+ Elements.isMalformed(variableElement)) {
+ Selector selector = new Selector.setter(
+ new Name(variableElement.name, variableElement.library));
+ List<ir.Primitive> value = <ir.Primitive>[currentValue];
+ // Note the order of the comparisons below. It can be the case that an
+ // element isError and isMalformed.
+ if (Elements.isError(variableElement)) {
+ bodyBuilder.buildStaticNoSuchMethod(selector, value);
+ } else {
+ bodyBuilder.buildErroneousInvocation(variableElement, selector, value);
+ }
} else if (Elements.isStaticOrTopLevel(variableElement)) {
if (variableElement.isField) {
bodyBuilder.buildStaticFieldSet(variableElement, currentValue);
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
index 829f942..e4fb1fd 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
@@ -185,25 +185,25 @@
ClosureScope getClosureScopeForNode(ast.Node node);
ClosureEnvironment getClosureEnvironment();
- /// Normalizes the argument list to a static invocation (i.e. where the target
- /// element is known).
+ /// Normalizes the argument list of a static invocation.
///
- /// For the JS backend, inserts default arguments and normalizes order of
- /// named arguments.
- ///
- /// For the Dart backend, returns [arguments].
- List<ir.Primitive> normalizeStaticArguments(
+ /// A static invocation is one where the target is known. The argument list
+ /// [arguments] is normalized by adding default values for optional arguments
+ /// that are not passed, and by sorting it in place so that named arguments
+ /// appear in a canonical order. A [CallStructure] reflecting this order
+ /// is returned.
+ CallStructure normalizeStaticArguments(
CallStructure callStructure,
FunctionElement target,
List<ir.Primitive> arguments);
- /// Normalizes the argument list of a dynamic invocation (i.e. where the
- /// target element is unknown).
+ /// Normalizes the argument list of a dynamic invocation.
///
- /// For the JS backend, normalizes order of named arguments.
- ///
- /// For the Dart backend, returns [arguments].
- List<ir.Primitive> normalizeDynamicArguments(
+ /// A dynamic invocation is one where the target is not known. The argument
+ /// list [arguments] is normalized by sorting it in place so that the named
+ /// arguments appear in a canonical order. A [CallStructure] reflecting this
+ /// order is returned.
+ CallStructure normalizeDynamicArguments(
CallStructure callStructure,
List<ir.Primitive> arguments);
@@ -316,8 +316,8 @@
CallStructure callStructure = new CallStructure(
redirectingSignature.parameterCount,
namedParameters);
- arguments = normalizeStaticArguments(callStructure, targetConstructor,
- arguments);
+ callStructure =
+ normalizeStaticArguments(callStructure, targetConstructor, arguments);
ir.Primitive instance = irBuilder.buildConstructorInvocation(
targetConstructor,
callStructure,
@@ -719,10 +719,9 @@
ast.NodeList argumentsNode,
CallStructure callStructure, _) {
ir.Primitive receiver = visit(expression);
- List<ir.Primitive> arguments = node.arguments.mapToList(visit);
- arguments = normalizeDynamicArguments(callStructure, arguments);
- return irBuilder.buildCallInvocation(
- receiver, callStructure, arguments,
+ List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
+ callStructure = normalizeDynamicArguments(callStructure, arguments);
+ return irBuilder.buildCallInvocation(receiver, callStructure, arguments,
sourceInformation:
sourceInformationBuilder.buildCall(node, argumentsNode));
}
@@ -950,12 +949,16 @@
ast.Node left,
op.BinaryOperator operator,
ast.Node right) {
- Selector selector = new Selector.binaryOperator(operator.selectorName);
ir.Primitive receiver = visit(left);
+ Selector selector = new Selector.binaryOperator(operator.selectorName);
List<ir.Primitive> arguments = <ir.Primitive>[visit(right)];
- arguments = normalizeDynamicArguments(selector.callStructure, arguments);
+ CallStructure callStructure =
+ normalizeDynamicArguments(selector.callStructure, arguments);
return irBuilder.buildDynamicInvocation(
- receiver, selector, elements.getTypeMask(node), arguments,
+ receiver,
+ new Selector(selector.kind, selector.memberName, callStructure),
+ elements.getTypeMask(node),
+ arguments,
sourceInformation:
sourceInformationBuilder.buildCall(node, node.selector));
}
@@ -972,12 +975,16 @@
ir.Primitive visitIndex(ast.Send node,
ast.Node receiver,
ast.Node index, _) {
- Selector selector = new Selector.index();
ir.Primitive target = visit(receiver);
+ Selector selector = new Selector.index();
List<ir.Primitive> arguments = <ir.Primitive>[visit(index)];
- arguments = normalizeDynamicArguments(selector.callStructure, arguments);
+ CallStructure callStructure =
+ normalizeDynamicArguments(selector.callStructure, arguments);
return irBuilder.buildDynamicInvocation(
- target, selector, elements.getTypeMask(node), arguments,
+ target,
+ new Selector(selector.kind, selector.memberName, callStructure),
+ elements.getTypeMask(node),
+ arguments,
sourceInformation:
sourceInformationBuilder.buildCall(receiver, node.selector));
}
@@ -985,11 +992,9 @@
ir.Primitive translateSuperBinary(FunctionElement function,
op.BinaryOperator operator,
ast.Node argument) {
- CallStructure callStructure = CallStructure.ONE_ARG;
List<ir.Primitive> arguments = <ir.Primitive>[visit(argument)];
- arguments = normalizeDynamicArguments(callStructure, arguments);
- return irBuilder.buildSuperMethodInvocation(
- function, callStructure, arguments);
+ return irBuilder.buildSuperMethodInvocation(function,
+ CallStructure.ONE_ARG, arguments);
}
@override
@@ -1081,28 +1086,33 @@
// TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct
// semantic correlation between arguments and invocation.
- List<ir.Primitive> translateDynamicArguments(ast.NodeList nodeList,
- CallStructure callStructure) {
- List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit);
+ CallStructure translateDynamicArguments(ast.NodeList nodeList,
+ CallStructure callStructure,
+ List<ir.Primitive> arguments) {
+ assert(arguments.isEmpty);
+ for (ast.Node node in nodeList) arguments.add(visit(node));
return normalizeDynamicArguments(callStructure, arguments);
}
// TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct
// semantic correlation between arguments and invocation.
- List<ir.Primitive> translateStaticArguments(ast.NodeList nodeList,
- Element element,
- CallStructure callStructure) {
- List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit);
+ CallStructure translateStaticArguments(ast.NodeList nodeList,
+ Element element,
+ CallStructure callStructure,
+ List<ir.Primitive> arguments) {
+ assert(arguments.isEmpty);
+ for (ast.Node node in nodeList) arguments.add(visit(node));
return normalizeStaticArguments(callStructure, element, arguments);
}
ir.Primitive translateCallInvoke(ir.Primitive target,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
CallStructure callStructure,
SourceInformation sourceInformation) {
-
- return irBuilder.buildCallInvocation(target, callStructure,
- translateDynamicArguments(arguments, callStructure),
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ callStructure =
+ translateDynamicArguments(argumentsNode, callStructure, arguments);
+ return irBuilder.buildCallInvocation(target, callStructure, arguments,
sourceInformation: sourceInformation);
}
@@ -1123,12 +1133,18 @@
ir.Primitive handleDynamicInvoke(
ast.Send node,
ast.Node receiver,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
Selector selector,
_) {
+ ir.Primitive target = translateReceiver(receiver);
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ CallStructure callStructure = translateDynamicArguments(
+ argumentsNode, selector.callStructure, arguments);
return irBuilder.buildDynamicInvocation(
- translateReceiver(receiver), selector, elements.getTypeMask(node),
- translateDynamicArguments(arguments, selector.callStructure),
+ target,
+ new Selector(selector.kind, selector.memberName, callStructure),
+ elements.getTypeMask(node),
+ arguments,
sourceInformation:
sourceInformationBuilder.buildCall(node, node.selector));
}
@@ -1137,39 +1153,56 @@
ir.Primitive visitIfNotNullDynamicPropertyInvoke(
ast.Send node,
ast.Node receiver,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
Selector selector,
_) {
ir.Primitive target = visit(receiver);
return irBuilder.buildIfNotNullSend(
target,
- nested(() => irBuilder.buildDynamicInvocation(
- target, selector, elements.getTypeMask(node),
- translateDynamicArguments(arguments, selector.callStructure))));
+ nested(() {
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ CallStructure callStructure = translateDynamicArguments(
+ argumentsNode, selector.callStructure, arguments);
+ return irBuilder.buildDynamicInvocation(
+ target,
+ new Selector(selector.kind, selector.memberName, callStructure),
+ elements.getTypeMask(node),
+ arguments);
+ }));
}
ir.Primitive handleLocalInvoke(
ast.Send node,
LocalElement element,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
CallStructure callStructure,
_) {
- return irBuilder.buildLocalVariableInvocation(element, callStructure,
- translateDynamicArguments(arguments, callStructure),
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ callStructure =
+ translateDynamicArguments(argumentsNode, callStructure, arguments);
+ return irBuilder.buildLocalVariableInvocation(
+ element,
+ callStructure,
+ arguments,
callSourceInformation:
- sourceInformationBuilder.buildCall(node, arguments));
+ sourceInformationBuilder.buildCall(node, argumentsNode));
}
@override
ir.Primitive visitLocalFunctionInvoke(
ast.Send node,
LocalFunctionElement function,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
CallStructure callStructure,
_) {
- return irBuilder.buildLocalFunctionInvocation(function, callStructure,
- translateDynamicArguments(arguments, callStructure),
- sourceInformationBuilder.buildCall(node, arguments));
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ callStructure =
+ translateDynamicArguments(argumentsNode, callStructure, arguments);
+ return irBuilder.buildLocalFunctionInvocation(
+ function,
+ callStructure,
+ arguments,
+ sourceInformationBuilder.buildCall(node, argumentsNode));
}
@override
@@ -1181,16 +1214,20 @@
ir.Primitive handleStaticFieldInvoke(
ast.Send node,
FieldElement field,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
CallStructure callStructure,
_) {
SourceInformation src = sourceInformationBuilder.buildGet(node);
ir.Primitive target = buildStaticFieldGet(field, src);
- return irBuilder.buildCallInvocation(target,
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ callStructure =
+ translateDynamicArguments(argumentsNode, callStructure, arguments);
+ return irBuilder.buildCallInvocation(
+ target,
callStructure,
- translateDynamicArguments(arguments, callStructure),
+ arguments,
sourceInformation:
- sourceInformationBuilder.buildCall(node, arguments));
+ sourceInformationBuilder.buildCall(node, argumentsNode));
}
@override
@@ -1207,7 +1244,7 @@
MethodElement function,
ast.NodeList arguments,
CallStructure callStructure, _) {
- return buildStaticNoSuchMethod(
+ return irBuilder.buildStaticNoSuchMethod(
elements.getSelector(node),
arguments.nodes.mapToList(visit));
}
@@ -1216,58 +1253,75 @@
ir.Primitive handleStaticGetterInvoke(
ast.Send node,
FunctionElement getter,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
CallStructure callStructure,
_) {
- ir.Primitive target = irBuilder.buildStaticGetterGet(
- getter, sourceInformationBuilder.buildGet(node));
- return irBuilder.buildCallInvocation(target,
+ ir.Primitive target = irBuilder.buildStaticGetterGet(getter,
+ sourceInformationBuilder.buildGet(node));
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ callStructure =
+ translateDynamicArguments(argumentsNode, callStructure, arguments);
+ return irBuilder.buildCallInvocation(
+ target,
callStructure,
- translateDynamicArguments(arguments, callStructure),
+ arguments,
sourceInformation:
- sourceInformationBuilder.buildCall(node, arguments));
+ sourceInformationBuilder.buildCall(node, argumentsNode));
}
@override
ir.Primitive visitSuperFieldInvoke(
ast.Send node,
FieldElement field,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
CallStructure callStructure,
_) {
ir.Primitive target = irBuilder.buildSuperFieldGet(field);
- return irBuilder.buildCallInvocation(target,
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ callStructure =
+ translateDynamicArguments(argumentsNode, callStructure, arguments);
+ return irBuilder.buildCallInvocation(
+ target,
callStructure,
- translateDynamicArguments(arguments, callStructure),
+ arguments,
sourceInformation:
- sourceInformationBuilder.buildCall(node, arguments));
+ sourceInformationBuilder.buildCall(node, argumentsNode));
}
@override
ir.Primitive visitSuperGetterInvoke(
ast.Send node,
FunctionElement getter,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
CallStructure callStructure,
_) {
- ir.Primitive target = irBuilder.buildSuperGetterGet(
- getter, sourceInformationBuilder.buildGet(node));
- return irBuilder.buildCallInvocation(target,
+ ir.Primitive target = irBuilder.buildSuperGetterGet(getter,
+ sourceInformationBuilder.buildGet(node));
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ callStructure =
+ translateDynamicArguments(argumentsNode, callStructure, arguments);
+ return irBuilder.buildCallInvocation(
+ target,
callStructure,
- translateDynamicArguments(arguments, callStructure),
+ arguments,
sourceInformation:
- sourceInformationBuilder.buildCall(node, arguments));
+ sourceInformationBuilder.buildCall(node, argumentsNode));
}
@override
ir.Primitive visitSuperMethodInvoke(
ast.Send node,
MethodElement method,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
CallStructure callStructure,
_) {
- return irBuilder.buildSuperMethodInvocation(method, callStructure,
- translateDynamicArguments(arguments, callStructure),
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ callStructure = translateStaticArguments(argumentsNode, method,
+ callStructure, arguments);
+ return irBuilder.buildSuperMethodInvocation(
+ method,
+ callStructure,
+ arguments,
sourceInformation:
sourceInformationBuilder.buildCall(node, node.selector));
}
@@ -1278,22 +1332,30 @@
MethodElement method,
ast.NodeList arguments,
CallStructure callStructure, _) {
+ List<ir.Primitive> normalizedArguments = <ir.Primitive>[];
+ CallStructure normalizedCallStructure =
+ translateDynamicArguments(arguments, callStructure, normalizedArguments);
return buildInstanceNoSuchMethod(
- elements.getSelector(node),
+ new Selector.call(method.memberName, normalizedCallStructure),
elements.getTypeMask(node),
- translateDynamicArguments(arguments, callStructure));
+ normalizedArguments);
}
@override
ir.Primitive visitUnresolvedSuperInvoke(
ast.Send node,
Element element,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
Selector selector, _) {
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ CallStructure callStructure = translateDynamicArguments(
+ argumentsNode, selector.callStructure, arguments);
+ // TODO(johnniwinther): Supply a member name to the visit function instead
+ // of looking it up in elements.
return buildInstanceNoSuchMethod(
- elements.getSelector(node),
+ new Selector.call(elements.getSelector(node).memberName, callStructure),
elements.getTypeMask(node),
- translateDynamicArguments(arguments, selector.callStructure));
+ arguments);
}
@override
@@ -1371,15 +1433,19 @@
rhsValue = irBuilder.buildIntegerConstant(1);
}
List<ir.Primitive> arguments = <ir.Primitive>[rhsValue];
- arguments = normalizeDynamicArguments(
- operatorSelector.callStructure, arguments);
+ CallStructure callStructure =
+ normalizeDynamicArguments(operatorSelector.callStructure, arguments);
TypeMask operatorTypeMask =
elements.getOperatorTypeMaskInComplexSendSet(node);
SourceInformation operatorSourceInformation =
sourceInformationBuilder.buildCall(node, node.assignmentOperator);
ir.Primitive result = irBuilder.buildDynamicInvocation(
- value, operatorSelector, operatorTypeMask, arguments,
- sourceInformation: operatorSourceInformation);
+ value,
+ new Selector(operatorSelector.kind, operatorSelector.memberName,
+ callStructure),
+ operatorTypeMask,
+ arguments,
+ sourceInformation: operatorSourceInformation);
setValue(result);
return rhs.kind == CompoundKind.POSTFIX ? value : result;
}
@@ -1577,7 +1643,7 @@
ir.Primitive buildLocalNoSuchSetter(LocalElement local, ir.Primitive value) {
Selector selector = new Selector.setter(
new Name(local.name, local.library, isSetter: true));
- return buildStaticNoSuchMethod(selector, [value]);
+ return irBuilder.buildStaticNoSuchMethod(selector, [value]);
}
@override
@@ -1633,13 +1699,13 @@
}
ir.Primitive buildStaticNoSuchGetter(Element element) {
- return buildStaticNoSuchMethod(
+ return irBuilder.buildStaticNoSuchMethod(
new Selector.getter(new Name(element.name, element.library)),
const <ir.Primitive>[]);
}
ir.Primitive buildStaticNoSuchSetter(Element element, ir.Primitive value) {
- return buildStaticNoSuchMethod(
+ return irBuilder.buildStaticNoSuchMethod(
new Selector.setter(new Name(element.name, element.library)),
<ir.Primitive>[value]);
}
@@ -1858,11 +1924,11 @@
getValue: () {
Selector selector = new Selector.index();
List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
- arguments =
+ CallStructure callStructure =
normalizeDynamicArguments(selector.callStructure, arguments);
return irBuilder.buildDynamicInvocation(
target,
- selector,
+ new Selector(selector.kind, selector.memberName, callStructure),
elements.getGetterTypeMaskInComplexSendSet(node),
arguments,
sourceInformation:
@@ -1968,10 +2034,6 @@
return irBuilder.buildNonTailThrow(visit(node.expression));
}
- ir.Primitive buildStaticNoSuchMethod(
- Selector selector,
- List<ir.Primitive> arguments);
-
ir.Primitive buildInstanceNoSuchMethod(
Selector selector,
TypeMask mask,
@@ -1989,7 +2051,7 @@
ast.Node rhs, _) {
// TODO(asgerf): What is unresolved? The getter and/or the setter?
// If it was the setter, we must evaluate the right-hand side.
- return buildStaticNoSuchMethod(elements.getSelector(node), []);
+ return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node), []);
}
@override
@@ -2008,29 +2070,36 @@
ast.NewExpression node,
Element constructor,
DartType type,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
Selector selector, _) {
// If the class is there but the constructor is missing, it's an NSM error.
- return buildStaticNoSuchMethod(selector,
- translateDynamicArguments(arguments, selector.callStructure));
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ CallStructure callStructure = translateDynamicArguments(
+ argumentsNode, selector.callStructure, arguments);
+ return irBuilder.buildStaticNoSuchMethod(
+ new Selector(selector.kind, selector.memberName, callStructure),
+ arguments);
}
@override
ir.Primitive visitConstructorIncompatibleInvoke(
ast.NewExpression node,
- Element constructor,
+ ConstructorElement constructor,
DartType type,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
CallStructure callStructure, _) {
- return buildStaticNoSuchMethod(elements.getSelector(node.send),
- translateDynamicArguments(arguments, callStructure));
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ callStructure =
+ translateDynamicArguments(argumentsNode, callStructure, arguments);
+ return irBuilder.buildStaticNoSuchMethod(
+ new Selector.call(constructor.memberName, callStructure), arguments);
}
@override
ir.Primitive visitUnresolvedGet(
ast.Send node,
Element element, _) {
- return buildStaticNoSuchMethod(elements.getSelector(node), []);
+ return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node), []);
}
@override
@@ -2039,7 +2108,7 @@
Element element,
ast.NodeList arguments,
Selector selector, _) {
- return buildStaticNoSuchMethod(elements.getSelector(node),
+ return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node),
arguments.nodes.mapToList(visit));
}
@@ -2048,13 +2117,16 @@
ast.NewExpression node,
ConstructorElement constructor,
InterfaceType type,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
CallStructure callStructure, _) {
String nameString = Elements.reconstructConstructorName(constructor);
Name name = new Name(nameString, constructor.library);
- return buildStaticNoSuchMethod(
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ callStructure =
+ translateDynamicArguments(argumentsNode, callStructure, arguments);
+ return irBuilder.buildStaticNoSuchMethod(
new Selector.call(name, callStructure),
- translateDynamicArguments(arguments, callStructure));
+ arguments);
}
@override
@@ -2062,7 +2134,8 @@
ast.Send node,
Element element,
ast.Node rhs, _) {
- return buildStaticNoSuchMethod(elements.getSelector(node), [visit(rhs)]);
+ return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node),
+ [visit(rhs)]);
}
@override
@@ -2113,7 +2186,7 @@
ast.Node rhs, _) {
InterfaceType type = constant.type;
ClassElement element = type.element;
- return buildStaticNoSuchMethod(
+ return irBuilder.buildStaticNoSuchMethod(
new Selector.setter(element.memberName),
[visit(rhs)]);
}
@@ -2125,7 +2198,7 @@
ast.Node rhs, _) {
TypedefType type = constant.type;
TypedefElement element = type.element;
- return buildStaticNoSuchMethod(
+ return irBuilder.buildStaticNoSuchMethod(
new Selector.setter(element.memberName),
[visit(rhs)]);
}
@@ -2135,7 +2208,7 @@
ast.SendSet node,
TypeVariableElement element,
ast.Node rhs, _) {
- return buildStaticNoSuchMethod(
+ return irBuilder.buildStaticNoSuchMethod(
new Selector.setter(element.memberName), [visit(rhs)]);
}
@@ -2144,7 +2217,7 @@
ast.SendSet node,
ConstantExpression constant,
ast.Node rhs, _) {
- return buildStaticNoSuchMethod(
+ return irBuilder.buildStaticNoSuchMethod(
new Selector.setter(Names.dynamic_), [visit(rhs)]);
}
@@ -2155,6 +2228,7 @@
InterfaceType type,
ast.NodeList arguments,
CallStructure callStructure, _) {
+ for (ast.Node argument in arguments) visit(argument);
return buildAbstractClassInstantiationError(element.enclosingClass);
}
@@ -2164,7 +2238,7 @@
FieldElement field,
ast.Node rhs, _) {
// TODO(asgerf): Include class name somehow for static class members?
- return buildStaticNoSuchMethod(
+ return irBuilder.buildStaticNoSuchMethod(
new Selector.setter(field.memberName),
[visit(rhs)]);
}
@@ -2185,7 +2259,7 @@
ast.SendSet node,
LocalElement local,
ast.Node rhs, _) {
- return buildStaticNoSuchMethod(
+ return irBuilder.buildStaticNoSuchMethod(
new Selector.setter(new Name(local.name, local.library)),
[visit(rhs)]);
}
@@ -2196,7 +2270,7 @@
MethodElement function,
ast.Node rhs,
_) {
- return buildStaticNoSuchMethod(
+ return irBuilder.buildStaticNoSuchMethod(
new Selector.setter(function.memberName),
[visit(rhs)]);
}
@@ -2207,7 +2281,7 @@
GetterElement getter,
ast.Node rhs,
_) {
- return buildStaticNoSuchMethod(
+ return irBuilder.buildStaticNoSuchMethod(
new Selector.setter(getter.memberName),
[visit(rhs)]);
}
@@ -2217,7 +2291,7 @@
ast.Send node,
SetterElement setter,
_) {
- return buildStaticNoSuchMethod(
+ return irBuilder.buildStaticNoSuchMethod(
new Selector.getter(setter.memberName),
[]);
}
@@ -2226,13 +2300,13 @@
ir.Primitive handleStaticSetterInvoke(
ast.Send node,
SetterElement setter,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
CallStructure callStructure, _) {
// Translate as a method call.
- List<ir.Primitive> args = arguments.nodes.mapToList(visit);
- return buildStaticNoSuchMethod(
+ List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
+ return irBuilder.buildStaticNoSuchMethod(
new Selector.call(setter.memberName, callStructure),
- args);
+ arguments);
}
@override
@@ -2273,14 +2347,15 @@
ir.Primitive visitSuperSetterInvoke(
ast.Send node,
SetterElement setter,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
CallStructure callStructure, _) {
- List<ir.Primitive> args =
- translateDynamicArguments(arguments, callStructure);
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ callStructure =
+ translateDynamicArguments(argumentsNode, callStructure, arguments);
return buildInstanceNoSuchMethod(
new Selector.call(setter.memberName, callStructure),
elements.getTypeMask(node),
- args);
+ arguments);
}
ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) {
@@ -2501,6 +2576,7 @@
}
FunctionElement get throwTypeErrorHelper => _backend.helpers.throwTypeError;
+ Element get throwNoSuchMethod => _backend.helpers.throwNoSuchMethod;
ClassElement get nullClass => _compiler.coreClasses.nullClass;
@@ -3207,70 +3283,56 @@
}
}
- /// Inserts default arguments and normalizes order of named arguments.
- List<ir.Primitive> normalizeStaticArguments(
- CallStructure callStructure,
- FunctionElement target,
- List<ir.Primitive> arguments) {
+ CallStructure normalizeStaticArguments(CallStructure callStructure,
+ FunctionElement target,
+ List<ir.Primitive> arguments) {
target = target.implementation;
FunctionSignature signature = target.functionSignature;
if (!signature.optionalParametersAreNamed &&
signature.parameterCount == arguments.length) {
- // Optimization: don't copy the argument list for trivial cases.
- return arguments;
+ return callStructure;
}
- List<ir.Primitive> result = <ir.Primitive>[];
- int i = 0;
- signature.forEachRequiredParameter((ParameterElement element) {
- result.add(arguments[i]);
- ++i;
- });
-
if (!signature.optionalParametersAreNamed) {
+ int i = signature.requiredParameterCount;
signature.forEachOptionalParameter((ParameterElement element) {
- if (i < arguments.length) {
- result.add(arguments[i]);
+ if (i < callStructure.positionalArgumentCount) {
++i;
} else {
- result.add(translateDefaultValue(element));
+ arguments.add(translateDefaultValue(element));
}
});
- } else {
- int offset = i;
- // Iterate over the optional parameters of the signature, and try to
- // find them in [compiledNamedArguments]. If found, we use the
- // value in the temporary list, otherwise the default value.
- signature.orderedOptionalParameters.forEach((ParameterElement element) {
- int nameIndex = callStructure.namedArguments.indexOf(element.name);
- if (nameIndex != -1) {
- int translatedIndex = offset + nameIndex;
- result.add(arguments[translatedIndex]);
- } else {
- result.add(translateDefaultValue(element));
- }
- });
+ return new CallStructure(signature.parameterCount);
}
- return result;
+
+ int offset = signature.requiredParameterCount;
+ List<ir.Primitive> namedArguments = arguments.sublist(offset);
+ arguments.length = offset;
+ List<String> normalizedNames = <String>[];
+ // Iterate over the optional parameters of the signature, and try to
+ // find them in the callStructure's named arguments. If found, we use the
+ // value in the temporary list, otherwise the default value.
+ signature.orderedOptionalParameters.forEach((ParameterElement element) {
+ int nameIndex = callStructure.namedArguments.indexOf(element.name);
+ arguments.add(nameIndex == -1 ? translateDefaultValue(element)
+ : namedArguments[nameIndex]);
+ normalizedNames.add(element.name);
+ });
+ return new CallStructure(signature.parameterCount, normalizedNames);
}
- /// Normalizes order of named arguments.
- List<ir.Primitive> normalizeDynamicArguments(
- CallStructure callStructure,
- List<ir.Primitive> arguments) {
+ CallStructure normalizeDynamicArguments(CallStructure callStructure,
+ List<ir.Primitive> arguments) {
assert(arguments.length == callStructure.argumentCount);
- // Optimization: don't copy the argument list for trivial cases.
- if (callStructure.namedArguments.isEmpty) return arguments;
- List<ir.Primitive> result = <ir.Primitive>[];
- for (int i=0; i < callStructure.positionalArgumentCount; i++) {
- result.add(arguments[i]);
- }
+ if (callStructure.namedArguments.isEmpty) return callStructure;
+ int destinationIndex = callStructure.positionalArgumentCount;
+ List<ir.Primitive> namedArguments = arguments.sublist(destinationIndex);
for (String argName in callStructure.getOrderedNamedArguments()) {
- int nameIndex = callStructure.namedArguments.indexOf(argName);
- int translatedIndex = callStructure.positionalArgumentCount + nameIndex;
- result.add(arguments[translatedIndex]);
+ int sourceIndex = callStructure.namedArguments.indexOf(argName);
+ arguments[destinationIndex++] = namedArguments[sourceIndex];
}
- return result;
+ return new CallStructure(callStructure.argumentCount,
+ callStructure.getOrderedNamedArguments());
}
@override
@@ -3278,14 +3340,14 @@
ast.NewExpression node,
ConstructorElement constructor,
DartType type,
- ast.NodeList arguments,
+ ast.NodeList argumentsNode,
CallStructure callStructure,
_) {
- List<ir.Primitive> arguments =
- node.send.arguments.mapToList(visit, growable:false);
+ List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
// Use default values from the effective target, not the immediate target.
ConstructorElement target = constructor.effectiveTarget;
- arguments = normalizeStaticArguments(callStructure, target, arguments);
+ callStructure =
+ normalizeStaticArguments(callStructure, target, arguments);
TypeMask allocationSiteType;
ast.Node send = node.send;
if (Elements.isFixedListConstructorCall(constructor, send, compiler) ||
@@ -3304,20 +3366,6 @@
}
@override
- ir.Primitive buildStaticNoSuchMethod(Selector selector,
- List<ir.Primitive> arguments) {
- Element thrower = backend.helpers.throwNoSuchMethod;
- ir.Primitive receiver = irBuilder.buildStringConstant('');
- ir.Primitive name = irBuilder.buildStringConstant(selector.name);
- ir.Primitive argumentList = irBuilder.buildListLiteral(null, arguments);
- ir.Primitive expectedArgumentNames = irBuilder.buildNullConstant();
- return irBuilder.buildStaticFunctionInvocation(
- thrower,
- new CallStructure.unnamed(4),
- [receiver, name, argumentList, expectedArgumentNames]);
- }
-
- @override
ir.Primitive buildInstanceNoSuchMethod(Selector selector,
TypeMask mask,
List<ir.Primitive> arguments) {
@@ -3396,12 +3444,15 @@
reporter.internalError(node,
'Isolate library and compiler mismatch.');
}
- List<ir.Primitive> arguments = translateStaticArguments(argumentList,
- element, callStructure);
- return irBuilder.buildStaticFunctionInvocation(element,
- callStructure, arguments,
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ callStructure = translateStaticArguments(argumentList, element,
+ callStructure, arguments);
+ return irBuilder.buildStaticFunctionInvocation(
+ element,
+ callStructure,
+ arguments,
sourceInformation:
- sourceInformationBuilder.buildCall(node, node.selector));
+ sourceInformationBuilder.buildCall(node, node.selector));
}
/// Lookup the value of the enum described by [node].
@@ -3591,14 +3642,18 @@
@override
ir.Primitive handleStaticFunctionInvoke(ast.Send node,
MethodElement function,
- ast.NodeList argumentList,
+ ast.NodeList argumentsNode,
CallStructure callStructure,
_) {
if (compiler.backend.isForeign(function)) {
- return handleForeignCode(node, function, argumentList, callStructure);
+ return handleForeignCode(node, function, argumentsNode, callStructure);
} else {
- return irBuilder.buildStaticFunctionInvocation(function, callStructure,
- translateStaticArguments(argumentList, function, callStructure),
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ callStructure = translateStaticArguments(argumentsNode, function,
+ callStructure, arguments);
+ return irBuilder.buildStaticFunctionInvocation(function,
+ callStructure,
+ arguments,
sourceInformation:
sourceInformationBuilder.buildCall(node, node.selector));
}
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
index 78b976f..12262e13 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
@@ -148,24 +148,18 @@
}
String visitInvokeConstructor(InvokeConstructor node) {
- String className;
// TODO(karlklose): for illegal nodes constructed for tests or unresolved
// constructor calls in the DartBackend, we get an element with no enclosing
// class. Clean this up by introducing a name field to the node and
// removing [ErroneousElement]s from the IR.
- if (node.dartType != null) {
- className = node.dartType.toString();
- } else {
- className = node.target.enclosingClass.name;
- }
- String callName;
- if (node.target.name.isEmpty) {
- callName = '${className}';
- } else {
- callName = '${className}.${node.target.name}';
+ String name = node.dartType != null
+ ? node.dartType.toString()
+ : node.target.enclosingClass.name;
+ if (!node.target.name.isEmpty) {
+ name = '${name}.${node.target.name}';
}
String args = formatArguments(node.selector.callStructure, node.arguments);
- return '(InvokeConstructor $callName $args)';
+ return '(InvokeConstructor $name $args)';
}
String visitInvokeContinuation(InvokeContinuation node) {
diff --git a/pkg/compiler/lib/src/cps_ir/type_mask_system.dart b/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
index 2329144..25fb1c9 100644
--- a/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
@@ -579,4 +579,19 @@
return null;
}
}
+
+ /// Returns the type of the entry at a given index, `null` if unknown.
+ TypeMask indexWithConstant(TypeMask container, ConstantValue indexValue) {
+ if (container is DictionaryTypeMask) {
+ if (indexValue is StringConstantValue) {
+ String key = indexValue.primitiveValue.slowToString();
+ TypeMask result = container.typeMap[key];
+ if (result != null) return result;
+ }
+ }
+ if (container is ContainerTypeMask) {
+ return container.elementType;
+ }
+ return null;
+ }
}
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index 8a4daba..f716f05 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -591,6 +591,46 @@
return constant(new StringConstantValue(new ast.DartString.literal(value)));
}
+ AbstractConstantValue indexSpecial(AbstractConstantValue left,
+ AbstractConstantValue right) {
+ if (left.isNothing || right.isNothing) return nothing;
+ if (right.isConstant) {
+ ConstantValue index = right.constant;
+ if (left.isConstant) {
+ ConstantValue receiver = left.constant;
+ if (receiver is StringConstantValue) {
+ if (index is IntConstantValue) {
+ String stringValue = receiver.primitiveValue.slowToString();
+ int indexValue = index.primitiveValue;
+ if (0 <= indexValue && indexValue < stringValue.length) {
+ return stringConstant(stringValue[indexValue]);
+ } else {
+ return nothing; // Will throw.
+ }
+ }
+ } else if (receiver is ListConstantValue) {
+ if (index is IntConstantValue) {
+ int indexValue = index.primitiveValue;
+ if (0 <= indexValue && indexValue < receiver.length) {
+ return constant(receiver.entries[indexValue]);
+ } else {
+ return nothing; // Will throw.
+ }
+ }
+ } else if (receiver is MapConstantValue) {
+ ConstantValue result = receiver.lookup(index);
+ if (result != null) {
+ return constant(result);
+ }
+ return constant(new NullConstantValue());
+ }
+ }
+ TypeMask type = typeSystem.indexWithConstant(left.type, index);
+ if (type != null) return nonConstant(type);
+ }
+ return null; // The caller will use return type from type inference.
+ }
+
AbstractConstantValue stringify(AbstractConstantValue value) {
if (value.isNothing) return nothing;
if (value.isNonConst) return nonConstant(typeSystem.stringType);
@@ -2603,8 +2643,15 @@
AbstractConstantValue receiver = getValue(node.receiver.definition);
node.receiverIsNotNull = receiver.isDefinitelyNotNull;
if (receiver.isNothing) {
- setResult(node, lattice.nothing);
- return; // And come back later.
+ return setResult(node, lattice.nothing);
+ }
+
+ void finish(AbstractConstantValue result, {bool canReplace: false}) {
+ if (result == null) {
+ canReplace = false;
+ result = lattice.getInvokeReturnType(node.selector, node.mask);
+ }
+ setResult(node, result, canReplace: canReplace);
}
if (node.selector.isGetter) {
@@ -2613,37 +2660,34 @@
AbstractConstantValue object = getValue(node.dartReceiver);
if (typeSystem.isDefinitelyIndexable(object.type, allowNull: true)) {
AbstractConstantValue length = lattice.lengthSpecial(object);
- if (length != null) {
- setResult(node, length, canReplace: !object.isNullable);
- }
+ return finish(length, canReplace: !object.isNullable);
}
}
- setResult(node, lattice.getInvokeReturnType(node.selector, node.mask));
- return;
+ return finish(null);
}
if (node.selector.isCall) {
- AbstractConstantValue result;
if (node.selector == Selectors.codeUnitAt) {
AbstractConstantValue object = getValue(node.dartReceiver);
AbstractConstantValue right = getValue(node.dartArgument(0));
- result = lattice.codeUnitAtSpecial(object, right);
+ AbstractConstantValue result = lattice.codeUnitAtSpecial(object, right);
+ return finish(result, canReplace: !object.isNullable);
}
- if (result == null) {
- setResult(node, lattice.getInvokeReturnType(node.selector, node.mask));
- } else {
- setResult(node, result, canReplace: true);
- }
- return;
+ return finish(null);
+ }
+
+ if (node.selector == Selectors.index) {
+ AbstractConstantValue object = getValue(node.dartReceiver);
+ AbstractConstantValue right = getValue(node.dartArgument(0));
+ AbstractConstantValue result = lattice.indexSpecial(object, right);
+ return finish(result, canReplace: !object.isNullable);
}
if (!node.selector.isOperator) {
- setResult(node, lattice.getInvokeReturnType(node.selector, node.mask));
- return;
+ return finish(null);
}
// Calculate the resulting constant if possible.
- AbstractConstantValue result;
String opname = node.selector.name;
if (node.arguments.length == 1) {
AbstractConstantValue argument = getValue(node.dartReceiver);
@@ -2652,22 +2696,17 @@
opname = "-";
}
UnaryOperator operator = UnaryOperator.parse(opname);
- result = lattice.unaryOp(operator, argument);
+ AbstractConstantValue result = lattice.unaryOp(operator, argument);
+ return finish(result, canReplace: !argument.isNullable);
} else if (node.arguments.length == 2) {
// Binary operator.
AbstractConstantValue left = getValue(node.dartReceiver);
AbstractConstantValue right = getValue(node.dartArgument(0));
BinaryOperator operator = BinaryOperator.parse(opname);
- result = lattice.binaryOp(operator, left, right);
+ AbstractConstantValue result = lattice.binaryOp(operator, left, right);
+ return finish(result, canReplace: !left.isNullable);
}
-
- // Update value of the continuation parameter. Again, this is effectively
- // a phi.
- if (result == null) {
- setResult(node, lattice.getInvokeReturnType(node.selector, node.mask));
- } else {
- setResult(node, result, canReplace: true);
- }
+ return finish(null);
}
void visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 662316b..0e2c63f 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -317,6 +317,7 @@
new OptionHandler('--out=.+|-o.*', setOutput, multipleArguments: true),
new OptionHandler(Flags.allowMockCompilation, passThrough),
new OptionHandler(Flags.fastStartup, passThrough),
+ new OptionHandler(Flags.conditionalDirectives, passThrough),
new OptionHandler('${Flags.minify}|-m', implyCompilation),
new OptionHandler(Flags.preserveUris, passThrough),
new OptionHandler('--force-strip=.*', setStrip),
diff --git a/pkg/compiler/lib/src/diagnostics/dart2js_messages.dart b/pkg/compiler/lib/src/diagnostics/dart2js_messages.dart
new file mode 100644
index 0000000..0f4e624
--- /dev/null
+++ b/pkg/compiler/lib/src/diagnostics/dart2js_messages.dart
@@ -0,0 +1,3715 @@
+// 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.
+
+// The messages in this file should meet the following guide lines:
+//
+// 1. The message should be a complete sentence starting with an uppercase
+// letter, and ending with a period.
+//
+// 2. Reserved words and embedded identifiers should be in single quotes, so
+// prefer double quotes for the complete message. For example, "The
+// class '#{className}' can't use 'super'." Notice that the word 'class' in the
+// preceding message is not quoted as it refers to the concept 'class', not the
+// reserved word. On the other hand, 'super' refers to the reserved word. Do
+// not quote 'null' and numeric literals.
+//
+// 3. Do not try to compose messages, as it can make translating them hard.
+//
+// 4. Try to keep the error messages short, but informative.
+//
+// 5. Use simple words and terminology, assume the reader of the message
+// doesn't have an advanced degree in math, and that English is not the
+// reader's native language. Do not assume any formal computer science
+// training. For example, do not use Latin abbreviations (prefer "that is" over
+// "i.e.", and "for example" over "e.g."). Also avoid phrases such as "if and
+// only if" and "iff", that level of precision is unnecessary.
+//
+// 6. Prefer contractions when they are in common use, for example, prefer
+// "can't" over "cannot". Using "cannot", "must not", "shall not", etc. is
+// off-putting to people new to programming.
+//
+// 7. Use common terminology, preferably from the Dart Language
+// Specification. This increases the user's chance of finding a good
+// explanation on the web.
+//
+// 8. Do not try to be cute or funny. It is extremely frustrating to work on a
+// product that crashes with a "tongue-in-cheek" message, especially if you did
+// not want to use this product to begin with.
+//
+// 9. Do not lie, that is, do not write error messages containing phrases like
+// "can't happen". If the user ever saw this message, it would be a
+// lie. Prefer messages like: "Internal error: This function should not be
+// called when 'x' is null.".
+//
+// 10. Prefer to not use imperative tone. That is, the message should not sound
+// accusing or like it is ordering the user around. The computer should
+// describe the problem, not criticize for violating the specification.
+//
+// Other things to keep in mind:
+//
+// An INFO message should always be preceded by a non-INFO message, and the
+// INFO messages are additional details about the preceding non-INFO
+// message. For example, consider duplicated elements. First report a WARNING
+// or ERROR about the duplicated element, and then report an INFO about the
+// location of the existing element.
+//
+// Generally, we want to provide messages that consists of three sentences:
+// 1. what is wrong, 2. why is it wrong, 3. how do I fix it. However, we
+// combine the first two in [template] and the last in [howToFix].
+
+/// Padding used before and between import chains in the message for
+/// [MessageKind.IMPORT_EXPERIMENTAL_MIRRORS].
+const String IMPORT_EXPERIMENTAL_MIRRORS_PADDING = '\n* ';
+
+/// Padding used before and between import chains in the message for
+/// [MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND].
+const String MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING = '\n ';
+
+/// Padding used before and between import chains in the message for
+/// [MessageKind.DISALLOWED_LIBRARY_IMPORT].
+const String DISALLOWED_LIBRARY_IMPORT_PADDING = '\n ';
+
+const DONT_KNOW_HOW_TO_FIX = "Computer says no!";
+
+final Map<String, Map> MESSAGES = {
+ /// Do not use this. It is here for legacy and debugging. It violates item
+ /// 4 of the guide lines for error messages in the beginning of the file.
+ 'GENERIC': {'id': 'SOWPSL', 'template': "#{text}",},
+
+ 'NOT_ASSIGNABLE': {
+ 'id': 'VYNMAP',
+ 'template': "'#{fromType}' is not assignable to '#{toType}'.",
+ },
+
+ 'FORIN_NOT_ASSIGNABLE': {
+ 'id': 'XQSRXO',
+ 'template': "The element type '#{currentType}' of '#{expressionType}' "
+ "is not assignable to '#{elementType}'.",
+ },
+
+ 'VOID_EXPRESSION': {
+ 'id': 'QHEVSC',
+ 'template': "Expression does not yield a value.",
+ },
+
+ 'VOID_VARIABLE': {
+ 'id': 'RFEURK',
+ 'template': "Variable cannot be of type void.",
+ },
+
+ 'RETURN_VALUE_IN_VOID': {
+ 'id': 'FUNYDS',
+ 'template': "Cannot return value from void function.",
+ },
+
+ 'RETURN_NOTHING': {
+ 'id': 'HPPODJ',
+ 'template': "Value of type '#{returnType}' expected.",
+ },
+
+ 'MISSING_ARGUMENT': {
+ 'id': 'LHMCIK',
+ 'template': "Missing argument of type '#{argumentType}'.",
+ },
+
+ 'ADDITIONAL_ARGUMENT': {'id': 'GMITMA', 'template': "Additional argument.",},
+
+ 'NAMED_ARGUMENT_NOT_FOUND': {
+ 'id': 'UCEARQ',
+ 'template': "No named argument '#{argumentName}' found on method.",
+ },
+
+ 'MEMBER_NOT_FOUND': {
+ 'id': 'MMQODC',
+ 'template': "No member named '#{memberName}' in class '#{className}'.",
+ },
+
+ 'AWAIT_MEMBER_NOT_FOUND': {
+ 'id': 'XIDLIP',
+ 'template': "No member named 'await' in class '#{className}'.",
+ 'howToFix': "Did you mean to add the 'async' marker "
+ "to '#{functionName}'?",
+ 'examples': [
+ """
+class A {
+m() => await -3;
+}
+main() => new A().m();
+"""
+ ],
+ },
+
+ 'AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE': {
+ 'id': 'HBIYGN',
+ 'template': "No member named 'await' in class '#{className}'.",
+ 'howToFix': "Did you mean to add the 'async' marker "
+ "to the enclosing function?",
+ 'examples': [
+ """
+class A {
+m() => () => await -3;
+}
+main() => new A().m();
+"""
+ ],
+ },
+
+ 'METHOD_NOT_FOUND': {
+ 'id': 'QYYHBU',
+ 'template': "No method named '#{memberName}' in class '#{className}'.",
+ },
+
+ 'OPERATOR_NOT_FOUND': {
+ 'id': 'SXGOYS',
+ 'template': "No operator '#{memberName}' in class '#{className}'.",
+ },
+
+ 'SETTER_NOT_FOUND': {
+ 'id': 'ADFRVF',
+ 'template': "No setter named '#{memberName}' in class '#{className}'.",
+ },
+
+ 'SETTER_NOT_FOUND_IN_SUPER': {
+ 'id': 'OCVRNJ',
+ 'template': "No setter named '#{name}' in superclass of '#{className}'.",
+ },
+
+ 'GETTER_NOT_FOUND': {
+ 'id': 'PBNXAC',
+ 'template': "No getter named '#{memberName}' in class '#{className}'.",
+ },
+
+ 'NOT_CALLABLE': {
+ 'id': 'SEMKJO',
+ 'template': "'#{elementName}' is not callable.",
+ },
+
+ 'MEMBER_NOT_STATIC': {
+ 'id': 'QIOISX',
+ 'template': "'#{className}.#{memberName}' is not static.",
+ },
+
+ 'NO_INSTANCE_AVAILABLE': {
+ 'id': 'FQPYLR',
+ 'template': "'#{name}' is only available in instance methods.",
+ },
+
+ 'NO_THIS_AVAILABLE': {
+ 'id': 'LXPXKG',
+ 'template': "'this' is only available in instance methods.",
+ },
+
+ 'PRIVATE_ACCESS': {
+ 'id': 'DIMHCR',
+ 'template': "'#{name}' is declared private within library "
+ "'#{libraryName}'.",
+ },
+
+ 'THIS_IS_THE_DECLARATION': {
+ 'id': 'YIJWTO',
+ 'template': "This is the declaration of '#{name}'.",
+ },
+
+ 'THIS_IS_THE_METHOD': {
+ 'id': 'PYXWLF',
+ 'template': "This is the method declaration.",
+ },
+
+ 'CANNOT_RESOLVE': {'id': 'SPVJYO', 'template': "Cannot resolve '#{name}'.",},
+
+ 'CANNOT_RESOLVE_AWAIT': {
+ 'id': 'YQYLRS',
+ 'template': "Cannot resolve '#{name}'.",
+ 'howToFix': "Did you mean to add the 'async' marker "
+ "to '#{functionName}'?",
+ 'examples': ["main() => await -3;", "foo() => await -3; main() => foo();"],
+ },
+
+ 'CANNOT_RESOLVE_AWAIT_IN_CLOSURE': {
+ 'id': 'SIXRAA',
+ 'template': "Cannot resolve '#{name}'.",
+ 'howToFix': "Did you mean to add the 'async' marker "
+ "to the enclosing function?",
+ 'examples': ["main() { (() => await -3)(); }",],
+ },
+
+ 'CANNOT_RESOLVE_IN_INITIALIZER': {
+ 'id': 'VVEQFD',
+ 'template':
+ "Cannot resolve '#{name}'. It would be implicitly looked up on this "
+ "instance, but instances are not available in initializers.",
+ 'howToFix': "Try correcting the unresolved reference or move the "
+ "initialization to a constructor body.",
+ 'examples': [
+ """
+class A {
+var test = unresolvedName;
+}
+main() => new A();
+"""
+ ],
+ },
+
+ 'CANNOT_RESOLVE_CONSTRUCTOR': {
+ 'id': 'QRPATN',
+ 'template': "Cannot resolve constructor '#{constructorName}'.",
+ },
+
+ 'CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT': {
+ 'id': 'IFKCHF',
+ 'template': "cannot resolve constructor '#{constructorName}' "
+ "for implicit super call.",
+ 'howToFix': "Try explicitly invoking a constructor of the super class",
+ 'examples': [
+ """
+class A {
+A.foo() {}
+}
+class B extends A {
+B();
+}
+main() => new B();
+"""
+ ],
+ },
+
+ 'INVALID_UNNAMED_CONSTRUCTOR_NAME': {
+ 'id': 'VPJLVI',
+ 'template': "Unnamed constructor name must be '#{name}'.",
+ },
+
+ 'INVALID_CONSTRUCTOR_NAME': {
+ 'id': 'LMDCAS',
+ 'template': "Constructor name must start with '#{name}'.",
+ },
+
+ 'CANNOT_RESOLVE_TYPE': {
+ 'id': 'PQIAPG',
+ 'template': "Cannot resolve type '#{typeName}'.",
+ },
+
+ 'DUPLICATE_DEFINITION': {
+ 'id': 'LVTYNW',
+ 'template': "Duplicate definition of '#{name}'.",
+ 'howToFix': "Try to rename or remove this definition.",
+ 'examples': [
+ """
+class C {
+void f() {}
+int get f => 1;
+}
+
+main() {
+new C();
+}
+
+"""
+ ],
+ },
+
+ 'EXISTING_DEFINITION': {
+ 'id': 'DAUYKK',
+ 'template': "Existing definition of '#{name}'.",
+ },
+
+ 'DUPLICATE_IMPORT': {
+ 'id': 'KYJFJN',
+ 'template': "Duplicate import of '#{name}'.",
+ },
+
+ 'HIDDEN_IMPORT': {
+ 'id': 'ACRDPR',
+ 'template': "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
+ "from library '#{hidingUri}'.",
+ 'howToFix': "Try adding 'hide #{name}' to the import of '#{hiddenUri}'.",
+ 'examples': [
+ {
+ 'main.dart': """
+import 'dart:async'; // This imports a class Future.
+import 'future.dart';
+
+void main() => new Future();""",
+ 'future.dart': """
+library future;
+
+class Future {}"""
+ },
+ {
+ 'main.dart': """
+import 'future.dart';
+import 'dart:async'; // This imports a class Future.
+
+void main() => new Future();""",
+ 'future.dart': """
+library future;
+
+class Future {}"""
+ },
+ {
+ 'main.dart': """
+import 'export.dart';
+import 'dart:async'; // This imports a class Future.
+
+void main() => new Future();""",
+ 'future.dart': """
+library future;
+
+class Future {}""",
+ 'export.dart': """
+library export;
+
+export 'future.dart';"""
+ },
+ {
+ 'main.dart': """
+import 'future.dart' as prefix;
+import 'dart:async' as prefix; // This imports a class Future.
+
+void main() => new prefix.Future();""",
+ 'future.dart': """
+library future;
+
+class Future {}"""
+ }
+ ],
+ },
+
+ 'HIDDEN_IMPLICIT_IMPORT': {
+ 'id': 'WDNFSI',
+ 'template': "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
+ "from library '#{hidingUri}'.",
+ 'howToFix': "Try adding an explicit "
+ "'import \"#{hiddenUri}\" hide #{name}'.",
+ 'examples': [
+ {
+ 'main.dart': """
+// This hides the implicit import of class Type from dart:core.
+import 'type.dart';
+
+void main() => new Type();""",
+ 'type.dart': """
+library type;
+
+class Type {}"""
+ },
+ {
+ 'conflictsWithDart.dart': """
+library conflictsWithDart;
+
+class Duration {
+static var x = 100;
+}
+""",
+ 'conflictsWithDartAsWell.dart': """
+library conflictsWithDartAsWell;
+
+class Duration {
+static var x = 100;
+}
+""",
+ 'main.dart': r"""
+library testDartConflicts;
+
+import 'conflictsWithDart.dart';
+import 'conflictsWithDartAsWell.dart';
+
+main() {
+print("Hail Caesar ${Duration.x}");
+}
+"""
+ }
+ ],
+ },
+
+ 'DUPLICATE_EXPORT': {
+ 'id': 'XGNOCL',
+ 'template': "Duplicate export of '#{name}'.",
+ 'howToFix': "Try adding 'hide #{name}' to one of the exports.",
+ 'examples': [
+ {
+ 'main.dart': """
+export 'decl1.dart';
+export 'decl2.dart';
+
+main() {}""",
+ 'decl1.dart': "class Class {}",
+ 'decl2.dart': "class Class {}"
+ }
+ ],
+ },
+
+ 'DUPLICATE_EXPORT_CONT': {
+ 'id': 'BDROED',
+ 'template': "This is another export of '#{name}'.",
+ },
+
+ 'DUPLICATE_EXPORT_DECL': {
+ 'id': 'GFFLMA',
+ 'template':
+ "The exported '#{name}' from export #{uriString} is defined here.",
+ },
+
+ 'EMPTY_HIDE': {
+ 'id': 'ODFAOC',
+ 'template': "Library '#{uri}' doesn't export a '#{name}' declaration.",
+ 'howToFix': "Try removing '#{name}' the 'hide' clause.",
+ 'examples': [
+ {
+ 'main.dart': """
+import 'dart:core' hide Foo;
+
+main() {}"""
+ },
+ {
+ 'main.dart': """
+export 'dart:core' hide Foo;
+
+main() {}"""
+ },
+ ],
+ },
+
+ 'EMPTY_SHOW': {
+ 'id': 'EXONIK',
+ 'template': "Library '#{uri}' doesn't export a '#{name}' declaration.",
+ 'howToFix': "Try removing '#{name}' from the 'show' clause.",
+ 'examples': [
+ {
+ 'main.dart': """
+import 'dart:core' show Foo;
+
+main() {}"""
+ },
+ {
+ 'main.dart': """
+export 'dart:core' show Foo;
+
+main() {}"""
+ },
+ ],
+ },
+
+ 'NOT_A_TYPE': {'id': 'CTTAXD', 'template': "'#{node}' is not a type.",},
+
+ 'NOT_A_PREFIX': {'id': 'LKEUMI', 'template': "'#{node}' is not a prefix.",},
+
+ 'PREFIX_AS_EXPRESSION': {
+ 'id': 'CYIMBJ',
+ 'template': "Library prefix '#{prefix}' is not a valid expression.",
+ },
+
+ 'CANNOT_FIND_CONSTRUCTOR': {
+ 'id': 'DROVNH',
+ 'template': "Cannot find constructor '#{constructorName}' in class "
+ "'#{className}'.",
+ },
+
+ 'CANNOT_FIND_UNNAMED_CONSTRUCTOR': {
+ 'id': 'GDCTGB',
+ 'template': "Cannot find unnamed constructor in class "
+ "'#{className}'.",
+ },
+
+ 'CYCLIC_CLASS_HIERARCHY': {
+ 'id': 'HKFYOA',
+ 'template': "'#{className}' creates a cycle in the class hierarchy.",
+ },
+
+ 'CYCLIC_REDIRECTING_FACTORY': {
+ 'id': 'QGETJC',
+ 'template': "Redirecting factory leads to a cyclic redirection.",
+ },
+
+ 'INVALID_RECEIVER_IN_INITIALIZER': {
+ 'id': 'SYUTHA',
+ 'template': "Field initializer expected.",
+ },
+
+ 'NO_SUPER_IN_STATIC': {
+ 'id': 'HSCESG',
+ 'template': "'super' is only available in instance methods.",
+ },
+
+ 'DUPLICATE_INITIALIZER': {
+ 'id': 'GKVFEP',
+ 'template': "Field '#{fieldName}' is initialized more than once.",
+ },
+
+ 'ALREADY_INITIALIZED': {
+ 'id': 'NCRMVD',
+ 'template': "'#{fieldName}' was already initialized here.",
+ },
+
+ 'INIT_STATIC_FIELD': {
+ 'id': 'DBSRHA',
+ 'template': "Cannot initialize static field '#{fieldName}'.",
+ },
+
+ 'NOT_A_FIELD': {
+ 'id': 'FYEPLC',
+ 'template': "'#{fieldName}' is not a field.",
+ },
+
+ 'CONSTRUCTOR_CALL_EXPECTED': {
+ 'id': 'GEJCDX',
+ 'template': "only call to 'this' or 'super' constructor allowed.",
+ },
+
+ 'INVALID_FOR_IN': {
+ 'id': 'AUQJBG',
+ 'template': "Invalid for-in variable declaration.",
+ },
+
+ 'INVALID_INITIALIZER': {'id': 'JKUKSA', 'template': "Invalid initializer.",},
+
+ 'FUNCTION_WITH_INITIALIZER': {
+ 'id': 'BNRDDK',
+ 'template': "Only constructors can have initializers.",
+ },
+
+ 'REDIRECTING_CONSTRUCTOR_CYCLE': {
+ 'id': 'CQTMEP',
+ 'template': "Cyclic constructor redirection.",
+ },
+
+ 'REDIRECTING_CONSTRUCTOR_HAS_BODY': {
+ 'id': 'WXJQNE',
+ 'template': "Redirecting constructor can't have a body.",
+ },
+
+ 'CONST_CONSTRUCTOR_HAS_BODY': {
+ 'id': 'GNEFQG',
+ 'template': "Const constructor or factory can't have a body.",
+ 'howToFix': "Remove the 'const' keyword or the body",
+ 'examples': [
+ """
+class C {
+const C() {}
+}
+
+main() => new C();"""
+ ],
+ },
+
+ 'REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER': {
+ 'id': 'NUIDSF',
+ 'template': "Redirecting constructor cannot have other initializers.",
+ },
+
+ 'SUPER_INITIALIZER_IN_OBJECT': {
+ 'id': 'DXYGND',
+ 'template': "'Object' cannot have a super initializer.",
+ },
+
+ 'DUPLICATE_SUPER_INITIALIZER': {
+ 'id': 'FFKOWP',
+ 'template': "Cannot have more than one super initializer.",
+ },
+
+ 'SUPER_CALL_TO_FACTORY': {
+ 'id': 'YTOWGV',
+ 'template': "The target of the superinitializer must be a generative "
+ "constructor.",
+ 'howToFix': "Try calling another constructor on the superclass.",
+ 'examples': [
+ """
+class Super {
+factory Super() => null;
+}
+class Class extends Super {}
+main() => new Class();
+""",
+ """
+class Super {
+factory Super() => null;
+}
+class Class extends Super {
+Class();
+}
+main() => new Class();
+""",
+ """
+class Super {
+factory Super() => null;
+}
+class Class extends Super {
+Class() : super();
+}
+main() => new Class();
+""",
+ """
+class Super {
+factory Super.foo() => null;
+}
+class Class extends Super {
+Class() : super.foo();
+}
+main() => new Class();
+"""
+ ],
+ },
+
+ 'THIS_CALL_TO_FACTORY': {
+ 'id': 'JLATDB',
+ 'template': "The target of the redirection clause must be a generative "
+ "constructor",
+ 'howToFix': "Try redirecting to another constructor.",
+ 'examples': [
+ """
+class Class {
+factory Class() => null;
+Class.foo() : this();
+}
+main() => new Class.foo();
+""",
+ """
+class Class {
+factory Class.foo() => null;
+Class() : this.foo();
+}
+main() => new Class();
+"""
+ ],
+ },
+
+ 'INVALID_CONSTRUCTOR_ARGUMENTS': {
+ 'id': 'WVPLKL',
+ 'template': "Arguments do not match the expected parameters of constructor "
+ "'#{constructorName}'.",
+ },
+
+ 'NO_MATCHING_CONSTRUCTOR': {
+ 'id': 'OJQQLE',
+ 'template':
+ "'super' call arguments and constructor parameters do not match.",
+ },
+
+ 'NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT': {
+ 'id': 'WHCVID',
+ 'template': "Implicit 'super' call arguments and constructor parameters "
+ "do not match.",
+ },
+
+ 'CONST_CALLS_NON_CONST': {
+ 'id': 'CQFHXC',
+ 'template': "'const' constructor cannot call a non-const constructor.",
+ },
+
+ 'CONST_CALLS_NON_CONST_FOR_IMPLICIT': {
+ 'id': 'SFCEXS',
+ 'template': "'const' constructor cannot call a non-const constructor. "
+ "This constructor has an implicit call to a "
+ "super non-const constructor.",
+ 'howToFix': "Try making the super constructor const.",
+ 'examples': [
+ """
+class C {
+C(); // missing const
+}
+class D extends C {
+final d;
+const D(this.d);
+}
+main() => new D(0);"""
+ ],
+ },
+
+ 'CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS': {
+ 'id': 'XBHUDL',
+ 'template': "Can't declare constructor 'const' on class #{className} "
+ "because the class contains non-final instance fields.",
+ 'howToFix': "Try making all fields final.",
+ 'examples': [
+ """
+class C {
+// 'a' must be declared final to allow for the const constructor.
+var a;
+const C(this.a);
+}
+
+main() => new C(0);"""
+ ],
+ },
+
+ 'CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD': {
+ 'id': 'YYAHVD',
+ 'template': "This non-final field prevents using const constructors.",
+ },
+
+ 'CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR': {
+ 'id': 'FROWJB',
+ 'template': "This const constructor is not allowed due to "
+ "non-final fields.",
+ },
+
+ 'INITIALIZING_FORMAL_NOT_ALLOWED': {
+ 'id': 'YIPXYP',
+ 'template': "Initializing formal parameter only allowed in generative "
+ "constructor.",
+ },
+
+ 'INVALID_PARAMETER': {
+ 'id': 'OWWLIX',
+ 'template': "Cannot resolve parameter.",
+ },
+
+ 'NOT_INSTANCE_FIELD': {
+ 'id': 'VSPKMU',
+ 'template': "'#{fieldName}' is not an instance field.",
+ },
+
+ 'THIS_PROPERTY': {'id': 'MWFIGH', 'template': "Expected an identifier.",},
+
+ 'NO_CATCH_NOR_FINALLY': {
+ 'id': 'OPJXPP',
+ 'template': "Expected 'catch' or 'finally'.",
+ },
+
+ 'EMPTY_CATCH_DECLARATION': {
+ 'id': 'UNHCPY',
+ 'template': "Expected an identifier in catch declaration.",
+ },
+
+ 'EXTRA_CATCH_DECLARATION': {
+ 'id': 'YGGRAK',
+ 'template': "Extra parameter in catch declaration.",
+ },
+
+ 'PARAMETER_WITH_TYPE_IN_CATCH': {
+ 'id': 'EXQVDU',
+ 'template': "Cannot use type annotations in catch.",
+ },
+
+ 'PARAMETER_WITH_MODIFIER_IN_CATCH': {
+ 'id': 'BQLKRF',
+ 'template': "Cannot use modifiers in catch.",
+ },
+
+ 'OPTIONAL_PARAMETER_IN_CATCH': {
+ 'id': 'DAICPP',
+ 'template': "Cannot use optional parameters in catch.",
+ },
+
+ 'THROW_WITHOUT_EXPRESSION': {
+ 'id': 'YHACYV',
+ 'template': "Cannot use re-throw outside of catch block "
+ "(expression expected after 'throw').",
+ },
+
+ 'UNBOUND_LABEL': {
+ 'id': 'GLDXHY',
+ 'template': "Cannot resolve label '#{labelName}'.",
+ },
+
+ 'NO_BREAK_TARGET': {
+ 'id': 'VBXXBE',
+ 'template': "'break' statement not inside switch or loop.",
+ },
+
+ 'NO_CONTINUE_TARGET': {
+ 'id': 'JTTHHM',
+ 'template': "'continue' statement not inside loop.",
+ },
+
+ 'EXISTING_LABEL': {
+ 'id': 'AHCSXF',
+ 'template': "Original declaration of duplicate label '#{labelName}'.",
+ },
+
+ 'DUPLICATE_LABEL': {
+ 'id': 'HPULLI',
+ 'template': "Duplicate declaration of label '#{labelName}'.",
+ },
+
+ 'UNUSED_LABEL': {'id': 'KFREJO', 'template': "Unused label '#{labelName}'.",},
+
+ 'INVALID_CONTINUE': {
+ 'id': 'DSKTPX',
+ 'template': "Target of continue is not a loop or switch case.",
+ },
+
+ 'INVALID_BREAK': {
+ 'id': 'MFCCWX',
+ 'template': "Target of break is not a statement.",
+ },
+
+ 'DUPLICATE_TYPE_VARIABLE_NAME': {
+ 'id': 'BAYCCM',
+ 'template': "Type variable '#{typeVariableName}' already declared.",
+ },
+
+ 'TYPE_VARIABLE_WITHIN_STATIC_MEMBER': {
+ 'id': 'XQLXRL',
+ 'template': "Cannot refer to type variable '#{typeVariableName}' "
+ "within a static member.",
+ },
+
+ 'TYPE_VARIABLE_IN_CONSTANT': {
+ 'id': 'ANDEVG',
+ 'template': "Constant expressions can't refer to type variables.",
+ 'howToFix': "Try removing the type variable or replacing it with a "
+ "concrete type.",
+ 'examples': [
+ """
+class C<T> {
+const C();
+
+m(T t) => const C<T>();
+}
+
+void main() => new C().m(null);
+"""
+ ],
+ },
+
+ 'INVALID_TYPE_VARIABLE_BOUND': {
+ 'id': 'WQAEDK',
+ 'template': "'#{typeArgument}' is not a subtype of bound '#{bound}' for "
+ "type variable '#{typeVariable}' of type '#{thisType}'.",
+ 'howToFix': "Try to change or remove the type argument.",
+ 'examples': [
+ """
+class C<T extends num> {}
+
+// 'String' is not a valid instantiation of T with bound num.'.
+main() => new C<String>();
+"""
+ ],
+ },
+
+ 'INVALID_USE_OF_SUPER': {
+ 'id': 'JKYYSN',
+ 'template': "'super' not allowed here.",
+ },
+
+ 'INVALID_CASE_DEFAULT': {
+ 'id': 'ABSPBM',
+ 'template': "'default' only allowed on last case of a switch.",
+ },
+
+ 'SWITCH_CASE_TYPES_NOT_EQUAL': {
+ 'id': 'UFQPBC',
+ 'template': "'case' expressions do not all have type '#{type}'.",
+ },
+
+ 'SWITCH_CASE_TYPES_NOT_EQUAL_CASE': {
+ 'id': 'RDMVAC',
+ 'template': "'case' expression of type '#{type}'.",
+ },
+
+ 'SWITCH_CASE_FORBIDDEN': {
+ 'id': 'UHSCSU',
+ 'template': "'case' expression may not be of type '#{type}'.",
+ },
+
+ 'SWITCH_CASE_VALUE_OVERRIDES_EQUALS': {
+ 'id': 'NRTWXL',
+ 'template': "'case' expression type '#{type}' overrides 'operator =='.",
+ },
+
+ 'INVALID_ARGUMENT_AFTER_NAMED': {
+ 'id': 'WAJURC',
+ 'template': "Unnamed argument after named argument.",
+ },
+
+ 'NOT_A_COMPILE_TIME_CONSTANT': {
+ 'id': 'SBCHWL',
+ 'template': "Not a compile-time constant.",
+ },
+
+ 'DEFERRED_COMPILE_TIME_CONSTANT': {
+ 'id': 'FHXTCK',
+ 'template': "A deferred value cannot be used as a compile-time constant.",
+ },
+
+ 'DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION': {
+ 'id': 'TSBXLG',
+ 'template': "A deferred class cannot be used to create a "
+ "compile-time constant.",
+ },
+
+ 'CYCLIC_COMPILE_TIME_CONSTANTS': {
+ 'id': 'JJWJYE',
+ 'template': "Cycle in the compile-time constant computation.",
+ },
+
+ 'CONSTRUCTOR_IS_NOT_CONST': {
+ 'id': 'DOJCUX',
+ 'template': "Constructor is not a 'const' constructor.",
+ },
+
+ 'CONST_MAP_KEY_OVERRIDES_EQUALS': {
+ 'id': 'VJNWEL',
+ 'template': "Const-map key type '#{type}' overrides 'operator =='.",
+ },
+
+ 'NO_SUCH_LIBRARY_MEMBER': {
+ 'id': 'IOXVBA',
+ 'template': "'#{libraryName}' has no member named '#{memberName}'.",
+ },
+
+ 'CANNOT_INSTANTIATE_TYPEDEF': {
+ 'id': 'KOYNMU',
+ 'template': "Cannot instantiate typedef '#{typedefName}'.",
+ },
+
+ 'REQUIRED_PARAMETER_WITH_DEFAULT': {
+ 'id': 'CJWECI',
+ 'template': "Non-optional parameters can't have a default value.",
+ 'howToFix':
+ "Try removing the default value or making the parameter optional.",
+ 'examples': [
+ """
+main() {
+foo(a: 1) => print(a);
+foo(2);
+}""",
+ """
+main() {
+foo(a = 1) => print(a);
+foo(2);
+}"""
+ ],
+ },
+
+ 'NAMED_PARAMETER_WITH_EQUALS': {
+ 'id': 'RPJDXD',
+ 'template': "Named optional parameters can't use '=' to specify a default "
+ "value.",
+ 'howToFix': "Try replacing '=' with ':'.",
+ 'examples': [
+ """
+main() {
+foo({a = 1}) => print(a);
+foo(a: 2);
+}"""
+ ],
+ },
+
+ 'POSITIONAL_PARAMETER_WITH_EQUALS': {
+ 'id': 'JMSSDX',
+ 'template': "Positional optional parameters can't use ':' to specify a "
+ "default value.",
+ 'howToFix': "Try replacing ':' with '='.",
+ 'examples': [
+ """
+main() {
+foo([a: 1]) => print(a);
+foo(2);
+}"""
+ ],
+ },
+
+ 'TYPEDEF_FORMAL_WITH_DEFAULT': {
+ 'id': 'NABHHS',
+ 'template': "A parameter of a typedef can't specify a default value.",
+ 'howToFix': "Try removing the default value.",
+ 'examples': [
+ """
+typedef void F([int arg = 0]);
+
+main() {
+F f;
+}""",
+ """
+typedef void F({int arg: 0});
+
+main() {
+F f;
+}"""
+ ],
+ },
+
+ 'FUNCTION_TYPE_FORMAL_WITH_DEFAULT': {
+ 'id': 'APKYLU',
+ 'template': "A function type parameter can't specify a default value.",
+ 'howToFix': "Try removing the default value.",
+ 'examples': [
+ """
+foo(f(int i, [a = 1])) {}
+
+main() {
+foo(1, 2);
+}""",
+ """
+foo(f(int i, {a: 1})) {}
+
+main() {
+foo(1, a: 2);
+}"""
+ ],
+ },
+
+ 'REDIRECTING_FACTORY_WITH_DEFAULT': {
+ 'id': 'AWSSEY',
+ 'template':
+ "A parameter of a redirecting factory constructor can't specify a "
+ "default value.",
+ 'howToFix': "Try removing the default value.",
+ 'examples': [
+ """
+class A {
+A([a]);
+factory A.foo([a = 1]) = A;
+}
+
+main() {
+new A.foo(1);
+}""",
+ """
+class A {
+A({a});
+factory A.foo({a: 1}) = A;
+}
+
+main() {
+new A.foo(a: 1);
+}"""
+ ],
+ },
+
+ 'FORMAL_DECLARED_CONST': {
+ 'id': 'AVPRDK',
+ 'template': "A formal parameter can't be declared const.",
+ 'howToFix': "Try removing 'const'.",
+ 'examples': [
+ """
+foo(const x) {}
+main() => foo(42);
+""",
+ """
+foo({const x}) {}
+main() => foo(42);
+""",
+ """
+foo([const x]) {}
+main() => foo(42);
+"""
+ ],
+ },
+
+ 'FORMAL_DECLARED_STATIC': {
+ 'id': 'PJKDMX',
+ 'template': "A formal parameter can't be declared static.",
+ 'howToFix': "Try removing 'static'.",
+ 'examples': [
+ """
+foo(static x) {}
+main() => foo(42);
+""",
+ """
+foo({static x}) {}
+main() => foo(42);
+""",
+ """
+foo([static x]) {}
+main() => foo(42);
+"""
+ ],
+ },
+
+ 'FINAL_FUNCTION_TYPE_PARAMETER': {
+ 'id': 'JIOPIQ',
+ 'template': "A function type parameter can't be declared final.",
+ 'howToFix': "Try removing 'final'.",
+ 'examples': [
+ """
+foo(final int x(int a)) {}
+main() => foo((y) => 42);
+""",
+ """
+foo({final int x(int a)}) {}
+main() => foo((y) => 42);
+""",
+ """
+foo([final int x(int a)]) {}
+main() => foo((y) => 42);
+"""
+ ],
+ },
+
+ 'VAR_FUNCTION_TYPE_PARAMETER': {
+ 'id': 'FOQOHK',
+ 'template': "A function type parameter can't be declared with 'var'.",
+ 'howToFix': "Try removing 'var'.",
+ 'examples': [
+ """
+foo(var int x(int a)) {}
+main() => foo((y) => 42);
+""",
+ """
+foo({var int x(int a)}) {}
+main() => foo((y) => 42);
+""",
+ """
+foo([var int x(int a)]) {}
+main() => foo((y) => 42);
+"""
+ ],
+ },
+
+ 'CANNOT_INSTANTIATE_TYPE_VARIABLE': {
+ 'id': 'JAYHCH',
+ 'template': "Cannot instantiate type variable '#{typeVariableName}'.",
+ },
+
+ 'CYCLIC_TYPE_VARIABLE': {
+ 'id': 'RQMPSO',
+ 'template': "Type variable '#{typeVariableName}' is a supertype of itself.",
+ },
+
+ 'CYCLIC_TYPEDEF': {
+ 'id': 'VFERCQ',
+ 'template': "A typedef can't refer to itself.",
+ 'howToFix': "Try removing all references to '#{typedefName}' "
+ "in the definition of '#{typedefName}'.",
+ 'examples': [
+ """
+typedef F F(); // The return type 'F' is a self-reference.
+main() { F f = null; }"""
+ ],
+ },
+
+ 'CYCLIC_TYPEDEF_ONE': {
+ 'id': 'ASWLWR',
+ 'template': "A typedef can't refer to itself through another typedef.",
+ 'howToFix': "Try removing all references to "
+ "'#{otherTypedefName}' in the definition of '#{typedefName}'.",
+ 'examples': [
+ """
+typedef G F(); // The return type 'G' is a self-reference through typedef 'G'.
+typedef F G(); // The return type 'F' is a self-reference through typedef 'F'.
+main() { F f = null; }""",
+ """
+typedef G F(); // The return type 'G' creates a self-reference.
+typedef H G(); // The return type 'H' creates a self-reference.
+typedef H(F f); // The argument type 'F' creates a self-reference.
+main() { F f = null; }"""
+ ],
+ },
+
+ 'CLASS_NAME_EXPECTED': {'id': 'DPKNHY', 'template': "Class name expected.",},
+
+ 'CANNOT_EXTEND': {
+ 'id': 'GCIQXD',
+ 'template': "'#{type}' cannot be extended.",
+ },
+
+ 'CANNOT_IMPLEMENT': {
+ 'id': 'IBOQKV',
+ 'template': "'#{type}' cannot be implemented.",
+ },
+
+ // TODO(johnnwinther): Split messages into reasons for malformedness.
+ 'CANNOT_EXTEND_MALFORMED': {
+ 'id': 'YPFJBD',
+ 'template': "Class '#{className}' can't extend the type '#{malformedType}' "
+ "because it is malformed.",
+ 'howToFix': "Try correcting the malformed type annotation or removing the "
+ "'extends' clause.",
+ 'examples': [
+ """
+class A extends Malformed {}
+main() => new A();"""
+ ],
+ },
+
+ 'CANNOT_IMPLEMENT_MALFORMED': {
+ 'id': 'XJUIAQ',
+ 'template':
+ "Class '#{className}' can't implement the type '#{malformedType}' "
+ "because it is malformed.",
+ 'howToFix': "Try correcting the malformed type annotation or removing the "
+ "type from the 'implements' clause.",
+ 'examples': [
+ """
+class A implements Malformed {}
+main() => new A();"""
+ ],
+ },
+
+ 'CANNOT_MIXIN_MALFORMED': {
+ 'id': 'SSMNXN',
+ 'template': "Class '#{className}' can't mixin the type '#{malformedType}' "
+ "because it is malformed.",
+ 'howToFix': "Try correcting the malformed type annotation or removing the "
+ "type from the 'with' clause.",
+ 'examples': [
+ """
+class A extends Object with Malformed {}
+main() => new A();"""
+ ],
+ },
+
+ 'CANNOT_MIXIN': {
+ 'id': 'KLSXDQ',
+ 'template': "The type '#{type}' can't be mixed in.",
+ 'howToFix': "Try removing '#{type}' from the 'with' clause.",
+ 'examples': [
+ """
+class C extends Object with String {}
+
+main() => new C();
+""",
+ """
+typedef C = Object with String;
+
+main() => new C();
+"""
+ ],
+ },
+
+ 'CANNOT_EXTEND_ENUM': {
+ 'id': 'JEPRST',
+ 'template':
+ "Class '#{className}' can't extend the type '#{enumType}' because "
+ "it is declared by an enum.",
+ 'howToFix': "Try making '#{enumType}' a normal class or removing the "
+ "'extends' clause.",
+ 'examples': [
+ """
+enum Enum { A }
+class B extends Enum {}
+main() => new B();"""
+ ],
+ },
+
+ 'CANNOT_IMPLEMENT_ENUM': {
+ 'id': 'JMJMSH',
+ 'template': "Class '#{className}' can't implement the type '#{enumType}' "
+ "because it is declared by an enum.",
+ 'howToFix': "Try making '#{enumType}' a normal class or removing the "
+ "type from the 'implements' clause.",
+ 'examples': [
+ """
+enum Enum { A }
+class B implements Enum {}
+main() => new B();"""
+ ],
+ },
+
+ 'CANNOT_MIXIN_ENUM': {
+ 'id': 'YSYDIM',
+ 'template':
+ "Class '#{className}' can't mixin the type '#{enumType}' because it "
+ "is declared by an enum.",
+ 'howToFix': "Try making '#{enumType}' a normal class or removing the "
+ "type from the 'with' clause.",
+ 'examples': [
+ """
+enum Enum { A }
+class B extends Object with Enum {}
+main() => new B();"""
+ ],
+ },
+
+ 'CANNOT_INSTANTIATE_ENUM': {
+ 'id': 'CQYIFU',
+ 'template': "Enum type '#{enumName}' cannot be instantiated.",
+ 'howToFix': "Try making '#{enumType}' a normal class or use an enum "
+ "constant.",
+ 'examples': [
+ """
+enum Enum { A }
+main() => new Enum(0);""",
+ """
+enum Enum { A }
+main() => const Enum(0);"""
+ ],
+ },
+
+ 'EMPTY_ENUM_DECLARATION': {
+ 'id': 'JFPDOH',
+ 'template': "Enum '#{enumName}' must contain at least one value.",
+ 'howToFix': "Try adding an enum constant or making #{enumName} a "
+ "normal class.",
+ 'examples': [
+ """
+enum Enum {}
+main() { Enum e; }"""
+ ],
+ },
+
+ 'MISSING_ENUM_CASES': {
+ 'id': 'HHEOIW',
+ 'template': "Missing enum constants in switch statement: #{enumValues}.",
+ 'howToFix': "Try adding the missing constants or a default case.",
+ 'examples': [
+ """
+enum Enum { A, B }
+main() {
+switch (Enum.A) {
+case Enum.B: break;
+}
+}""",
+ """
+enum Enum { A, B, C }
+main() {
+switch (Enum.A) {
+case Enum.B: break;
+}
+}"""
+ ],
+ },
+
+ 'DUPLICATE_EXTENDS_IMPLEMENTS': {
+ 'id': 'BKRKEO',
+ 'template': "'#{type}' can not be both extended and implemented.",
+ },
+
+ 'DUPLICATE_IMPLEMENTS': {
+ 'id': 'IWJFTU',
+ 'template': "'#{type}' must not occur more than once "
+ "in the implements clause.",
+ },
+
+ 'MULTI_INHERITANCE': {
+ 'id': 'NWXGOI',
+ 'template':
+ "Dart2js does not currently support inheritance of the same class "
+ "with different type arguments: Both #{firstType} and #{secondType} "
+ "are supertypes of #{thisType}.",
+ },
+
+ 'ILLEGAL_SUPER_SEND': {
+ 'id': 'LDRGIU',
+ 'template': "'#{name}' cannot be called on super.",
+ },
+
+ 'NO_SUCH_SUPER_MEMBER': {
+ 'id': 'HIJJVG',
+ 'template':
+ "Cannot resolve '#{memberName}' in a superclass of '#{className}'.",
+ },
+
+ 'ADDITIONAL_TYPE_ARGUMENT': {
+ 'id': 'HWYHWH',
+ 'template': "Additional type argument.",
+ },
+
+ 'MISSING_TYPE_ARGUMENT': {
+ 'id': 'KYTQWA',
+ 'template': "Missing type argument.",
+ },
+
+ // TODO(johnniwinther): Use ADDITIONAL_TYPE_ARGUMENT or
+ // MISSING_TYPE_ARGUMENT instead.
+ 'TYPE_ARGUMENT_COUNT_MISMATCH': {
+ 'id': 'ECXGRM',
+ 'template': "Incorrect number of type arguments on '#{type}'.",
+ },
+
+ 'GETTER_MISMATCH': {
+ 'id': 'MNODFW',
+ 'template': "Setter disagrees on: '#{modifiers}'.",
+ },
+
+ 'SETTER_MISMATCH': {
+ 'id': 'FMNHPL',
+ 'template': "Getter disagrees on: '#{modifiers}'.",
+ },
+
+ 'ILLEGAL_SETTER_FORMALS': {
+ 'id': 'COTPVN',
+ 'template': "A setter must have exactly one argument.",
+ },
+
+ 'NO_STATIC_OVERRIDE': {
+ 'id': 'EHINXB',
+ 'template':
+ "Static member cannot override instance member '#{memberName}' of "
+ "'#{className}'.",
+ },
+
+ 'NO_STATIC_OVERRIDE_CONT': {
+ 'id': 'TEVJMA',
+ 'template': "This is the instance member that cannot be overridden "
+ "by a static member.",
+ },
+
+ 'INSTANCE_STATIC_SAME_NAME': {
+ 'id': 'LTBFBO',
+ 'template': "Instance member '#{memberName}' and static member of "
+ "superclass '#{className}' have the same name.",
+ },
+
+ 'INSTANCE_STATIC_SAME_NAME_CONT': {
+ 'id': 'CHSUCQ',
+ 'template': "This is the static member with the same name.",
+ },
+
+ 'INVALID_OVERRIDE_METHOD': {
+ 'id': 'NINKPI',
+ 'template': "The type '#{declaredType}' of method '#{name}' declared in "
+ "'#{class}' is not a subtype of the overridden method type "
+ "'#{inheritedType}' inherited from '#{inheritedClass}'.",
+ },
+
+ 'INVALID_OVERRIDDEN_METHOD': {
+ 'id': 'BQHUPY',
+ 'template': "This is the overridden method '#{name}' declared in class "
+ "'#{class}'.",
+ },
+
+ 'INVALID_OVERRIDE_GETTER': {
+ 'id': 'KLMPWO',
+ 'template': "The type '#{declaredType}' of getter '#{name}' declared in "
+ "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+ "overridden getter inherited from '#{inheritedClass}'.",
+ },
+
+ 'INVALID_OVERRIDDEN_GETTER': {
+ 'id': 'ASSKCT',
+ 'template': "This is the overridden getter '#{name}' declared in class "
+ "'#{class}'.",
+ },
+
+ 'INVALID_OVERRIDE_GETTER_WITH_FIELD': {
+ 'id': 'TCCGXU',
+ 'template': "The type '#{declaredType}' of field '#{name}' declared in "
+ "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+ "overridden getter inherited from '#{inheritedClass}'.",
+ },
+
+ 'INVALID_OVERRIDE_FIELD_WITH_GETTER': {
+ 'id': 'UMMEXO',
+ 'template': "The type '#{declaredType}' of getter '#{name}' declared in "
+ "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+ "overridden field inherited from '#{inheritedClass}'.",
+ },
+
+ 'INVALID_OVERRIDE_SETTER': {
+ 'id': 'BWRGEC',
+ 'template': "The type '#{declaredType}' of setter '#{name}' declared in "
+ "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+ "overridden setter inherited from '#{inheritedClass}'.",
+ },
+
+ 'INVALID_OVERRIDDEN_SETTER': {
+ 'id': 'XQUOLL',
+ 'template': "This is the overridden setter '#{name}' declared in class "
+ "'#{class}'.",
+ },
+
+ 'INVALID_OVERRIDE_SETTER_WITH_FIELD': {
+ 'id': 'GKGOFA',
+ 'template': "The type '#{declaredType}' of field '#{name}' declared in "
+ "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+ "overridden setter inherited from '#{inheritedClass}'.",
+ },
+
+ 'INVALID_OVERRIDE_FIELD_WITH_SETTER': {
+ 'id': 'OOXKHQ',
+ 'template': "The type '#{declaredType}' of setter '#{name}' declared in "
+ "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+ "overridden field inherited from '#{inheritedClass}'.",
+ },
+
+ 'INVALID_OVERRIDE_FIELD': {
+ 'id': 'LDPKOL',
+ 'template': "The type '#{declaredType}' of field '#{name}' declared in "
+ "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+ "overridden field inherited from '#{inheritedClass}'.",
+ },
+
+ 'INVALID_OVERRIDDEN_FIELD': {
+ 'id': 'UNQFWX',
+ 'template': "This is the overridden field '#{name}' declared in class "
+ "'#{class}'.",
+ },
+
+ 'CANNOT_OVERRIDE_FIELD_WITH_METHOD': {
+ 'id': 'SYKCSK',
+ 'template': "Method '#{name}' in '#{class}' can't override field from "
+ "'#{inheritedClass}'.",
+ },
+
+ 'CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT': {
+ 'id': 'HYHQSO',
+ 'template': "This is the field that cannot be overridden by a method.",
+ },
+
+ 'CANNOT_OVERRIDE_METHOD_WITH_FIELD': {
+ 'id': 'UROMAS',
+ 'template': "Field '#{name}' in '#{class}' can't override method from "
+ "'#{inheritedClass}'.",
+ },
+
+ 'CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT': {
+ 'id': 'NSORYS',
+ 'template': "This is the method that cannot be overridden by a field.",
+ },
+
+ 'CANNOT_OVERRIDE_GETTER_WITH_METHOD': {
+ 'id': 'MMFIOH',
+ 'template': "Method '#{name}' in '#{class}' can't override getter from "
+ "'#{inheritedClass}'.",
+ },
+
+ 'CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT': {
+ 'id': 'YGWPDH',
+ 'template': "This is the getter that cannot be overridden by a method.",
+ },
+
+ 'CANNOT_OVERRIDE_METHOD_WITH_GETTER': {
+ 'id': 'BNKNXO',
+ 'template': "Getter '#{name}' in '#{class}' can't override method from "
+ "'#{inheritedClass}'.",
+ },
+
+ 'CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT': {
+ 'id': 'KFBCYX',
+ 'template': "This is the method that cannot be overridden by a getter.",
+ },
+
+ 'MISSING_FORMALS': {
+ 'id': 'BOERAF',
+ 'template': "Formal parameters are missing.",
+ },
+
+ 'EXTRA_FORMALS': {
+ 'id': 'UTWRIU',
+ 'template': "Formal parameters are not allowed here.",
+ },
+
+ 'UNARY_OPERATOR_BAD_ARITY': {
+ 'id': 'TNHLAL',
+ 'template': "Operator '#{operatorName}' must have no parameters.",
+ },
+
+ 'MINUS_OPERATOR_BAD_ARITY': {
+ 'id': 'SXDRRU',
+ 'template': "Operator '-' must have 0 or 1 parameters.",
+ },
+
+ 'BINARY_OPERATOR_BAD_ARITY': {
+ 'id': 'QKWAUM',
+ 'template': "Operator '#{operatorName}' must have exactly 1 parameter.",
+ },
+
+ 'TERNARY_OPERATOR_BAD_ARITY': {
+ 'id': 'LSMQGF',
+ 'template': "Operator '#{operatorName}' must have exactly 2 parameters.",
+ },
+
+ 'OPERATOR_OPTIONAL_PARAMETERS': {
+ 'id': 'HSGRBV',
+ 'template': "Operator '#{operatorName}' cannot have optional parameters.",
+ },
+
+ 'OPERATOR_NAMED_PARAMETERS': {
+ 'id': 'EACWGS',
+ 'template': "Operator '#{operatorName}' cannot have named parameters.",
+ },
+
+ 'CONSTRUCTOR_WITH_RETURN_TYPE': {
+ 'id': 'OPMBHF',
+ 'template': "Cannot have return type for constructor.",
+ },
+
+ 'CANNOT_RETURN_FROM_CONSTRUCTOR': {
+ 'id': 'NFUGNH',
+ 'template': "Constructors can't return values.",
+ 'howToFix': "Remove the return statement or use a factory constructor.",
+ 'examples': [
+ """
+class C {
+C() {
+ return 1;
+}
+}
+
+main() => new C();"""
+ ],
+ },
+
+ 'ILLEGAL_FINAL_METHOD_MODIFIER': {
+ 'id': 'YUKCVU',
+ 'template': "Cannot have final modifier on method.",
+ },
+
+ 'ILLEGAL_CONST_FIELD_MODIFIER': {
+ 'id': 'JGFAGV',
+ 'template': "Cannot have const modifier on non-static field.",
+ 'howToFix': "Try adding a static modifier, or removing the const modifier.",
+ 'examples': [
+ """
+class C {
+const int a = 1;
+}
+
+main() => new C();"""
+ ],
+ },
+
+ 'ILLEGAL_CONSTRUCTOR_MODIFIERS': {
+ 'id': 'WODRHN',
+ 'template': "Illegal constructor modifiers: '#{modifiers}'.",
+ },
+
+ 'ILLEGAL_MIXIN_APPLICATION_MODIFIERS': {
+ 'id': 'OFLFHN',
+ 'template': "Illegal mixin application modifiers: '#{modifiers}'.",
+ },
+
+ 'ILLEGAL_MIXIN_SUPERCLASS': {
+ 'id': 'TPVVYN',
+ 'template': "Class used as mixin must have Object as superclass.",
+ },
+
+ 'ILLEGAL_MIXIN_OBJECT': {
+ 'id': 'CMVTLF',
+ 'template': "Cannot use Object as mixin.",
+ },
+
+ 'ILLEGAL_MIXIN_CONSTRUCTOR': {
+ 'id': 'HXBUIB',
+ 'template': "Class used as mixin cannot have non-factory constructor.",
+ },
+
+ 'ILLEGAL_MIXIN_CYCLE': {
+ 'id': 'ANXAMU',
+ 'template': "Class used as mixin introduces mixin cycle: "
+ "'#{mixinName1}' <-> '#{mixinName2}'.",
+ },
+
+ 'ILLEGAL_MIXIN_WITH_SUPER': {
+ 'id': 'KIEUGK',
+ 'template': "Cannot use class '#{className}' as a mixin because it uses "
+ "'super'.",
+ },
+
+ 'ILLEGAL_MIXIN_SUPER_USE': {
+ 'id': 'QKUPLH',
+ 'template': "Use of 'super' in class used as mixin.",
+ },
+
+ 'PARAMETER_NAME_EXPECTED': {
+ 'id': 'JOUOBT',
+ 'template': "parameter name expected.",
+ },
+
+ 'CANNOT_RESOLVE_GETTER': {
+ 'id': 'TDHKSW',
+ 'template': "Cannot resolve getter.",
+ },
+
+ 'CANNOT_RESOLVE_SETTER': {
+ 'id': 'QQFANP',
+ 'template': "Cannot resolve setter.",
+ },
+
+ 'ASSIGNING_FINAL_FIELD_IN_SUPER': {
+ 'id': 'LXUPCC',
+ 'template': "Cannot assign a value to final field '#{name}' "
+ "in superclass '#{superclassName}'.",
+ },
+
+ 'ASSIGNING_METHOD': {
+ 'id': 'JUVMYC',
+ 'template': "Cannot assign a value to a method.",
+ },
+
+ 'ASSIGNING_METHOD_IN_SUPER': {
+ 'id': 'AGMAXN',
+ 'template': "Cannot assign a value to method '#{name}' "
+ "in superclass '#{superclassName}'.",
+ },
+
+ 'ASSIGNING_TYPE': {
+ 'id': 'VXTPWE',
+ 'template': "Cannot assign a value to a type.",
+ },
+
+ 'IF_NULL_ASSIGNING_TYPE': {
+ 'id': 'XBRHGK',
+ 'template':
+ "Cannot assign a value to a type. Note that types are never null, "
+ "so this ??= assignment has no effect.",
+ 'howToFix': "Try removing the '??=' assignment.",
+ 'examples': ["class A {} main() { print(A ??= 3);}",],
+ },
+
+ 'VOID_NOT_ALLOWED': {
+ 'id': 'DMMDXT',
+ 'template':
+ "Type 'void' can't be used here because it isn't a return type.",
+ 'howToFix':
+ "Try removing 'void' keyword or replace it with 'var', 'final', "
+ "or a type.",
+ 'examples': ["void x; main() {}", "foo(void x) {} main() { foo(null); }",],
+ },
+
+ 'NULL_NOT_ALLOWED': {
+ 'id': 'STYNSK',
+ 'template': "`null` can't be used here.",
+ },
+
+ 'BEFORE_TOP_LEVEL': {
+ 'id': 'GRCXQF',
+ 'template': "Part header must come before top-level definitions.",
+ },
+
+ 'IMPORT_PART_OF': {
+ 'id': 'VANCWE',
+ 'template': "The imported library must not have a 'part-of' directive.",
+ 'howToFix': "Try removing the 'part-of' directive or replacing the "
+ "import of the library with a 'part' directive.",
+ 'examples': [
+ {
+ 'main.dart': """
+library library;
+
+import 'part.dart';
+
+main() {}
+""",
+ 'part.dart': """
+part of library;
+"""
+ }
+ ],
+ },
+
+ 'IMPORT_PART_OF_HERE': {
+ 'id': 'TRSZOJ',
+ 'template': 'The library is imported here.',
+ },
+
+ 'LIBRARY_NAME_MISMATCH': {
+ 'id': 'AXGYPQ',
+ 'template': "Expected part of library name '#{libraryName}'.",
+ 'howToFix': "Try changing the directive to 'part of #{libraryName};'.",
+ 'examples': [
+ {
+ 'main.dart': """
+library lib.foo;
+
+part 'part.dart';
+
+main() {}
+""",
+ 'part.dart': """
+part of lib.bar;
+"""
+ }
+ ],
+ },
+
+ 'MISSING_LIBRARY_NAME': {
+ 'id': 'NYQNCA',
+ 'template': "Library has no name. Part directive expected library name "
+ "to be '#{libraryName}'.",
+ 'howToFix': "Try adding 'library #{libraryName};' to the library.",
+ 'examples': [
+ {
+ 'main.dart': """
+part 'part.dart';
+
+main() {}
+""",
+ 'part.dart': """
+part of lib.foo;
+"""
+ }
+ ],
+ },
+
+ 'THIS_IS_THE_PART_OF_TAG': {
+ 'id': 'RPSJRS',
+ 'template': "This is the part of directive.",
+ },
+
+ 'MISSING_PART_OF_TAG': {
+ 'id': 'QNYCMV',
+ 'template': "This file has no part-of tag, but it is being used as a part.",
+ },
+
+ 'DUPLICATED_PART_OF': {
+ 'id': 'UJDYHF',
+ 'template': "Duplicated part-of directive.",
+ },
+
+ 'DUPLICATED_LIBRARY_NAME': {
+ 'id': 'OSEHXI',
+ 'template': "Duplicated library name '#{libraryName}'.",
+ },
+
+ 'DUPLICATED_RESOURCE': {
+ 'id': 'UFWKBY',
+ 'template': "The resource '#{resourceUri}' is loaded through both "
+ "'#{canonicalUri1}' and '#{canonicalUri2}'.",
+ },
+
+ 'DUPLICATED_LIBRARY_RESOURCE': {
+ 'id': 'KYGYTT',
+ 'template':
+ "The library '#{libraryName}' in '#{resourceUri}' is loaded through "
+ "both '#{canonicalUri1}' and '#{canonicalUri2}'.",
+ },
+
+ // This is used as an exception.
+ 'INVALID_SOURCE_FILE_LOCATION': {
+ 'id': 'WIGJFG',
+ 'template': """
+Invalid offset (#{offset}) in source map.
+File: #{fileName}
+Length: #{length}""",
+ },
+
+ 'TOP_LEVEL_VARIABLE_DECLARED_STATIC': {
+ 'id': 'IVNDML',
+ 'template': "Top-level variable cannot be declared static.",
+ },
+
+ 'REFERENCE_IN_INITIALIZATION': {
+ 'id': 'OVWTEU',
+ 'template': "Variable '#{variableName}' is referenced during its "
+ "initialization.",
+ 'howToFix': "If you are trying to reference a shadowed variable, rename "
+ "one of the variables.",
+ 'examples': [
+ """
+foo(t) {
+var t = t;
+return t;
+}
+
+main() => foo(1);
+"""
+ ],
+ },
+
+ 'CONST_WITHOUT_INITIALIZER': {
+ 'id': 'UDWCNH',
+ 'template': "A constant variable must be initialized.",
+ 'howToFix': "Try adding an initializer or "
+ "removing the 'const' modifier.",
+ 'examples': [
+ """
+void main() {
+const c; // This constant variable must be initialized.
+}"""
+ ],
+ },
+
+ 'FINAL_WITHOUT_INITIALIZER': {
+ 'id': 'YMESFI',
+ 'template': "A final variable must be initialized.",
+ 'howToFix': "Try adding an initializer or "
+ "removing the 'final' modifier.",
+ 'examples': ["class C { static final field; } main() => C.field;"],
+ },
+
+ 'CONST_LOOP_VARIABLE': {
+ 'id': 'WUSKMG',
+ 'template': "A loop variable cannot be constant.",
+ 'howToFix': "Try remove the 'const' modifier or "
+ "replacing it with a 'final' modifier.",
+ 'examples': [
+ """
+void main() {
+ for (const c in []) {}
+}"""
+ ],
+ },
+
+ 'MEMBER_USES_CLASS_NAME': {
+ 'id': 'TVFYRK',
+ 'template': "Member variable can't have the same name as the class it is "
+ "declared in.",
+ 'howToFix': "Try renaming the variable.",
+ 'examples': [
+ """
+class A { var A; }
+main() {
+var a = new A();
+a.A = 1;
+}
+""",
+ """
+class A { static var A; }
+main() => A.A = 1;
+"""
+ ],
+ },
+
+ 'WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT': {
+ 'id': 'IXYNUF',
+ 'template': "Wrong number of arguments to assert. Should be 1, but given "
+ "#{argumentCount}.",
+ },
+
+ 'ASSERT_IS_GIVEN_NAMED_ARGUMENTS': {
+ 'id': 'EJFDTO',
+ 'template':
+ "'assert' takes no named arguments, but given #{argumentCount}.",
+ },
+
+ 'FACTORY_REDIRECTION_IN_NON_FACTORY': {
+ 'id': 'DTBWEX',
+ 'template': "Factory redirection only allowed in factories.",
+ },
+
+ 'MISSING_FACTORY_KEYWORD': {
+ 'id': 'HOQYYA',
+ 'template': "Did you forget a factory keyword here?",
+ },
+
+ 'NO_SUCH_METHOD_IN_NATIVE': {
+ 'id': 'MSDDBX',
+ 'template':
+ "'NoSuchMethod' is not supported for classes that extend native "
+ "classes.",
+ },
+
+ 'DEFERRED_LIBRARY_DART_2_DART': {
+ 'id': 'RIRQAH',
+ 'template': "Deferred loading is not supported by the dart backend yet. "
+ "The output will not be split.",
+ },
+
+ 'DEFERRED_LIBRARY_WITHOUT_PREFIX': {
+ 'id': 'CARRII',
+ 'template': "This import is deferred but there is no prefix keyword.",
+ 'howToFix': "Try adding a prefix to the import."
+ },
+
+ 'DEFERRED_OLD_SYNTAX': {
+ 'id': 'QCBRAE',
+ 'template': "The DeferredLibrary annotation is obsolete.",
+ 'howToFix':
+ "Use the \"import 'lib.dart' deferred as prefix\" syntax instead.",
+ },
+
+ 'DEFERRED_LIBRARY_DUPLICATE_PREFIX': {
+ 'id': 'BBMJTD',
+ 'template': "The prefix of this deferred import is not unique.",
+ 'howToFix': "Try changing the import prefix."
+ },
+
+ 'DEFERRED_TYPE_ANNOTATION': {
+ 'id': 'JOUEFD',
+ 'template': "The type #{node} is deferred. "
+ "Deferred types are not valid as type annotations.",
+ 'howToFix': "Try using a non-deferred abstract class as an interface.",
+ },
+
+ 'ILLEGAL_STATIC': {
+ 'id': 'HFBHVE',
+ 'template': "Modifier static is only allowed on functions declared in "
+ "a class.",
+ },
+
+ 'STATIC_FUNCTION_BLOAT': {
+ 'id': 'SJHTKF',
+ 'template': "Using '#{class}.#{name}' may lead to unnecessarily large "
+ "generated code.",
+ 'howToFix': "Try adding '@MirrorsUsed(...)' as described at "
+ "https://goo.gl/Akrrog.",
+ },
+
+ 'NON_CONST_BLOAT': {
+ 'id': 'RDRSHO',
+ 'template': "Using 'new #{name}' may lead to unnecessarily large generated "
+ "code.",
+ 'howToFix': "Try using 'const #{name}' or adding '@MirrorsUsed(...)' as "
+ "described at https://goo.gl/Akrrog.",
+ },
+
+ 'STRING_EXPECTED': {
+ 'id': 'OEJOOI',
+ 'template': "Expected a 'String', but got an instance of '#{type}'.",
+ },
+
+ 'PRIVATE_IDENTIFIER': {
+ 'id': 'XAHVWI',
+ 'template': "'#{value}' is not a valid Symbol name because it starts with "
+ "'_'.",
+ },
+
+ 'PRIVATE_NAMED_PARAMETER': {
+ 'id': 'VFGCLK',
+ 'template': "Named optional parameter can't have a library private name.",
+ 'howToFix': "Try removing the '_' or making the parameter positional or "
+ "required.",
+ 'examples': ["""foo({int _p}) {} main() => foo();"""],
+ },
+
+ 'UNSUPPORTED_LITERAL_SYMBOL': {
+ 'id': 'OYCDII',
+ 'template':
+ "Symbol literal '##{value}' is currently unsupported by dart2js.",
+ },
+
+ 'INVALID_SYMBOL': {
+ 'id': 'RUXMBL',
+ 'template': '''
+'#{value}' is not a valid Symbol name because is not:
+* an empty String,
+* a user defined operator,
+* a qualified non-private identifier optionally followed by '=', or
+* a qualified non-private identifier followed by '.' and a user-defined '''
+ "operator.",
+ },
+
+ 'AMBIGUOUS_REEXPORT': {
+ 'id': 'YNTOND',
+ 'template': "'#{name}' is (re)exported by multiple libraries.",
+ },
+
+ 'AMBIGUOUS_LOCATION': {
+ 'id': 'SKLTYA',
+ 'template': "'#{name}' is defined here.",
+ },
+
+ 'IMPORTED_HERE': {'id': 'IMUXAE', 'template': "'#{name}' is imported here.",},
+
+ 'OVERRIDE_EQUALS_NOT_HASH_CODE': {
+ 'id': 'MUHYXI',
+ 'template': "The class '#{class}' overrides 'operator==', "
+ "but not 'get hashCode'.",
+ },
+
+ 'INTERNAL_LIBRARY_FROM': {
+ 'id': 'RXOCLX',
+ 'template': "Internal library '#{resolvedUri}' is not accessible from "
+ "'#{importingUri}'.",
+ },
+
+ 'INTERNAL_LIBRARY': {
+ 'id': 'SYLJAV',
+ 'template': "Internal library '#{resolvedUri}' is not accessible.",
+ },
+
+ 'JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS': {
+ 'id': 'LSHKJK',
+ 'template':
+ "Js-interop class '#{cls}' cannot extend from the non js-interop "
+ "class '#{superclass}'.",
+ 'howToFix': "Annotate the superclass with @JS.",
+ 'examples': [
+ """
+ import 'package:js/js.dart';
+
+ class Foo { }
+
+ @JS()
+ class Bar extends Foo { }
+
+ main() {
+ new Bar();
+ }
+ """
+ ],
+ },
+
+ 'JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER': {
+ 'id': 'QLLLEE',
+ 'template':
+ "Member '#{member}' in js-interop class '#{cls}' is not external.",
+ 'howToFix': "Mark all interop methods external",
+ 'examples': [
+ """
+ import 'package:js/js.dart';
+
+ @JS()
+ class Foo {
+ bar() {}
+ }
+
+ main() {
+ new Foo().bar();
+ }
+ """
+ ],
+ },
+
+ 'JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS': {
+ 'id': 'TDQHRY',
+ 'template': "Js-interop method '#{method}' has named arguments but is not "
+ "a factory constructor of an @anonymous @JS class.",
+ 'howToFix': "Remove all named arguments from js-interop method or "
+ "in the case of a factory constructor annotate the class "
+ "as @anonymous.",
+ 'examples': [
+ """
+ import 'package:js/js.dart';
+
+ @JS()
+ class Foo {
+ external bar(foo, {baz});
+ }
+
+ main() {
+ new Foo().bar(4, baz: 5);
+ }
+ """
+ ],
+ },
+
+ 'JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS': {
+ 'id': 'EHEKUY',
+ 'template':
+ "Parameter '#{parameter}' in anonymous js-interop class '#{cls}' "
+ "object literal constructor is positional instead of named."
+ ".",
+ 'howToFix': "Make all arguments in external factory object literal "
+ "constructors named.",
+ 'examples': [
+ """
+ import 'package:js/js.dart';
+
+ @anonymous
+ @JS()
+ class Foo {
+ external factory Foo(foo, {baz});
+ }
+
+ main() {
+ new Foo(5, baz: 5);
+ }
+ """
+ ],
+ },
+
+ 'LIBRARY_NOT_FOUND': {
+ 'id': 'BARPSL',
+ 'template': "Library not found '#{resolvedUri}'.",
+ },
+
+ 'LIBRARY_NOT_SUPPORTED': {
+ 'id': 'GDXUNS',
+ 'template': "Library not supported '#{resolvedUri}'.",
+ 'howToFix': "Try removing the dependency or enabling support using "
+ "the '--categories' option.",
+ 'examples': [
+// """
+// import 'dart:io';
+// main() {}
+// """
+ ],
+ // TODO(johnniwinther): Enable example when message_kind_test.dart
+ // supports library loader callbacks.
+ },
+
+ 'UNSUPPORTED_EQ_EQ_EQ': {
+ 'id': 'GPOVNO',
+ 'template': "'===' is not an operator. "
+ "Did you mean '#{lhs} == #{rhs}' or 'identical(#{lhs}, #{rhs})'?",
+ },
+
+ 'UNSUPPORTED_BANG_EQ_EQ': {
+ 'id': 'HDYKMV',
+ 'template': "'!==' is not an operator. "
+ "Did you mean '#{lhs} != #{rhs}' or '!identical(#{lhs}, #{rhs})'?",
+ },
+
+ 'UNSUPPORTED_PREFIX_PLUS': {
+ 'id': 'LSQTHP',
+ 'template': "'+' is not a prefix operator. ",
+ 'howToFix': "Try removing '+'.",
+ 'examples': ["main() => +2; // No longer a valid way to write '2'"],
+ },
+
+ 'UNSUPPORTED_THROW_WITHOUT_EXP': {
+ 'id': 'QOAKGE',
+ 'template': "No expression after 'throw'. "
+ "Did you mean 'rethrow'?",
+ },
+
+ 'DEPRECATED_TYPEDEF_MIXIN_SYNTAX': {
+ 'id': 'BBGGFE',
+ 'template': "'typedef' not allowed here. ",
+ 'howToFix': "Try replacing 'typedef' with 'class'.",
+ 'examples': [
+ """
+class B { }
+class M1 { }
+typedef C = B with M1; // Need to replace 'typedef' with 'class'.
+main() { new C(); }
+"""
+ ],
+ },
+
+ 'MIRRORS_EXPECTED_STRING': {
+ 'id': 'XSKTIB',
+ 'template':
+ "Can't use '#{name}' here because it's an instance of '#{type}' "
+ "and a 'String' value is expected.",
+ 'howToFix': "Did you forget to add quotes?",
+ 'examples': [
+ """
+// 'Foo' is a type literal, not a string.
+@MirrorsUsed(symbols: const [Foo])
+import 'dart:mirrors';
+
+class Foo {}
+
+main() {}
+"""
+ ],
+ },
+
+ 'MIRRORS_EXPECTED_STRING_OR_TYPE': {
+ 'id': 'JQDJPL',
+ 'template':
+ "Can't use '#{name}' here because it's an instance of '#{type}' "
+ "and a 'String' or 'Type' value is expected.",
+ 'howToFix': "Did you forget to add quotes?",
+ 'examples': [
+ """
+// 'main' is a method, not a class.
+@MirrorsUsed(targets: const [main])
+import 'dart:mirrors';
+
+main() {}
+"""
+ ],
+ },
+
+ 'MIRRORS_EXPECTED_STRING_OR_LIST': {
+ 'id': 'UVYCOE',
+ 'template':
+ "Can't use '#{name}' here because it's an instance of '#{type}' "
+ "and a 'String' or 'List' value is expected.",
+ 'howToFix': "Did you forget to add quotes?",
+ 'examples': [
+ """
+// 'Foo' is not a string.
+@MirrorsUsed(symbols: Foo)
+import 'dart:mirrors';
+
+class Foo {}
+
+main() {}
+"""
+ ],
+ },
+
+ 'MIRRORS_EXPECTED_STRING_TYPE_OR_LIST': {
+ 'id': 'WSYDFL',
+ 'template':
+ "Can't use '#{name}' here because it's an instance of '#{type}' "
+ "but a 'String', 'Type', or 'List' value is expected.",
+ 'howToFix': "Did you forget to add quotes?",
+ 'examples': [
+ """
+// '1' is not a string.
+@MirrorsUsed(targets: 1)
+import 'dart:mirrors';
+
+main() {}
+"""
+ ],
+ },
+
+ 'MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY': {
+ 'id': 'VDBBNE',
+ 'template': "Can't find '#{name}' in the current library.",
+ // TODO(ahe): The closest identifiers in edit distance would be nice.
+ 'howToFix': "Did you forget to add an import?",
+ 'examples': [
+ """
+// 'window' is not in scope because dart:html isn't imported.
+@MirrorsUsed(targets: 'window')
+import 'dart:mirrors';
+
+main() {}
+"""
+ ],
+ },
+
+ 'MIRRORS_CANNOT_RESOLVE_IN_LIBRARY': {
+ 'id': 'RUEKXE',
+ 'template': "Can't find '#{name}' in the library '#{library}'.",
+ // TODO(ahe): The closest identifiers in edit distance would be nice.
+ 'howToFix': "Is '#{name}' spelled right?",
+ 'examples': [
+ """
+// 'List' is misspelled.
+@MirrorsUsed(targets: 'dart.core.Lsit')
+import 'dart:mirrors';
+
+main() {}
+"""
+ ],
+ },
+
+ 'MIRRORS_CANNOT_FIND_IN_ELEMENT': {
+ 'id': 'ACPDCS',
+ 'template': "Can't find '#{name}' in '#{element}'.",
+ // TODO(ahe): The closest identifiers in edit distance would be nice.
+ 'howToFix': "Is '#{name}' spelled right?",
+ 'examples': [
+ """
+// 'addAll' is misspelled.
+@MirrorsUsed(targets: 'dart.core.List.addAl')
+import 'dart:mirrors';
+
+main() {}
+"""
+ ],
+ },
+
+ 'INVALID_URI': {
+ 'id': 'QQEQMK',
+ 'template': "'#{uri}' is not a valid URI.",
+ 'howToFix': DONT_KNOW_HOW_TO_FIX,
+ 'examples': [
+ """
+// can't have a '[' in a URI
+import '../../Udyn[mic ils/expect.dart';
+
+main() {}
+"""
+ ],
+ },
+
+ 'INVALID_PACKAGE_CONFIG': {
+ 'id': 'XKFAJO',
+ 'template': """Package config file '#{uri}' is invalid.
+#{exception}""",
+ 'howToFix': DONT_KNOW_HOW_TO_FIX
+ },
+
+ 'INVALID_PACKAGE_URI': {
+ 'id': 'MFVNNJ',
+ 'template': "'#{uri}' is not a valid package URI (#{exception}).",
+ 'howToFix': DONT_KNOW_HOW_TO_FIX,
+ 'examples': [
+ """
+// can't have a 'top level' package URI
+import 'package:foo.dart';
+
+main() {}
+""",
+ """
+// can't have 2 slashes
+import 'package://foo/foo.dart';
+
+main() {}
+""",
+ """
+// package name must be valid
+import 'package:not\valid/foo.dart';
+
+main() {}
+"""
+ ],
+ },
+
+ 'READ_SCRIPT_ERROR': {
+ 'id': 'JDDYLH',
+ 'template': "Can't read '#{uri}' (#{exception}).",
+ // Don't know how to fix since the underlying error is unknown.
+ 'howToFix': DONT_KNOW_HOW_TO_FIX,
+ 'examples': [
+ """
+// 'foo.dart' does not exist.
+import 'foo.dart';
+
+main() {}
+"""
+ ],
+ },
+
+ 'READ_SELF_ERROR': {
+ 'id': 'CRJUAV',
+ 'template': "#{exception}",
+ // Don't know how to fix since the underlying error is unknown.
+ 'howToFix': DONT_KNOW_HOW_TO_FIX
+ },
+
+ 'EXTRANEOUS_MODIFIER': {
+ 'id': 'DPLVJG',
+ 'template': "Can't have modifier '#{modifier}' here.",
+ 'howToFix': "Try removing '#{modifier}'.",
+ 'examples': [
+ "var String foo; main(){}",
+ // "var get foo; main(){}",
+ "var set foo; main(){}",
+ "var final foo; main(){}",
+ "var var foo; main(){}",
+ "var const foo; main(){}",
+ "var abstract foo; main(){}",
+ "var static foo; main(){}",
+ "var external foo; main(){}",
+ "get var foo; main(){}",
+ "set var foo; main(){}",
+ "final var foo; main(){}",
+ "var var foo; main(){}",
+ "const var foo; main(){}",
+ "abstract var foo; main(){}",
+ "static var foo; main(){}",
+ "external var foo; main(){}"
+ ],
+ },
+
+ 'EXTRANEOUS_MODIFIER_REPLACE': {
+ 'id': 'SSXDLN',
+ 'template': "Can't have modifier '#{modifier}' here.",
+ 'howToFix': "Try replacing modifier '#{modifier}' with 'var', 'final', "
+ "or a type.",
+ 'examples': [
+ // "get foo; main(){}",
+ "set foo; main(){}",
+ "abstract foo; main(){}",
+ "static foo; main(){}",
+ "external foo; main(){}"
+ ],
+ },
+
+ 'ABSTRACT_CLASS_INSTANTIATION': {
+ 'id': 'KOBCRO',
+ 'template': "Can't instantiate abstract class.",
+ 'howToFix': DONT_KNOW_HOW_TO_FIX,
+ 'examples': ["abstract class A {} main() { new A(); }"],
+ },
+
+ 'BODY_EXPECTED': {
+ 'id': 'YXCAHO',
+ 'template': "Expected a function body or '=>'.",
+ // TODO(ahe): In some scenarios, we can suggest removing the 'static'
+ // keyword.
+ 'howToFix': "Try adding {}.",
+ 'examples': ["main();"],
+ },
+
+ 'MIRROR_BLOAT': {
+ 'id': 'BSEAIT',
+ 'template':
+ "#{count} methods retained for use by dart:mirrors out of #{total}"
+ " total methods (#{percentage}%).",
+ },
+
+ 'MIRROR_IMPORT': {'id': 'BDAETE', 'template': "Import of 'dart:mirrors'.",},
+
+ 'MIRROR_IMPORT_NO_USAGE': {
+ 'id': 'OJOHTR',
+ 'template':
+ "This import is not annotated with @MirrorsUsed, which may lead to "
+ "unnecessarily large generated code.",
+ 'howToFix': "Try adding '@MirrorsUsed(...)' as described at "
+ "https://goo.gl/Akrrog.",
+ },
+
+ 'JS_PLACEHOLDER_CAPTURE': {
+ 'id': 'EJXEGQ',
+ 'template': "JS code must not use '#' placeholders inside functions.",
+ 'howToFix': "Use an immediately called JavaScript function to capture the"
+ " the placeholder values as JavaScript function parameters.",
+ },
+
+ 'WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT': {
+ 'id': 'JHRISO',
+ 'template':
+ "Argument for 'JS_INTERCEPTOR_CONSTANT' must be a type constant.",
+ },
+
+ 'EXPECTED_IDENTIFIER_NOT_RESERVED_WORD': {
+ 'id': 'FEJXJF',
+ 'template': "'#{keyword}' is a reserved word and can't be used here.",
+ 'howToFix': "Try using a different name.",
+ 'examples': ["do() {} main() {}"],
+ },
+
+ 'NAMED_FUNCTION_EXPRESSION': {
+ 'id': 'CTHFPI',
+ 'template': "Function expression '#{name}' cannot be named.",
+ 'howToFix': "Try removing the name.",
+ 'examples': ["main() { var f = func() {}; }"],
+ },
+
+ 'UNUSED_METHOD': {
+ 'id': 'PKLRQL',
+ 'template': "The method '#{name}' is never called.",
+ 'howToFix': "Consider deleting it.",
+ 'examples': ["deadCode() {} main() {}"],
+ },
+
+ 'UNUSED_CLASS': {
+ 'id': 'TBIECC',
+ 'template': "The class '#{name}' is never used.",
+ 'howToFix': "Consider deleting it.",
+ 'examples': ["class DeadCode {} main() {}"],
+ },
+
+ 'UNUSED_TYPEDEF': {
+ 'id': 'JBIPCN',
+ 'template': "The typedef '#{name}' is never used.",
+ 'howToFix': "Consider deleting it.",
+ 'examples': ["typedef DeadCode(); main() {}"],
+ },
+
+ 'ABSTRACT_METHOD': {
+ 'id': 'HOKOBG',
+ 'template': "The method '#{name}' has no implementation in "
+ "class '#{class}'.",
+ 'howToFix': "Try adding a body to '#{name}' or declaring "
+ "'#{class}' to be 'abstract'.",
+ 'examples': [
+ """
+class Class {
+method();
+}
+main() => new Class().method();
+"""
+ ],
+ },
+
+ 'ABSTRACT_GETTER': {
+ 'id': 'VKTRNK',
+ 'template': "The getter '#{name}' has no implementation in "
+ "class '#{class}'.",
+ 'howToFix': "Try adding a body to '#{name}' or declaring "
+ "'#{class}' to be 'abstract'.",
+ 'examples': [
+ """
+class Class {
+get getter;
+}
+main() => new Class();
+"""
+ ],
+ },
+
+ 'ABSTRACT_SETTER': {
+ 'id': 'XGDGKK',
+ 'template': "The setter '#{name}' has no implementation in "
+ "class '#{class}'.",
+ 'howToFix': "Try adding a body to '#{name}' or declaring "
+ "'#{class}' to be 'abstract'.",
+ 'examples': [
+ """
+class Class {
+set setter(_);
+}
+main() => new Class();
+"""
+ ],
+ },
+
+ 'INHERIT_GETTER_AND_METHOD': {
+ 'id': 'UMEUEG',
+ 'template': "The class '#{class}' can't inherit both getters and methods "
+ "by the named '#{name}'.",
+ 'howToFix': DONT_KNOW_HOW_TO_FIX,
+ 'examples': [
+ """
+class A {
+get member => null;
+}
+class B {
+member() {}
+}
+class Class implements A, B {
+}
+main() => new Class();
+"""
+ ],
+ },
+
+ 'INHERITED_METHOD': {
+ 'id': 'GMSVBM',
+ 'template': "The inherited method '#{name}' is declared here in class "
+ "'#{class}'.",
+ },
+
+ 'INHERITED_EXPLICIT_GETTER': {
+ 'id': 'KKAVRS',
+ 'template': "The inherited getter '#{name}' is declared here in class "
+ "'#{class}'.",
+ },
+
+ 'INHERITED_IMPLICIT_GETTER': {
+ 'id': 'JBAMEJ',
+ 'template': "The inherited getter '#{name}' is implicitly declared by this "
+ "field in class '#{class}'.",
+ },
+
+ 'UNIMPLEMENTED_METHOD_ONE': {
+ 'id': 'CMCLWO',
+ 'template': "'#{class}' doesn't implement '#{method}' "
+ "declared in '#{declarer}'.",
+ 'howToFix': "Try adding an implementation of '#{name}' or declaring "
+ "'#{class}' to be 'abstract'.",
+ 'examples': [
+ """
+abstract class I {
+m();
+}
+class C implements I {}
+main() => new C();
+""",
+ """
+abstract class I {
+m();
+}
+class C extends I {}
+main() => new C();
+"""
+ ],
+ },
+
+ 'UNIMPLEMENTED_METHOD': {
+ 'id': 'IJSNQB',
+ 'template': "'#{class}' doesn't implement '#{method}'.",
+ 'howToFix': "Try adding an implementation of '#{name}' or declaring "
+ "'#{class}' to be 'abstract'.",
+ 'examples': [
+ """
+abstract class I {
+m();
+}
+
+abstract class J {
+m();
+}
+
+class C implements I, J {}
+
+main() {
+new C();
+}
+""",
+ """
+abstract class I {
+m();
+}
+
+abstract class J {
+m();
+}
+
+class C extends I implements J {}
+
+main() {
+new C();
+}
+"""
+ ],
+ },
+
+ 'UNIMPLEMENTED_METHOD_CONT': {
+ 'id': 'KFBKPO',
+ 'template': "The method '#{name}' is declared here in class '#{class}'.",
+ },
+
+ 'UNIMPLEMENTED_SETTER_ONE': {
+ 'id': 'QGKTEA',
+ 'template': "'#{class}' doesn't implement the setter '#{name}' "
+ "declared in '#{declarer}'.",
+ 'howToFix': "Try adding an implementation of '#{name}' or declaring "
+ "'#{class}' to be 'abstract'.",
+ 'examples': [
+ """
+abstract class I {
+set m(_);
+}
+class C implements I {}
+class D implements I {
+set m(_) {}
+}
+main() {
+new D().m = 0;
+new C();
+}
+"""
+ ],
+ },
+
+ 'UNIMPLEMENTED_SETTER': {
+ 'id': 'VEEGJQ',
+ 'template': "'#{class}' doesn't implement the setter '#{name}'.",
+ 'howToFix': "Try adding an implementation of '#{name}' or declaring "
+ "'#{class}' to be 'abstract'.",
+ 'examples': [
+ """
+abstract class I {
+set m(_);
+}
+abstract class J {
+set m(_);
+}
+class C implements I, J {}
+main() => new C();
+""",
+ """
+abstract class I {
+set m(_);
+}
+abstract class J {
+set m(_);
+}
+class C extends I implements J {}
+main() => new C();
+"""
+ ],
+ },
+
+ 'UNIMPLEMENTED_EXPLICIT_SETTER': {
+ 'id': 'SABABA',
+ 'template': "The setter '#{name}' is declared here in class '#{class}'.",
+ },
+
+ 'UNIMPLEMENTED_IMPLICIT_SETTER': {
+ 'id': 'SWESAQ',
+ 'template': "The setter '#{name}' is implicitly declared by this field "
+ "in class '#{class}'.",
+ },
+
+ 'UNIMPLEMENTED_GETTER_ONE': {
+ 'id': 'ODEPFW',
+ 'template': "'#{class}' doesn't implement the getter '#{name}' "
+ "declared in '#{declarer}'.",
+ 'howToFix': "Try adding an implementation of '#{name}' or declaring "
+ "'#{class}' to be 'abstract'.",
+ 'examples': [
+ """
+abstract class I {
+get m;
+}
+class C implements I {}
+main() => new C();
+""",
+ """
+abstract class I {
+get m;
+}
+class C extends I {}
+main() => new C();
+"""
+ ],
+ },
+
+ 'UNIMPLEMENTED_GETTER': {
+ 'id': 'VHSECG',
+ 'template': "'#{class}' doesn't implement the getter '#{name}'.",
+ 'howToFix': "Try adding an implementation of '#{name}' or declaring "
+ "'#{class}' to be 'abstract'.",
+ 'examples': [
+ """
+abstract class I {
+get m;
+}
+abstract class J {
+get m;
+}
+class C implements I, J {}
+main() => new C();
+""",
+ """
+abstract class I {
+get m;
+}
+abstract class J {
+get m;
+}
+class C extends I implements J {}
+main() => new C();
+"""
+ ],
+ },
+
+ 'UNIMPLEMENTED_EXPLICIT_GETTER': {
+ 'id': 'HFDJPP',
+ 'template': "The getter '#{name}' is declared here in class '#{class}'.",
+ },
+
+ 'UNIMPLEMENTED_IMPLICIT_GETTER': {
+ 'id': 'BSCQNO',
+ 'template': "The getter '#{name}' is implicitly declared by this field "
+ "in class '#{class}'.",
+ },
+
+ 'INVALID_METADATA': {
+ 'id': 'RKJGDE',
+ 'template':
+ "A metadata annotation must be either a reference to a compile-time "
+ "constant variable or a call to a constant constructor.",
+ 'howToFix':
+ "Try using a different constant value or referencing it through a "
+ "constant variable.",
+ 'examples': [
+'@Object main() {}',
+'@print main() {}']
+ },
+
+ 'INVALID_METADATA_GENERIC': {
+ 'id': 'WEEDQD',
+ 'template':
+ "A metadata annotation using a constant constructor cannot use type "
+ "arguments.",
+ 'howToFix':
+ "Try removing the type arguments or referencing the constant "
+ "through a constant variable.",
+ 'examples': [
+ '''
+class C<T> {
+ const C();
+}
+@C<int>() main() {}
+'''],
+ },
+
+ 'EQUAL_MAP_ENTRY_KEY': {
+ 'id': 'KIDLPM',
+ 'template': "An entry with the same key already exists in the map.",
+ 'howToFix': "Try removing the previous entry or changing the key in one "
+ "of the entries.",
+ 'examples': [
+ """
+main() {
+var m = const {'foo': 1, 'foo': 2};
+}"""
+ ],
+ },
+
+ 'BAD_INPUT_CHARACTER': {
+ 'id': 'SHQWJY',
+ 'template': "Character U+#{characterHex} isn't allowed here.",
+ 'howToFix': DONT_KNOW_HOW_TO_FIX,
+ 'examples': [
+ """
+main() {
+String x = ç;
+}
+"""
+ ],
+ },
+
+ 'UNTERMINATED_STRING': {
+ 'id': 'TRLTHK',
+ 'template': "String must end with #{quote}.",
+ 'howToFix': DONT_KNOW_HOW_TO_FIX,
+ 'examples': [
+ """
+main() {
+return '
+;
+}
+""",
+ """
+main() {
+return \"
+;
+}
+""",
+ """
+main() {
+return r'
+;
+}
+""",
+ """
+main() {
+return r\"
+;
+}
+""",
+ """
+main() => '''
+""",
+ """
+main() => \"\"\"
+""",
+ """
+main() => r'''
+""",
+ """
+main() => r\"\"\"
+"""
+ ],
+ },
+
+ 'UNMATCHED_TOKEN': {
+ 'id': 'AGJKMQ',
+ 'template': "Can't find '#{end}' to match '#{begin}'.",
+ 'howToFix': DONT_KNOW_HOW_TO_FIX,
+ 'examples': ["main(", "main(){", "main(){]}",],
+ },
+
+ 'UNTERMINATED_TOKEN': {
+ 'id': 'VIIXHQ',
+ 'template':
+ // This is a fall-back message that shouldn't happen.
+ "Incomplete token.",
+ },
+
+ 'EXPONENT_MISSING': {
+ 'id': 'CXPLCR',
+ 'template':
+ "Numbers in exponential notation should always contain an exponent"
+ " (an integer number with an optional sign).",
+ 'howToFix': "Make sure there is an exponent, and remove any whitespace "
+ "before it.",
+ 'examples': [
+ """
+main() {
+var i = 1e;
+}
+"""
+ ],
+ },
+
+ 'HEX_DIGIT_EXPECTED': {
+ 'id': 'GKCAGV',
+ 'template': "A hex digit (0-9 or A-F) must follow '0x'.",
+ 'howToFix': DONT_KNOW_HOW_TO_FIX, // Seems obvious from the error message.
+ 'examples': [
+ """
+main() {
+var i = 0x;
+}
+"""
+ ],
+ },
+
+ 'MALFORMED_STRING_LITERAL': {
+ 'id': 'DULNSD',
+ 'template':
+ r"A '$' has special meaning inside a string, and must be followed by "
+ "an identifier or an expression in curly braces ({}).",
+ 'howToFix': r"Try adding a backslash (\) to escape the '$'.",
+ 'examples': [
+ r"""
+main() {
+return '$';
+}
+""",
+ r'''
+main() {
+return "$";
+}
+''',
+ r"""
+main() {
+return '''$''';
+}
+""",
+ r'''
+main() {
+return """$""";
+}
+'''
+ ],
+ },
+
+ 'UNTERMINATED_COMMENT': {
+ 'id': 'NECJNM',
+ 'template': "Comment starting with '/*' must end with '*/'.",
+ 'howToFix': DONT_KNOW_HOW_TO_FIX,
+ 'examples': [
+ r"""
+main() {
+}
+/*"""
+ ],
+ },
+
+ 'MISSING_TOKEN_BEFORE_THIS': {
+ 'id': 'AFKXGU',
+ 'template': "Expected '#{token}' before this.",
+ // Consider the second example below: the parser expects a ')' before
+ // 'y', but a ',' would also have worked. We don't have enough
+ // information to give a good suggestion.
+ 'howToFix': DONT_KNOW_HOW_TO_FIX,
+ 'examples': ["main() => true ? 1;", "main() => foo(x: 1 y: 2);",],
+ },
+
+ 'MISSING_TOKEN_AFTER_THIS': {
+ 'id': 'FMUFJL',
+ 'template': "Expected '#{token}' after this.",
+ // See [MISSING_TOKEN_BEFORE_THIS], we don't have enough information
+ // to give a good suggestion.
+ 'howToFix': DONT_KNOW_HOW_TO_FIX,
+ 'examples': [
+ "main(x) {x}",
+ """
+class S1 {}
+class S2 {}
+class S3 {}
+class A = S1 with S2, S3
+main() => new A();
+"""
+ ],
+ },
+
+ 'CONSIDER_ANALYZE_ALL': {
+ 'id': 'HHILSH',
+ 'template': "Could not find '#{main}'. Nothing will be analyzed.",
+ 'howToFix': "Try using '--analyze-all' to analyze everything.",
+ 'examples': [''],
+ },
+
+ 'MISSING_MAIN': {
+ 'id': 'HNAOPV',
+ 'template': "Could not find '#{main}'.",
+ // No example, test uses '--analyze-only' which will produce the above
+ // message [CONSIDER_ANALYZE_ALL]. An example for a human operator
+ // would be an empty file.
+ 'howToFix': "Try adding a method named '#{main}' to your program."
+ },
+
+ 'MAIN_NOT_A_FUNCTION': {
+ 'id': 'PIURPA',
+ 'template': "'#{main}' is not a function.",
+ 'howToFix': DONT_KNOW_HOW_TO_FIX, // Don't state the obvious.
+ 'examples': ['var main;'],
+ },
+
+ 'MAIN_WITH_EXTRA_PARAMETER': {
+ 'id': 'ONOGQB',
+ 'template': "'#{main}' cannot have more than two parameters.",
+ 'howToFix': DONT_KNOW_HOW_TO_FIX, // Don't state the obvious.
+ 'examples': ['main(a, b, c) {}'],
+ },
+
+ 'COMPILER_CRASHED': {
+ 'id': 'MHDWAV',
+ 'template': "The compiler crashed when compiling this element.",
+ },
+
+ 'PLEASE_REPORT_THE_CRASH': {
+ 'id': 'UUTHXX',
+ 'template': '''
+The compiler is broken.
+
+When compiling the above element, the compiler crashed. It is not
+possible to tell if this is caused by a problem in your program or
+not. Regardless, the compiler should not crash.
+
+The Dart team would greatly appreciate if you would take a moment to
+report this problem at http://dartbug.com/new.
+
+Please include the following information:
+
+* the name and version of your operating system,
+
+* the Dart SDK build number (#{buildId}), and
+
+* the entire message you see here (including the full stack trace
+below as well as the source location above).
+''',
+ },
+
+ 'POTENTIAL_MUTATION': {
+ 'id': 'YGNLLB',
+ 'template': "Variable '#{variableName}' is not known to be of type "
+ "'#{shownType}' because it is potentially mutated in the scope for "
+ "promotion.",
+ },
+
+ 'POTENTIAL_MUTATION_HERE': {
+ 'id': 'ATMSVX',
+ 'template': "Variable '#{variableName}' is potentially mutated here.",
+ },
+
+ 'POTENTIAL_MUTATION_IN_CLOSURE': {
+ 'id': 'XUAHTW',
+ 'template': "Variable '#{variableName}' is not known to be of type "
+ "'#{shownType}' because it is potentially mutated within a closure.",
+ },
+
+ 'POTENTIAL_MUTATION_IN_CLOSURE_HERE': {
+ 'id': 'UHFXLG',
+ 'template': "Variable '#{variableName}' is potentially mutated in a "
+ "closure here.",
+ },
+
+ 'ACCESSED_IN_CLOSURE': {
+ 'id': 'JJHKSF',
+ 'template': "Variable '#{variableName}' is not known to be of type "
+ "'#{shownType}' because it is accessed by a closure in the scope for "
+ "promotion and potentially mutated in the scope of "
+ "'#{variableName}'.",
+ },
+
+ 'ACCESSED_IN_CLOSURE_HERE': {
+ 'id': 'KMJVEA',
+ 'template': "Variable '#{variableName}' is accessed in a closure here.",
+ },
+
+ 'NOT_MORE_SPECIFIC': {
+ 'id': 'EJHQAG',
+ 'template': "Variable '#{variableName}' is not shown to have type "
+ "'#{shownType}' because '#{shownType}' is not more specific than the "
+ "known type '#{knownType}' of '#{variableName}'.",
+ },
+
+ 'NOT_MORE_SPECIFIC_SUBTYPE': {
+ 'id': 'APICDL',
+ 'template': "Variable '#{variableName}' is not shown to have type "
+ "'#{shownType}' because '#{shownType}' is not a subtype of the "
+ "known type '#{knownType}' of '#{variableName}'.",
+ },
+
+ 'NOT_MORE_SPECIFIC_SUGGESTION': {
+ 'id': 'FFNCJX',
+ 'template': "Variable '#{variableName}' is not shown to have type "
+ "'#{shownType}' because '#{shownType}' is not more specific than the "
+ "known type '#{knownType}' of '#{variableName}'.",
+ 'howToFix': "Try replacing '#{shownType}' with '#{shownTypeSuggestion}'.",
+ },
+
+ 'NO_COMMON_SUBTYPES': {
+ 'id': 'XKJOEC',
+ 'template': "Types '#{left}' and '#{right}' have no common subtypes.",
+ },
+
+ 'HIDDEN_WARNINGS_HINTS': {
+ 'id': 'JBAWEK',
+ 'template':
+ "#{warnings} warning(s) and #{hints} hint(s) suppressed in #{uri}.",
+ },
+
+ 'HIDDEN_WARNINGS': {
+ 'id': 'JIYWDC',
+ 'template': "#{warnings} warning(s) suppressed in #{uri}.",
+ },
+
+ 'HIDDEN_HINTS': {
+ 'id': 'RHNXQT',
+ 'template': "#{hints} hint(s) suppressed in #{uri}.",
+ },
+
+ 'PREAMBLE': {
+ 'id': 'GXGWIF',
+ 'template': "When run on the command-line, the compiled output might"
+ " require a preamble file located in:\n"
+ " <sdk>/lib/_internal/js_runtime/lib/preambles.",
+ },
+
+ 'INVALID_SYNC_MODIFIER': {
+ 'id': 'FNYUYU',
+ 'template': "Invalid modifier 'sync'.",
+ 'howToFix': "Try replacing 'sync' with 'sync*'.",
+ 'examples': ["main() sync {}"],
+ },
+
+ 'INVALID_AWAIT_FOR': {
+ 'id': 'IEYGCY',
+ 'template': "'await' is only supported on for-in loops.",
+ 'howToFix': "Try rewriting the loop as a for-in loop or removing the "
+ "'await' keyword.",
+ 'examples': [
+ """
+main() async* {
+await for (int i = 0; i < 10; i++) {}
+}
+"""
+ ],
+ },
+
+ 'INVALID_AWAIT_FOR_IN': {
+ 'id': 'FIEYGC',
+ 'template': "'await' is only supported in methods with an 'async' or "
+ "'async*' body modifier.",
+ 'howToFix': "Try adding 'async' or 'async*' to the method body or "
+ "removing the 'await' keyword.",
+ 'examples': [
+ """
+main(o) sync* {
+ await for (var e in o) {}
+}
+"""
+ ],
+ },
+
+ 'INVALID_AWAIT': {
+ 'id': 'IEYHYD',
+ 'template': "'await' is only supported in methods with an 'async' or "
+ "'async*' body modifier.",
+ 'howToFix': "Try adding 'async' or 'async*' to the method body.",
+ 'examples': [
+ """
+main() sync* {
+ await null;
+}
+"""
+ ],
+ },
+
+ 'INVALID_YIELD': {
+ 'id': 'IPGGCY',
+ 'template': "'yield' is only supported in methods with a 'sync*' or "
+ "'async*' body modifier.",
+ 'howToFix': "Try adding 'sync*' or 'async*' to the method body.",
+ 'examples': [
+ """
+main() async {
+ yield 0;
+}
+"""
+ ],
+ },
+
+ 'ASYNC_MODIFIER_ON_ABSTRACT_METHOD': {
+ 'id': 'VRISLY',
+ 'template':
+ "The modifier '#{modifier}' is not allowed on an abstract method.",
+ 'options': ['--enable-async'],
+ 'howToFix': "Try removing the '#{modifier}' modifier or adding a "
+ "body to the method.",
+ 'examples': [
+ """
+abstract class A {
+method() async;
+}
+class B extends A {
+method() {}
+}
+main() {
+A a = new B();
+a.method();
+}
+"""
+ ],
+ },
+
+ 'ASYNC_MODIFIER_ON_CONSTRUCTOR': {
+ 'id': 'DHCFON',
+ 'template': "The modifier '#{modifier}' is not allowed on constructors.",
+ 'options': ['--enable-async'],
+ 'howToFix': "Try removing the '#{modifier}' modifier.",
+ 'examples': [
+ """
+class A {
+A() async;
+}
+main() => new A();""",
+ """
+class A {
+A();
+factory A.a() async* {}
+}
+main() => new A.a();"""
+ ],
+ },
+
+ 'ASYNC_MODIFIER_ON_SETTER': {
+ 'id': 'NMJLJE',
+ 'template': "The modifier '#{modifier}' is not allowed on setters.",
+ 'options': ['--enable-async'],
+ 'howToFix': "Try removing the '#{modifier}' modifier.",
+ 'examples': [
+ """
+class A {
+set foo(v) async {}
+}
+main() => new A().foo = 0;"""
+ ],
+ },
+
+ 'YIELDING_MODIFIER_ON_ARROW_BODY': {
+ 'id': 'UOGLUX',
+ 'template':
+ "The modifier '#{modifier}' is not allowed on methods implemented "
+ "using '=>'.",
+ 'options': ['--enable-async'],
+ 'howToFix': "Try removing the '#{modifier}' modifier or implementing "
+ "the method body using a block: '{ ... }'.",
+ 'examples': ["main() sync* => null;", "main() async* => null;"],
+ },
+
+ // TODO(johnniwinther): Check for 'async' as identifier.
+ 'ASYNC_KEYWORD_AS_IDENTIFIER': {
+ 'id': 'VTWSMA',
+ 'template':
+ "'#{keyword}' cannot be used as an identifier in a function body "
+ "marked with '#{modifier}'.",
+ 'options': ['--enable-async'],
+ 'howToFix': "Try removing the '#{modifier}' modifier or renaming the "
+ "identifier.",
+ 'examples': [
+ """
+main() async {
+var await;
+}""",
+ """
+main() async* {
+var yield;
+}""",
+ """
+main() sync* {
+var yield;
+}"""
+ ],
+ },
+
+ 'RETURN_IN_GENERATOR': {
+ 'id': 'AWGUVF',
+ 'template':
+ "'return' with a value is not allowed in a method body using the "
+ "'#{modifier}' modifier.",
+ 'howToFix': "Try removing the value, replacing 'return' with 'yield' "
+ "or changing the method body modifier.",
+ 'examples': [
+ """
+foo() async* { return 0; }
+main() => foo();
+""",
+ """
+foo() sync* { return 0; }
+main() => foo();
+"""
+ ],
+ },
+
+ 'NATIVE_NOT_SUPPORTED': {
+ 'id': 'QMMLUT',
+ 'template': "'native' modifier is not supported.",
+ 'howToFix': "Try removing the 'native' implementation or analyzing the "
+ "code with the --allow-native-extensions option.",
+ 'examples': [
+ """
+main() native "Main";
+"""
+ ],
+ },
+
+ 'DART_EXT_NOT_SUPPORTED': {
+ 'id': 'JLPQFJ',
+ 'template': "The 'dart-ext' scheme is not supported.",
+ 'howToFix': "Try analyzing the code with the --allow-native-extensions "
+ "option.",
+ 'examples': [
+ """
+import 'dart-ext:main';
+
+main() {}
+"""
+ ],
+ },
+
+ 'LIBRARY_TAG_MUST_BE_FIRST': {
+ 'id': 'JFUSRX',
+ 'template':
+ "The library declaration should come before other declarations.",
+ 'howToFix': "Try moving the declaration to the top of the file.",
+ 'examples': [
+ """
+import 'dart:core';
+library foo;
+main() {}
+""",
+ ],
+ },
+
+ 'ONLY_ONE_LIBRARY_TAG': {
+ 'id': 'CCXFMY',
+ 'template': "There can only be one library declaration.",
+ 'howToFix': "Try removing all other library declarations.",
+ 'examples': [
+ """
+library foo;
+library bar;
+main() {}
+""",
+ """
+library foo;
+import 'dart:core';
+library bar;
+main() {}
+""",
+ ],
+ },
+
+ 'IMPORT_BEFORE_PARTS': {
+ 'id': 'NSMOQI',
+ 'template': "Import declarations should come before parts.",
+ 'howToFix': "Try moving this import further up in the file.",
+ 'examples': [
+ {
+ 'main.dart': """
+library test.main;
+part 'part.dart';
+import 'dart:core';
+main() {}
+""",
+ 'part.dart': """
+part of test.main;
+""",
+ }
+ ],
+ },
+
+ 'EXPORT_BEFORE_PARTS': {
+ 'id': 'KYJTTC',
+ 'template': "Export declarations should come before parts.",
+ 'howToFix': "Try moving this export further up in the file.",
+ 'examples': [
+ {
+ 'main.dart': """
+library test.main;
+part 'part.dart';
+export 'dart:core';
+main() {}
+""",
+ 'part.dart': """
+part of test.main;
+""",
+ }
+ ],
+
+//////////////////////////////////////////////////////////////////////////////
+// Patch errors start.
+//////////////////////////////////////////////////////////////////////////////
+ },
+
+ 'PATCH_RETURN_TYPE_MISMATCH': {
+ 'id': 'DTOQDU',
+ 'template': "Patch return type '#{patchReturnType}' does not match "
+ "'#{originReturnType}' on origin method '#{methodName}'.",
+ },
+
+ 'PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH': {
+ 'id': 'KJUUYC',
+ 'template': "Required parameter count of patch method "
+ "(#{patchParameterCount}) does not match parameter count on origin "
+ "method '#{methodName}' (#{originParameterCount}).",
+ },
+
+ 'PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH': {
+ 'id': 'GUTGTE',
+ 'template': "Optional parameter count of patch method "
+ "(#{patchParameterCount}) does not match parameter count on origin "
+ "method '#{methodName}' (#{originParameterCount}).",
+ },
+
+ 'PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH': {
+ 'id': 'MCHEIC',
+ 'template': "Optional parameters of origin and patch method "
+ "'#{methodName}' must both be either named or positional.",
+ },
+
+ 'PATCH_PARAMETER_MISMATCH': {
+ 'id': 'XISHPB',
+ 'template': "Patch method parameter '#{patchParameter}' does not match "
+ "'#{originParameter}' on origin method '#{methodName}'.",
+ },
+
+ 'PATCH_PARAMETER_TYPE_MISMATCH': {
+ 'id': 'UGRBYD',
+ 'template': "Patch method parameter '#{parameterName}' type "
+ "'#{patchParameterType}' does not match '#{originParameterType}' on "
+ "origin method '#{methodName}'.",
+ },
+
+ 'PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION': {
+ 'id': 'WSNMKD',
+ 'template': "External method without an implementation.",
+ },
+
+ 'PATCH_POINT_TO_FUNCTION': {
+ 'id': 'CAVBPN',
+ 'template': "This is the function patch '#{functionName}'.",
+ },
+
+ 'PATCH_POINT_TO_CLASS': {
+ 'id': 'TWDLDX',
+ 'template': "This is the class patch '#{className}'.",
+ },
+
+ 'PATCH_POINT_TO_GETTER': {
+ 'id': 'TRBBNY',
+ 'template': "This is the getter patch '#{getterName}'.",
+ },
+
+ 'PATCH_POINT_TO_SETTER': {
+ 'id': 'DAXDLW',
+ 'template': "This is the setter patch '#{setterName}'.",
+ },
+
+ 'PATCH_POINT_TO_CONSTRUCTOR': {
+ 'id': 'VYQISY',
+ 'template': "This is the constructor patch '#{constructorName}'.",
+ },
+
+ 'PATCH_POINT_TO_PARAMETER': {
+ 'id': 'TFPAGO',
+ 'template': "This is the patch parameter '#{parameterName}'.",
+ },
+
+ 'PATCH_NON_EXISTING': {
+ 'id': 'AWOACF',
+ 'template': "Origin does not exist for patch '#{name}'.",
+ },
+
+ // TODO(ahe): Eventually, this error should be removed as it will be
+ // handled by the regular parser.
+ 'PATCH_NONPATCHABLE': {
+ 'id': 'WQEPJI',
+ 'template': "Only classes and functions can be patched.",
+ },
+
+ 'PATCH_NON_EXTERNAL': {
+ 'id': 'MHLXNK',
+ 'template': "Only external functions can be patched.",
+ },
+
+ 'PATCH_NON_CLASS': {
+ 'id': 'UIALAB',
+ 'template': "Patching non-class with class patch '#{className}'.",
+ },
+
+ 'PATCH_NON_GETTER': {
+ 'id': 'VTNQCJ',
+ 'template': "Cannot patch non-getter '#{name}' with getter patch.",
+ },
+
+ 'PATCH_NO_GETTER': {
+ 'id': 'XOPDHD',
+ 'template': "No getter found for getter patch '#{getterName}'.",
+ },
+
+ 'PATCH_NON_SETTER': {
+ 'id': 'XBOMMN',
+ 'template': "Cannot patch non-setter '#{name}' with setter patch.",
+ },
+
+ 'PATCH_NO_SETTER': {
+ 'id': 'YITARQ',
+ 'template': "No setter found for setter patch '#{setterName}'.",
+ },
+
+ 'PATCH_NON_CONSTRUCTOR': {
+ 'id': 'TWAEQV',
+ 'template': "Cannot patch non-constructor with constructor patch "
+ "'#{constructorName}'.",
+ },
+
+ 'PATCH_NON_FUNCTION': {
+ 'id': 'EDXBPI',
+ 'template': "Cannot patch non-function with function patch "
+ "'#{functionName}'.",
+ },
+
+ 'INJECTED_PUBLIC_MEMBER': {
+ 'id': 'JGMXMI',
+ 'template': "Non-patch members in patch libraries must be private.",
+ },
+
+ 'EXTERNAL_WITH_BODY': {
+ 'id': 'GAVMSQ',
+ 'template':
+ "External function '#{functionName}' cannot have a function body.",
+ 'options': ["--output-type=dart"],
+ 'howToFix': "Try removing the 'external' modifier or the function body.",
+ 'examples': [
+ """
+external foo() => 0;
+main() => foo();
+""",
+ """
+external foo() {}
+main() => foo();
+"""
+ ],
+
+//////////////////////////////////////////////////////////////////////////////
+// Patch errors end.
+//////////////////////////////////////////////////////////////////////////////
+ },
+
+ 'EXPERIMENTAL_ASSERT_MESSAGE': {
+ 'id': 'NENGIS',
+ 'template': "Experimental language feature 'assertion with message'"
+ " is not supported.",
+ 'howToFix':
+ "Use option '--assert-message' to use assertions with messages.",
+ 'examples': [
+ r'''
+main() {
+int n = -7;
+assert(n > 0, 'must be positive: $n');
+}
+'''
+ ],
+ },
+
+ 'IMPORT_EXPERIMENTAL_MIRRORS': {
+ 'id': 'SCJYPH',
+ 'template': '''
+
+****************************************************************
+* WARNING: dart:mirrors support in dart2js is experimental,
+* and not recommended.
+* This implementation of mirrors is incomplete,
+* and often greatly increases the size of the generated
+* JavaScript code.
+*
+* Your app imports dart:mirrors via:'''
+ '''
+$IMPORT_EXPERIMENTAL_MIRRORS_PADDING#{importChain}
+*
+* You can disable this message by using the --enable-experimental-mirrors
+* command-line flag.
+*
+* To learn what to do next, please visit:
+* http://dartlang.org/dart2js-reflection
+****************************************************************
+''',
+ },
+
+ 'DISALLOWED_LIBRARY_IMPORT': {
+ 'id': 'OCSFJU',
+ 'template': '''
+Your app imports the unsupported library '#{uri}' via:
+'''
+ '''
+$DISALLOWED_LIBRARY_IMPORT_PADDING#{importChain}
+
+Use the --categories option to support import of '#{uri}'.
+''',
+ },
+
+ 'MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND': {
+ 'id': 'JBTRRM',
+ 'template': """
+dart:mirrors library is not supported when using this backend.
+
+Your app imports dart:mirrors via:"""
+ """
+$MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING#{importChain}""",
+ },
+
+ 'CALL_NOT_SUPPORTED_ON_NATIVE_CLASS': {
+ 'id': 'HAULDW',
+ 'template': "Non-supported 'call' member on a native class, or a "
+ "subclass of a native class.",
+ },
+
+ 'DIRECTLY_THROWING_NSM': {
+ 'id': 'XLTPCS',
+ 'template': "This 'noSuchMethod' implementation is guaranteed to throw an "
+ "exception. The generated code will be smaller if it is "
+ "rewritten.",
+ 'howToFix': "Rewrite to "
+ "'noSuchMethod(Invocation i) => super.noSuchMethod(i);'.",
+ },
+
+ 'COMPLEX_THROWING_NSM': {
+ 'id': 'PLCXVX',
+ 'template': "This 'noSuchMethod' implementation is guaranteed to throw an "
+ "exception. The generated code will be smaller and the compiler "
+ "will be able to perform more optimizations if it is rewritten.",
+ 'howToFix': "Rewrite to "
+ "'noSuchMethod(Invocation i) => super.noSuchMethod(i);'.",
+ },
+
+ 'COMPLEX_RETURNING_NSM': {
+ 'id': 'HUTCTQ',
+ 'template': "Overriding 'noSuchMethod' causes the compiler to generate "
+ "more code and prevents the compiler from doing some optimizations.",
+ 'howToFix': "Consider removing this 'noSuchMethod' implementation."
+ },
+
+ 'UNRECOGNIZED_VERSION_OF_LOOKUP_MAP': {
+ 'id': 'OVAFEW',
+ 'template': "Unsupported version of package:lookup_map.",
+ 'howToFix': DONT_KNOW_HOW_TO_FIX
+ },
+};
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index 5913cb0..200b63f 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -2,77 +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.
-
-/**
- * The messages in this file should meet the following guide lines:
- *
- * 1. The message should be a complete sentence starting with an uppercase
- * letter, and ending with a period.
- *
- * 2. Reserved words and embedded identifiers should be in single quotes, so
- * prefer double quotes for the complete message. For example, "The
- * class '#{className}' can't use 'super'." Notice that the word 'class' in the
- * preceding message is not quoted as it refers to the concept 'class', not the
- * reserved word. On the other hand, 'super' refers to the reserved word. Do
- * not quote 'null' and numeric literals.
- *
- * 3. Do not try to compose messages, as it can make translating them hard.
- *
- * 4. Try to keep the error messages short, but informative.
- *
- * 5. Use simple words and terminology, assume the reader of the message
- * doesn't have an advanced degree in math, and that English is not the
- * reader's native language. Do not assume any formal computer science
- * training. For example, do not use Latin abbreviations (prefer "that is" over
- * "i.e.", and "for example" over "e.g."). Also avoid phrases such as "if and
- * only if" and "iff", that level of precision is unnecessary.
- *
- * 6. Prefer contractions when they are in common use, for example, prefer
- * "can't" over "cannot". Using "cannot", "must not", "shall not", etc. is
- * off-putting to people new to programming.
- *
- * 7. Use common terminology, preferably from the Dart Language
- * Specification. This increases the user's chance of finding a good
- * explanation on the web.
- *
- * 8. Do not try to be cute or funny. It is extremely frustrating to work on a
- * product that crashes with a "tongue-in-cheek" message, especially if you did
- * not want to use this product to begin with.
- *
- * 9. Do not lie, that is, do not write error messages containing phrases like
- * "can't happen". If the user ever saw this message, it would be a
- * lie. Prefer messages like: "Internal error: This function should not be
- * called when 'x' is null.".
- *
- * 10. Prefer to not use imperative tone. That is, the message should not sound
- * accusing or like it is ordering the user around. The computer should
- * describe the problem, not criticize for violating the specification.
- *
- * Other things to keep in mind:
- *
- * An INFO message should always be preceded by a non-INFO message, and the
- * INFO messages are additional details about the preceding non-INFO
- * message. For example, consider duplicated elements. First report a WARNING
- * or ERROR about the duplicated element, and then report an INFO about the
- * location of the existing element.
- *
- * Generally, we want to provide messages that consists of three sentences:
- * 1. what is wrong, 2. why is it wrong, 3. how do I fix it. However, we
- * combine the first two in [template] and the last in [howToFix].
- */
-
library dart2js.messages;
-import '../tokens/token.dart' show
- ErrorToken,
- Token;
+import '../tokens/token.dart' show ErrorToken, Token;
-import 'invariant.dart' show
- invariant;
-import 'spannable.dart' show
- CURRENT_ELEMENT_SPANNABLE;
+import 'invariant.dart' show invariant;
+import 'spannable.dart' show CURRENT_ELEMENT_SPANNABLE;
-const DONT_KNOW_HOW_TO_FIX = "Computer says no!";
+import 'dart2js_messages.dart' as dart2js_messages;
+import 'shared_messages.dart' as shared_messages;
/// Keys for the [MessageTemplate]s.
enum MessageKind {
@@ -146,6 +84,7 @@
CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR,
CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD,
+ CONST_LOOP_VARIABLE,
CONST_MAP_KEY_OVERRIDES_EQUALS,
CONST_WITHOUT_INITIALIZER,
CONSTRUCTOR_CALL_EXPECTED,
@@ -233,6 +172,7 @@
IMPORT_BEFORE_PARTS,
IMPORT_EXPERIMENTAL_MIRRORS,
IMPORT_PART_OF,
+ IMPORT_PART_OF_HERE,
IMPORTED_HERE,
INHERIT_GETTER_AND_METHOD,
INHERITED_EXPLICIT_GETTER,
@@ -246,7 +186,9 @@
INTERNAL_LIBRARY,
INTERNAL_LIBRARY_FROM,
INVALID_ARGUMENT_AFTER_NAMED,
+ INVALID_AWAIT,
INVALID_AWAIT_FOR,
+ INVALID_AWAIT_FOR_IN,
INVALID_BREAK,
INVALID_CASE_DEFAULT,
INVALID_CONSTRUCTOR_ARGUMENTS,
@@ -254,6 +196,8 @@
INVALID_CONTINUE,
INVALID_FOR_IN,
INVALID_INITIALIZER,
+ INVALID_METADATA,
+ INVALID_METADATA_GENERIC,
INVALID_OVERRIDDEN_FIELD,
INVALID_OVERRIDDEN_GETTER,
INVALID_OVERRIDDEN_METHOD,
@@ -277,6 +221,7 @@
INVALID_UNNAMED_CONSTRUCTOR_NAME,
INVALID_URI,
INVALID_USE_OF_SUPER,
+ INVALID_YIELD,
JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS,
JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER,
JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS,
@@ -459,6 +404,462 @@
YIELDING_MODIFIER_ON_ARROW_BODY,
}
+const _KIND_TO_STRING_MAP = const <MessageKind, String>{
+ MessageKind.ABSTRACT_CLASS_INSTANTIATION: "ABSTRACT_CLASS_INSTANTIATION",
+ MessageKind.ABSTRACT_GETTER: "ABSTRACT_GETTER",
+ MessageKind.ABSTRACT_METHOD: "ABSTRACT_METHOD",
+ MessageKind.ABSTRACT_SETTER: "ABSTRACT_SETTER",
+ MessageKind.ACCESSED_IN_CLOSURE: "ACCESSED_IN_CLOSURE",
+ MessageKind.ACCESSED_IN_CLOSURE_HERE: "ACCESSED_IN_CLOSURE_HERE",
+ MessageKind.ADDITIONAL_ARGUMENT: "ADDITIONAL_ARGUMENT",
+ MessageKind.ADDITIONAL_TYPE_ARGUMENT: "ADDITIONAL_TYPE_ARGUMENT",
+ MessageKind.ALREADY_INITIALIZED: "ALREADY_INITIALIZED",
+ MessageKind.AMBIGUOUS_LOCATION: "AMBIGUOUS_LOCATION",
+ MessageKind.AMBIGUOUS_REEXPORT: "AMBIGUOUS_REEXPORT",
+ MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS:
+ "ASSERT_IS_GIVEN_NAMED_ARGUMENTS",
+ MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER: "ASSIGNING_FINAL_FIELD_IN_SUPER",
+ MessageKind.ASSIGNING_METHOD: "ASSIGNING_METHOD",
+ MessageKind.ASSIGNING_METHOD_IN_SUPER: "ASSIGNING_METHOD_IN_SUPER",
+ MessageKind.ASSIGNING_TYPE: "ASSIGNING_TYPE",
+ MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER: "ASYNC_KEYWORD_AS_IDENTIFIER",
+ MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD:
+ "ASYNC_MODIFIER_ON_ABSTRACT_METHOD",
+ MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR: "ASYNC_MODIFIER_ON_CONSTRUCTOR",
+ MessageKind.ASYNC_MODIFIER_ON_SETTER: "ASYNC_MODIFIER_ON_SETTER",
+ MessageKind.AWAIT_MEMBER_NOT_FOUND: "AWAIT_MEMBER_NOT_FOUND",
+ MessageKind.AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE:
+ "AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE",
+ MessageKind.BAD_INPUT_CHARACTER: "BAD_INPUT_CHARACTER",
+ MessageKind.BEFORE_TOP_LEVEL: "BEFORE_TOP_LEVEL",
+ MessageKind.BINARY_OPERATOR_BAD_ARITY: "BINARY_OPERATOR_BAD_ARITY",
+ MessageKind.BODY_EXPECTED: "BODY_EXPECTED",
+ MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS:
+ "CALL_NOT_SUPPORTED_ON_NATIVE_CLASS",
+ MessageKind.CANNOT_EXTEND: "CANNOT_EXTEND",
+ MessageKind.CANNOT_EXTEND_ENUM: "CANNOT_EXTEND_ENUM",
+ MessageKind.CANNOT_EXTEND_MALFORMED: "CANNOT_EXTEND_MALFORMED",
+ MessageKind.CANNOT_FIND_CONSTRUCTOR: "CANNOT_FIND_CONSTRUCTOR",
+ MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR:
+ "CANNOT_FIND_UNNAMED_CONSTRUCTOR",
+ MessageKind.CANNOT_IMPLEMENT: "CANNOT_IMPLEMENT",
+ MessageKind.CANNOT_IMPLEMENT_ENUM: "CANNOT_IMPLEMENT_ENUM",
+ MessageKind.CANNOT_IMPLEMENT_MALFORMED: "CANNOT_IMPLEMENT_MALFORMED",
+ MessageKind.CANNOT_INSTANTIATE_ENUM: "CANNOT_INSTANTIATE_ENUM",
+ MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE:
+ "CANNOT_INSTANTIATE_TYPE_VARIABLE",
+ MessageKind.CANNOT_INSTANTIATE_TYPEDEF: "CANNOT_INSTANTIATE_TYPEDEF",
+ MessageKind.CANNOT_MIXIN: "CANNOT_MIXIN",
+ MessageKind.CANNOT_MIXIN_ENUM: "CANNOT_MIXIN_ENUM",
+ MessageKind.CANNOT_MIXIN_MALFORMED: "CANNOT_MIXIN_MALFORMED",
+ MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD:
+ "CANNOT_OVERRIDE_FIELD_WITH_METHOD",
+ MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT:
+ "CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT",
+ MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD:
+ "CANNOT_OVERRIDE_GETTER_WITH_METHOD",
+ MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT:
+ "CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT",
+ MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD:
+ "CANNOT_OVERRIDE_METHOD_WITH_FIELD",
+ MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT:
+ "CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT",
+ MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER:
+ "CANNOT_OVERRIDE_METHOD_WITH_GETTER",
+ MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT:
+ "CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT",
+ MessageKind.CANNOT_RESOLVE: "CANNOT_RESOLVE",
+ MessageKind.CANNOT_RESOLVE_AWAIT: "CANNOT_RESOLVE_AWAIT",
+ MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE:
+ "CANNOT_RESOLVE_AWAIT_IN_CLOSURE",
+ MessageKind.CANNOT_RESOLVE_CONSTRUCTOR: "CANNOT_RESOLVE_CONSTRUCTOR",
+ MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT:
+ "CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT",
+ MessageKind.CANNOT_RESOLVE_GETTER: "CANNOT_RESOLVE_GETTER",
+ MessageKind.CANNOT_RESOLVE_IN_INITIALIZER: "CANNOT_RESOLVE_IN_INITIALIZER",
+ MessageKind.CANNOT_RESOLVE_SETTER: "CANNOT_RESOLVE_SETTER",
+ MessageKind.CANNOT_RESOLVE_TYPE: "CANNOT_RESOLVE_TYPE",
+ MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR: "CANNOT_RETURN_FROM_CONSTRUCTOR",
+ MessageKind.CLASS_NAME_EXPECTED: "CLASS_NAME_EXPECTED",
+ MessageKind.COMPILER_CRASHED: "COMPILER_CRASHED",
+ MessageKind.COMPLEX_RETURNING_NSM: "COMPLEX_RETURNING_NSM",
+ MessageKind.COMPLEX_THROWING_NSM: "COMPLEX_THROWING_NSM",
+ MessageKind.CONSIDER_ANALYZE_ALL: "CONSIDER_ANALYZE_ALL",
+ MessageKind.CONST_CALLS_NON_CONST: "CONST_CALLS_NON_CONST",
+ MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT:
+ "CONST_CALLS_NON_CONST_FOR_IMPLICIT",
+ MessageKind.CONST_CONSTRUCTOR_HAS_BODY: "CONST_CONSTRUCTOR_HAS_BODY",
+ MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS:
+ "CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS",
+ MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR:
+ "CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR",
+ MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD:
+ "CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD",
+ MessageKind.CONST_LOOP_VARIABLE: "CONST_LOOP_VARIABLE",
+ MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS: "CONST_MAP_KEY_OVERRIDES_EQUALS",
+ MessageKind.CONST_WITHOUT_INITIALIZER: "CONST_WITHOUT_INITIALIZER",
+ MessageKind.CONSTRUCTOR_CALL_EXPECTED: "CONSTRUCTOR_CALL_EXPECTED",
+ MessageKind.CONSTRUCTOR_IS_NOT_CONST: "CONSTRUCTOR_IS_NOT_CONST",
+ MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE: "CONSTRUCTOR_WITH_RETURN_TYPE",
+ MessageKind.CYCLIC_CLASS_HIERARCHY: "CYCLIC_CLASS_HIERARCHY",
+ MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS: "CYCLIC_COMPILE_TIME_CONSTANTS",
+ MessageKind.CYCLIC_REDIRECTING_FACTORY: "CYCLIC_REDIRECTING_FACTORY",
+ MessageKind.CYCLIC_TYPE_VARIABLE: "CYCLIC_TYPE_VARIABLE",
+ MessageKind.CYCLIC_TYPEDEF: "CYCLIC_TYPEDEF",
+ MessageKind.CYCLIC_TYPEDEF_ONE: "CYCLIC_TYPEDEF_ONE",
+ MessageKind.DART_EXT_NOT_SUPPORTED: "DART_EXT_NOT_SUPPORTED",
+ MessageKind.DEFERRED_COMPILE_TIME_CONSTANT: "DEFERRED_COMPILE_TIME_CONSTANT",
+ MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION:
+ "DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION",
+ MessageKind.DEFERRED_LIBRARY_DART_2_DART: "DEFERRED_LIBRARY_DART_2_DART",
+ MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX:
+ "DEFERRED_LIBRARY_DUPLICATE_PREFIX",
+ MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX:
+ "DEFERRED_LIBRARY_WITHOUT_PREFIX",
+ MessageKind.DEFERRED_OLD_SYNTAX: "DEFERRED_OLD_SYNTAX",
+ MessageKind.DEFERRED_TYPE_ANNOTATION: "DEFERRED_TYPE_ANNOTATION",
+ MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX:
+ "DEPRECATED_TYPEDEF_MIXIN_SYNTAX",
+ MessageKind.DIRECTLY_THROWING_NSM: "DIRECTLY_THROWING_NSM",
+ MessageKind.DISALLOWED_LIBRARY_IMPORT: "DISALLOWED_LIBRARY_IMPORT",
+ MessageKind.DUPLICATE_DEFINITION: "DUPLICATE_DEFINITION",
+ MessageKind.DUPLICATE_EXPORT: "DUPLICATE_EXPORT",
+ MessageKind.DUPLICATE_EXPORT_CONT: "DUPLICATE_EXPORT_CONT",
+ MessageKind.DUPLICATE_EXPORT_DECL: "DUPLICATE_EXPORT_DECL",
+ MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS: "DUPLICATE_EXTENDS_IMPLEMENTS",
+ MessageKind.DUPLICATE_IMPLEMENTS: "DUPLICATE_IMPLEMENTS",
+ MessageKind.DUPLICATE_IMPORT: "DUPLICATE_IMPORT",
+ MessageKind.DUPLICATE_INITIALIZER: "DUPLICATE_INITIALIZER",
+ MessageKind.DUPLICATE_LABEL: "DUPLICATE_LABEL",
+ MessageKind.DUPLICATE_SUPER_INITIALIZER: "DUPLICATE_SUPER_INITIALIZER",
+ MessageKind.DUPLICATE_TYPE_VARIABLE_NAME: "DUPLICATE_TYPE_VARIABLE_NAME",
+ MessageKind.DUPLICATED_LIBRARY_NAME: "DUPLICATED_LIBRARY_NAME",
+ MessageKind.DUPLICATED_LIBRARY_RESOURCE: "DUPLICATED_LIBRARY_RESOURCE",
+ MessageKind.DUPLICATED_PART_OF: "DUPLICATED_PART_OF",
+ MessageKind.DUPLICATED_RESOURCE: "DUPLICATED_RESOURCE",
+ MessageKind.EMPTY_CATCH_DECLARATION: "EMPTY_CATCH_DECLARATION",
+ MessageKind.EMPTY_ENUM_DECLARATION: "EMPTY_ENUM_DECLARATION",
+ MessageKind.EMPTY_HIDE: "EMPTY_HIDE",
+ MessageKind.EQUAL_MAP_ENTRY_KEY: "EQUAL_MAP_ENTRY_KEY",
+ MessageKind.EMPTY_SHOW: "EMPTY_SHOW",
+ MessageKind.EXISTING_DEFINITION: "EXISTING_DEFINITION",
+ MessageKind.EXISTING_LABEL: "EXISTING_LABEL",
+ MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD:
+ "EXPECTED_IDENTIFIER_NOT_RESERVED_WORD",
+ MessageKind.EXPERIMENTAL_ASSERT_MESSAGE: "EXPERIMENTAL_ASSERT_MESSAGE",
+ MessageKind.EXPONENT_MISSING: "EXPONENT_MISSING",
+ MessageKind.EXPORT_BEFORE_PARTS: "EXPORT_BEFORE_PARTS",
+ MessageKind.EXTERNAL_WITH_BODY: "EXTERNAL_WITH_BODY",
+ MessageKind.EXTRA_CATCH_DECLARATION: "EXTRA_CATCH_DECLARATION",
+ MessageKind.EXTRA_FORMALS: "EXTRA_FORMALS",
+ MessageKind.EXTRANEOUS_MODIFIER: "EXTRANEOUS_MODIFIER",
+ MessageKind.EXTRANEOUS_MODIFIER_REPLACE: "EXTRANEOUS_MODIFIER_REPLACE",
+ MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY:
+ "FACTORY_REDIRECTION_IN_NON_FACTORY",
+ MessageKind.FINAL_FUNCTION_TYPE_PARAMETER: "FINAL_FUNCTION_TYPE_PARAMETER",
+ MessageKind.FINAL_WITHOUT_INITIALIZER: "FINAL_WITHOUT_INITIALIZER",
+ MessageKind.FORIN_NOT_ASSIGNABLE: "FORIN_NOT_ASSIGNABLE",
+ MessageKind.FORMAL_DECLARED_CONST: "FORMAL_DECLARED_CONST",
+ MessageKind.FORMAL_DECLARED_STATIC: "FORMAL_DECLARED_STATIC",
+ MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT:
+ "FUNCTION_TYPE_FORMAL_WITH_DEFAULT",
+ MessageKind.FUNCTION_WITH_INITIALIZER: "FUNCTION_WITH_INITIALIZER",
+ MessageKind.GENERIC: "GENERIC",
+ MessageKind.GETTER_MISMATCH: "GETTER_MISMATCH",
+ MessageKind.GETTER_NOT_FOUND: "GETTER_NOT_FOUND",
+ MessageKind.HEX_DIGIT_EXPECTED: "HEX_DIGIT_EXPECTED",
+ MessageKind.HIDDEN_HINTS: "HIDDEN_HINTS",
+ MessageKind.HIDDEN_IMPLICIT_IMPORT: "HIDDEN_IMPLICIT_IMPORT",
+ MessageKind.HIDDEN_IMPORT: "HIDDEN_IMPORT",
+ MessageKind.HIDDEN_WARNINGS: "HIDDEN_WARNINGS",
+ MessageKind.HIDDEN_WARNINGS_HINTS: "HIDDEN_WARNINGS_HINTS",
+ MessageKind.IF_NULL_ASSIGNING_TYPE: "IF_NULL_ASSIGNING_TYPE",
+ MessageKind.ILLEGAL_CONST_FIELD_MODIFIER: "ILLEGAL_CONST_FIELD_MODIFIER",
+ MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS: "ILLEGAL_CONSTRUCTOR_MODIFIERS",
+ MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER: "ILLEGAL_FINAL_METHOD_MODIFIER",
+ MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS:
+ "ILLEGAL_MIXIN_APPLICATION_MODIFIERS",
+ MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR: "ILLEGAL_MIXIN_CONSTRUCTOR",
+ MessageKind.ILLEGAL_MIXIN_CYCLE: "ILLEGAL_MIXIN_CYCLE",
+ MessageKind.ILLEGAL_MIXIN_OBJECT: "ILLEGAL_MIXIN_OBJECT",
+ MessageKind.ILLEGAL_MIXIN_SUPER_USE: "ILLEGAL_MIXIN_SUPER_USE",
+ MessageKind.ILLEGAL_MIXIN_SUPERCLASS: "ILLEGAL_MIXIN_SUPERCLASS",
+ MessageKind.ILLEGAL_MIXIN_WITH_SUPER: "ILLEGAL_MIXIN_WITH_SUPER",
+ MessageKind.ILLEGAL_SETTER_FORMALS: "ILLEGAL_SETTER_FORMALS",
+ MessageKind.ILLEGAL_STATIC: "ILLEGAL_STATIC",
+ MessageKind.ILLEGAL_SUPER_SEND: "ILLEGAL_SUPER_SEND",
+ MessageKind.IMPORT_BEFORE_PARTS: "IMPORT_BEFORE_PARTS",
+ MessageKind.IMPORT_EXPERIMENTAL_MIRRORS: "IMPORT_EXPERIMENTAL_MIRRORS",
+ MessageKind.IMPORT_PART_OF: "IMPORT_PART_OF",
+ MessageKind.IMPORT_PART_OF_HERE: "IMPORT_PART_OF_HERE",
+ MessageKind.IMPORTED_HERE: "IMPORTED_HERE",
+ MessageKind.INHERIT_GETTER_AND_METHOD: "INHERIT_GETTER_AND_METHOD",
+ MessageKind.INHERITED_EXPLICIT_GETTER: "INHERITED_EXPLICIT_GETTER",
+ MessageKind.INHERITED_IMPLICIT_GETTER: "INHERITED_IMPLICIT_GETTER",
+ MessageKind.INHERITED_METHOD: "INHERITED_METHOD",
+ MessageKind.INJECTED_PUBLIC_MEMBER: "INJECTED_PUBLIC_MEMBER",
+ MessageKind.INIT_STATIC_FIELD: "INIT_STATIC_FIELD",
+ MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED:
+ "INITIALIZING_FORMAL_NOT_ALLOWED",
+ MessageKind.INSTANCE_STATIC_SAME_NAME: "INSTANCE_STATIC_SAME_NAME",
+ MessageKind.INSTANCE_STATIC_SAME_NAME_CONT: "INSTANCE_STATIC_SAME_NAME_CONT",
+ MessageKind.INTERNAL_LIBRARY: "INTERNAL_LIBRARY",
+ MessageKind.INTERNAL_LIBRARY_FROM: "INTERNAL_LIBRARY_FROM",
+ MessageKind.INVALID_ARGUMENT_AFTER_NAMED: "INVALID_ARGUMENT_AFTER_NAMED",
+ MessageKind.INVALID_AWAIT: "INVALID_AWAIT",
+ MessageKind.INVALID_AWAIT_FOR: "INVALID_AWAIT_FOR",
+ MessageKind.INVALID_AWAIT_FOR_IN: "INVALID_AWAIT_FOR_IN",
+ MessageKind.INVALID_BREAK: "INVALID_BREAK",
+ MessageKind.INVALID_CASE_DEFAULT: "INVALID_CASE_DEFAULT",
+ MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS: "INVALID_CONSTRUCTOR_ARGUMENTS",
+ MessageKind.INVALID_CONSTRUCTOR_NAME: "INVALID_CONSTRUCTOR_NAME",
+ MessageKind.INVALID_CONTINUE: "INVALID_CONTINUE",
+ MessageKind.INVALID_FOR_IN: "INVALID_FOR_IN",
+ MessageKind.INVALID_INITIALIZER: "INVALID_INITIALIZER",
+ MessageKind.INVALID_METADATA: "INVALID_METADATA",
+ MessageKind.INVALID_METADATA_GENERIC: "INVALID_METADATA_GENERIC",
+ MessageKind.INVALID_OVERRIDDEN_FIELD: "INVALID_OVERRIDDEN_FIELD",
+ MessageKind.INVALID_OVERRIDDEN_GETTER: "INVALID_OVERRIDDEN_GETTER",
+ MessageKind.INVALID_OVERRIDDEN_METHOD: "INVALID_OVERRIDDEN_METHOD",
+ MessageKind.INVALID_OVERRIDDEN_SETTER: "INVALID_OVERRIDDEN_SETTER",
+ MessageKind.INVALID_OVERRIDE_FIELD: "INVALID_OVERRIDE_FIELD",
+ MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER:
+ "INVALID_OVERRIDE_FIELD_WITH_GETTER",
+ MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER:
+ "INVALID_OVERRIDE_FIELD_WITH_SETTER",
+ MessageKind.INVALID_OVERRIDE_GETTER: "INVALID_OVERRIDE_GETTER",
+ MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD:
+ "INVALID_OVERRIDE_GETTER_WITH_FIELD",
+ MessageKind.INVALID_OVERRIDE_METHOD: "INVALID_OVERRIDE_METHOD",
+ MessageKind.INVALID_OVERRIDE_SETTER: "INVALID_OVERRIDE_SETTER",
+ MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD:
+ "INVALID_OVERRIDE_SETTER_WITH_FIELD",
+ MessageKind.INVALID_PACKAGE_CONFIG: "INVALID_PACKAGE_CONFIG",
+ MessageKind.INVALID_PACKAGE_URI: "INVALID_PACKAGE_URI",
+ MessageKind.INVALID_PARAMETER: "INVALID_PARAMETER",
+ MessageKind.INVALID_RECEIVER_IN_INITIALIZER:
+ "INVALID_RECEIVER_IN_INITIALIZER",
+ MessageKind.INVALID_SOURCE_FILE_LOCATION: "INVALID_SOURCE_FILE_LOCATION",
+ MessageKind.INVALID_SYMBOL: "INVALID_SYMBOL",
+ MessageKind.INVALID_SYNC_MODIFIER: "INVALID_SYNC_MODIFIER",
+ MessageKind.INVALID_TYPE_VARIABLE_BOUND: "INVALID_TYPE_VARIABLE_BOUND",
+ MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME:
+ "INVALID_UNNAMED_CONSTRUCTOR_NAME",
+ MessageKind.INVALID_URI: "INVALID_URI",
+ MessageKind.INVALID_USE_OF_SUPER: "INVALID_USE_OF_SUPER",
+ MessageKind.INVALID_YIELD: "INVALID_YIELD",
+ MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS:
+ "JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS",
+ MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER:
+ "JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER",
+ MessageKind.JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS:
+ "JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS",
+ MessageKind.JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS:
+ "JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS",
+ MessageKind.JS_PLACEHOLDER_CAPTURE: "JS_PLACEHOLDER_CAPTURE",
+ MessageKind.LIBRARY_NAME_MISMATCH: "LIBRARY_NAME_MISMATCH",
+ MessageKind.LIBRARY_NOT_FOUND: "LIBRARY_NOT_FOUND",
+ MessageKind.LIBRARY_NOT_SUPPORTED: "LIBRARY_NOT_SUPPORTED",
+ MessageKind.LIBRARY_TAG_MUST_BE_FIRST: "LIBRARY_TAG_MUST_BE_FIRST",
+ MessageKind.MAIN_NOT_A_FUNCTION: "MAIN_NOT_A_FUNCTION",
+ MessageKind.MAIN_WITH_EXTRA_PARAMETER: "MAIN_WITH_EXTRA_PARAMETER",
+ MessageKind.MALFORMED_STRING_LITERAL: "MALFORMED_STRING_LITERAL",
+ MessageKind.MEMBER_NOT_FOUND: "MEMBER_NOT_FOUND",
+ MessageKind.MEMBER_NOT_STATIC: "MEMBER_NOT_STATIC",
+ MessageKind.MEMBER_USES_CLASS_NAME: "MEMBER_USES_CLASS_NAME",
+ MessageKind.METHOD_NOT_FOUND: "METHOD_NOT_FOUND",
+ MessageKind.MINUS_OPERATOR_BAD_ARITY: "MINUS_OPERATOR_BAD_ARITY",
+ MessageKind.MIRROR_BLOAT: "MIRROR_BLOAT",
+ MessageKind.MIRROR_IMPORT: "MIRROR_IMPORT",
+ MessageKind.MIRROR_IMPORT_NO_USAGE: "MIRROR_IMPORT_NO_USAGE",
+ MessageKind.MIRRORS_CANNOT_FIND_IN_ELEMENT: "MIRRORS_CANNOT_FIND_IN_ELEMENT",
+ MessageKind.MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY:
+ "MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY",
+ MessageKind.MIRRORS_CANNOT_RESOLVE_IN_LIBRARY:
+ "MIRRORS_CANNOT_RESOLVE_IN_LIBRARY",
+ MessageKind.MIRRORS_EXPECTED_STRING: "MIRRORS_EXPECTED_STRING",
+ MessageKind.MIRRORS_EXPECTED_STRING_OR_LIST:
+ "MIRRORS_EXPECTED_STRING_OR_LIST",
+ MessageKind.MIRRORS_EXPECTED_STRING_OR_TYPE:
+ "MIRRORS_EXPECTED_STRING_OR_TYPE",
+ MessageKind.MIRRORS_EXPECTED_STRING_TYPE_OR_LIST:
+ "MIRRORS_EXPECTED_STRING_TYPE_OR_LIST",
+ MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND:
+ "MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND",
+ MessageKind.MISSING_ARGUMENT: "MISSING_ARGUMENT",
+ MessageKind.MISSING_ENUM_CASES: "MISSING_ENUM_CASES",
+ MessageKind.MISSING_FACTORY_KEYWORD: "MISSING_FACTORY_KEYWORD",
+ MessageKind.MISSING_FORMALS: "MISSING_FORMALS",
+ MessageKind.MISSING_LIBRARY_NAME: "MISSING_LIBRARY_NAME",
+ MessageKind.MISSING_MAIN: "MISSING_MAIN",
+ MessageKind.MISSING_PART_OF_TAG: "MISSING_PART_OF_TAG",
+ MessageKind.MISSING_TOKEN_AFTER_THIS: "MISSING_TOKEN_AFTER_THIS",
+ MessageKind.MISSING_TOKEN_BEFORE_THIS: "MISSING_TOKEN_BEFORE_THIS",
+ MessageKind.MISSING_TYPE_ARGUMENT: "MISSING_TYPE_ARGUMENT",
+ MessageKind.MULTI_INHERITANCE: "MULTI_INHERITANCE",
+ MessageKind.NAMED_ARGUMENT_NOT_FOUND: "NAMED_ARGUMENT_NOT_FOUND",
+ MessageKind.NAMED_FUNCTION_EXPRESSION: "NAMED_FUNCTION_EXPRESSION",
+ MessageKind.NAMED_PARAMETER_WITH_EQUALS: "NAMED_PARAMETER_WITH_EQUALS",
+ MessageKind.NATIVE_NOT_SUPPORTED: "NATIVE_NOT_SUPPORTED",
+ MessageKind.NO_BREAK_TARGET: "NO_BREAK_TARGET",
+ MessageKind.NO_CATCH_NOR_FINALLY: "NO_CATCH_NOR_FINALLY",
+ MessageKind.NO_COMMON_SUBTYPES: "NO_COMMON_SUBTYPES",
+ MessageKind.NO_CONTINUE_TARGET: "NO_CONTINUE_TARGET",
+ MessageKind.NO_INSTANCE_AVAILABLE: "NO_INSTANCE_AVAILABLE",
+ MessageKind.NO_MATCHING_CONSTRUCTOR: "NO_MATCHING_CONSTRUCTOR",
+ MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT:
+ "NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT",
+ MessageKind.NO_STATIC_OVERRIDE: "NO_STATIC_OVERRIDE",
+ MessageKind.NO_STATIC_OVERRIDE_CONT: "NO_STATIC_OVERRIDE_CONT",
+ MessageKind.NO_SUCH_LIBRARY_MEMBER: "NO_SUCH_LIBRARY_MEMBER",
+ MessageKind.NO_SUCH_METHOD_IN_NATIVE: "NO_SUCH_METHOD_IN_NATIVE",
+ MessageKind.NO_SUCH_SUPER_MEMBER: "NO_SUCH_SUPER_MEMBER",
+ MessageKind.NO_SUPER_IN_STATIC: "NO_SUPER_IN_STATIC",
+ MessageKind.NO_THIS_AVAILABLE: "NO_THIS_AVAILABLE",
+ MessageKind.NON_CONST_BLOAT: "NON_CONST_BLOAT",
+ MessageKind.NOT_A_COMPILE_TIME_CONSTANT: "NOT_A_COMPILE_TIME_CONSTANT",
+ MessageKind.NOT_A_FIELD: "NOT_A_FIELD",
+ MessageKind.NOT_A_PREFIX: "NOT_A_PREFIX",
+ MessageKind.NOT_A_TYPE: "NOT_A_TYPE",
+ MessageKind.NOT_ASSIGNABLE: "NOT_ASSIGNABLE",
+ MessageKind.NOT_CALLABLE: "NOT_CALLABLE",
+ MessageKind.NOT_INSTANCE_FIELD: "NOT_INSTANCE_FIELD",
+ MessageKind.NOT_MORE_SPECIFIC: "NOT_MORE_SPECIFIC",
+ MessageKind.NOT_MORE_SPECIFIC_SUBTYPE: "NOT_MORE_SPECIFIC_SUBTYPE",
+ MessageKind.NOT_MORE_SPECIFIC_SUGGESTION: "NOT_MORE_SPECIFIC_SUGGESTION",
+ MessageKind.NULL_NOT_ALLOWED: "NULL_NOT_ALLOWED",
+ MessageKind.ONLY_ONE_LIBRARY_TAG: "ONLY_ONE_LIBRARY_TAG",
+ MessageKind.OPERATOR_NAMED_PARAMETERS: "OPERATOR_NAMED_PARAMETERS",
+ MessageKind.OPERATOR_NOT_FOUND: "OPERATOR_NOT_FOUND",
+ MessageKind.OPERATOR_OPTIONAL_PARAMETERS: "OPERATOR_OPTIONAL_PARAMETERS",
+ MessageKind.OPTIONAL_PARAMETER_IN_CATCH: "OPTIONAL_PARAMETER_IN_CATCH",
+ MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE: "OVERRIDE_EQUALS_NOT_HASH_CODE",
+ MessageKind.PARAMETER_NAME_EXPECTED: "PARAMETER_NAME_EXPECTED",
+ MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH:
+ "PARAMETER_WITH_MODIFIER_IN_CATCH",
+ MessageKind.PARAMETER_WITH_TYPE_IN_CATCH: "PARAMETER_WITH_TYPE_IN_CATCH",
+ MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION:
+ "PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION",
+ MessageKind.PATCH_NO_GETTER: "PATCH_NO_GETTER",
+ MessageKind.PATCH_NO_SETTER: "PATCH_NO_SETTER",
+ MessageKind.PATCH_NON_CLASS: "PATCH_NON_CLASS",
+ MessageKind.PATCH_NON_CONSTRUCTOR: "PATCH_NON_CONSTRUCTOR",
+ MessageKind.PATCH_NON_EXISTING: "PATCH_NON_EXISTING",
+ MessageKind.PATCH_NON_EXTERNAL: "PATCH_NON_EXTERNAL",
+ MessageKind.PATCH_NON_FUNCTION: "PATCH_NON_FUNCTION",
+ MessageKind.PATCH_NON_GETTER: "PATCH_NON_GETTER",
+ MessageKind.PATCH_NON_SETTER: "PATCH_NON_SETTER",
+ MessageKind.PATCH_NONPATCHABLE: "PATCH_NONPATCHABLE",
+ MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH:
+ "PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH",
+ MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH:
+ "PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH",
+ MessageKind.PATCH_PARAMETER_MISMATCH: "PATCH_PARAMETER_MISMATCH",
+ MessageKind.PATCH_PARAMETER_TYPE_MISMATCH: "PATCH_PARAMETER_TYPE_MISMATCH",
+ MessageKind.PATCH_POINT_TO_CLASS: "PATCH_POINT_TO_CLASS",
+ MessageKind.PATCH_POINT_TO_CONSTRUCTOR: "PATCH_POINT_TO_CONSTRUCTOR",
+ MessageKind.PATCH_POINT_TO_FUNCTION: "PATCH_POINT_TO_FUNCTION",
+ MessageKind.PATCH_POINT_TO_GETTER: "PATCH_POINT_TO_GETTER",
+ MessageKind.PATCH_POINT_TO_PARAMETER: "PATCH_POINT_TO_PARAMETER",
+ MessageKind.PATCH_POINT_TO_SETTER: "PATCH_POINT_TO_SETTER",
+ MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH:
+ "PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH",
+ MessageKind.PATCH_RETURN_TYPE_MISMATCH: "PATCH_RETURN_TYPE_MISMATCH",
+ MessageKind.PLEASE_REPORT_THE_CRASH: "PLEASE_REPORT_THE_CRASH",
+ MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS:
+ "POSITIONAL_PARAMETER_WITH_EQUALS",
+ MessageKind.POTENTIAL_MUTATION: "POTENTIAL_MUTATION",
+ MessageKind.POTENTIAL_MUTATION_HERE: "POTENTIAL_MUTATION_HERE",
+ MessageKind.POTENTIAL_MUTATION_IN_CLOSURE: "POTENTIAL_MUTATION_IN_CLOSURE",
+ MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE:
+ "POTENTIAL_MUTATION_IN_CLOSURE_HERE",
+ MessageKind.PREAMBLE: "PREAMBLE",
+ MessageKind.PREFIX_AS_EXPRESSION: "PREFIX_AS_EXPRESSION",
+ MessageKind.PRIVATE_ACCESS: "PRIVATE_ACCESS",
+ MessageKind.PRIVATE_IDENTIFIER: "PRIVATE_IDENTIFIER",
+ MessageKind.PRIVATE_NAMED_PARAMETER: "PRIVATE_NAMED_PARAMETER",
+ MessageKind.READ_SCRIPT_ERROR: "READ_SCRIPT_ERROR",
+ MessageKind.READ_SELF_ERROR: "READ_SELF_ERROR",
+ MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE: "REDIRECTING_CONSTRUCTOR_CYCLE",
+ MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY:
+ "REDIRECTING_CONSTRUCTOR_HAS_BODY",
+ MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER:
+ "REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER",
+ MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT:
+ "REDIRECTING_FACTORY_WITH_DEFAULT",
+ MessageKind.REFERENCE_IN_INITIALIZATION: "REFERENCE_IN_INITIALIZATION",
+ MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT:
+ "REQUIRED_PARAMETER_WITH_DEFAULT",
+ MessageKind.RETURN_IN_GENERATOR: "RETURN_IN_GENERATOR",
+ MessageKind.RETURN_NOTHING: "RETURN_NOTHING",
+ MessageKind.RETURN_VALUE_IN_VOID: "RETURN_VALUE_IN_VOID",
+ MessageKind.SETTER_MISMATCH: "SETTER_MISMATCH",
+ MessageKind.SETTER_NOT_FOUND: "SETTER_NOT_FOUND",
+ MessageKind.SETTER_NOT_FOUND_IN_SUPER: "SETTER_NOT_FOUND_IN_SUPER",
+ MessageKind.STATIC_FUNCTION_BLOAT: "STATIC_FUNCTION_BLOAT",
+ MessageKind.STRING_EXPECTED: "STRING_EXPECTED",
+ MessageKind.SUPER_CALL_TO_FACTORY: "SUPER_CALL_TO_FACTORY",
+ MessageKind.SUPER_INITIALIZER_IN_OBJECT: "SUPER_INITIALIZER_IN_OBJECT",
+ MessageKind.SWITCH_CASE_FORBIDDEN: "SWITCH_CASE_FORBIDDEN",
+ MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL: "SWITCH_CASE_TYPES_NOT_EQUAL",
+ MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE:
+ "SWITCH_CASE_TYPES_NOT_EQUAL_CASE",
+ MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS:
+ "SWITCH_CASE_VALUE_OVERRIDES_EQUALS",
+ MessageKind.TERNARY_OPERATOR_BAD_ARITY: "TERNARY_OPERATOR_BAD_ARITY",
+ MessageKind.THIS_CALL_TO_FACTORY: "THIS_CALL_TO_FACTORY",
+ MessageKind.THIS_IS_THE_DECLARATION: "THIS_IS_THE_DECLARATION",
+ MessageKind.THIS_IS_THE_METHOD: "THIS_IS_THE_METHOD",
+ MessageKind.THIS_IS_THE_PART_OF_TAG: "THIS_IS_THE_PART_OF_TAG",
+ MessageKind.THIS_PROPERTY: "THIS_PROPERTY",
+ MessageKind.THROW_WITHOUT_EXPRESSION: "THROW_WITHOUT_EXPRESSION",
+ MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC:
+ "TOP_LEVEL_VARIABLE_DECLARED_STATIC",
+ MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH: "TYPE_ARGUMENT_COUNT_MISMATCH",
+ MessageKind.TYPE_VARIABLE_IN_CONSTANT: "TYPE_VARIABLE_IN_CONSTANT",
+ MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER:
+ "TYPE_VARIABLE_WITHIN_STATIC_MEMBER",
+ MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT: "TYPEDEF_FORMAL_WITH_DEFAULT",
+ MessageKind.UNARY_OPERATOR_BAD_ARITY: "UNARY_OPERATOR_BAD_ARITY",
+ MessageKind.UNBOUND_LABEL: "UNBOUND_LABEL",
+ MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER: "UNIMPLEMENTED_EXPLICIT_GETTER",
+ MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER: "UNIMPLEMENTED_EXPLICIT_SETTER",
+ MessageKind.UNIMPLEMENTED_GETTER: "UNIMPLEMENTED_GETTER",
+ MessageKind.UNIMPLEMENTED_GETTER_ONE: "UNIMPLEMENTED_GETTER_ONE",
+ MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER: "UNIMPLEMENTED_IMPLICIT_GETTER",
+ MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER: "UNIMPLEMENTED_IMPLICIT_SETTER",
+ MessageKind.UNIMPLEMENTED_METHOD: "UNIMPLEMENTED_METHOD",
+ MessageKind.UNIMPLEMENTED_METHOD_CONT: "UNIMPLEMENTED_METHOD_CONT",
+ MessageKind.UNIMPLEMENTED_METHOD_ONE: "UNIMPLEMENTED_METHOD_ONE",
+ MessageKind.UNIMPLEMENTED_SETTER: "UNIMPLEMENTED_SETTER",
+ MessageKind.UNIMPLEMENTED_SETTER_ONE: "UNIMPLEMENTED_SETTER_ONE",
+ MessageKind.UNMATCHED_TOKEN: "UNMATCHED_TOKEN",
+ MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP:
+ "UNRECOGNIZED_VERSION_OF_LOOKUP_MAP",
+ MessageKind.UNSUPPORTED_BANG_EQ_EQ: "UNSUPPORTED_BANG_EQ_EQ",
+ MessageKind.UNSUPPORTED_EQ_EQ_EQ: "UNSUPPORTED_EQ_EQ_EQ",
+ MessageKind.UNSUPPORTED_LITERAL_SYMBOL: "UNSUPPORTED_LITERAL_SYMBOL",
+ MessageKind.UNSUPPORTED_PREFIX_PLUS: "UNSUPPORTED_PREFIX_PLUS",
+ MessageKind.UNSUPPORTED_THROW_WITHOUT_EXP: "UNSUPPORTED_THROW_WITHOUT_EXP",
+ MessageKind.UNTERMINATED_COMMENT: "UNTERMINATED_COMMENT",
+ MessageKind.UNTERMINATED_STRING: "UNTERMINATED_STRING",
+ MessageKind.UNTERMINATED_TOKEN: "UNTERMINATED_TOKEN",
+ MessageKind.UNUSED_CLASS: "UNUSED_CLASS",
+ MessageKind.UNUSED_LABEL: "UNUSED_LABEL",
+ MessageKind.UNUSED_METHOD: "UNUSED_METHOD",
+ MessageKind.UNUSED_TYPEDEF: "UNUSED_TYPEDEF",
+ MessageKind.VAR_FUNCTION_TYPE_PARAMETER: "VAR_FUNCTION_TYPE_PARAMETER",
+ MessageKind.VOID_EXPRESSION: "VOID_EXPRESSION",
+ MessageKind.VOID_NOT_ALLOWED: "VOID_NOT_ALLOWED",
+ MessageKind.VOID_VARIABLE: "VOID_VARIABLE",
+ MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT:
+ "WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT",
+ MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT:
+ "WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT",
+ MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY:
+ "YIELDING_MODIFIER_ON_ARROW_BODY",
+};
+
/// A message template for an error, warning, hint or info message generated
/// by the compiler. Each template is associated with a [MessageKind] that
/// uniquely identifies the message template.
@@ -467,6 +868,8 @@
class MessageTemplate {
final MessageKind kind;
+ final String id;
+
/// Should describe what is wrong and why.
final String template;
@@ -486,3090 +889,8 @@
/// Additional options needed for the examples to work.
final List<String> options;
- const MessageTemplate(
- this.kind,
- this.template,
- {this.howToFix,
- this.examples,
- this.options: const <String>[]});
-
- /// All templates used by the compiler.
- ///
- /// The map is complete mapping from [MessageKind] to their corresponding
- /// [MessageTemplate].
- static const Map<MessageKind, MessageTemplate> TEMPLATES =
- const <MessageKind, MessageTemplate>{
- /// Do not use this. It is here for legacy and debugging. It violates item
- /// 4 of the guide lines for error messages in the beginning of the file.
- MessageKind.GENERIC:
- const MessageTemplate(MessageKind.GENERIC, '#{text}'),
-
- MessageKind.NOT_ASSIGNABLE:
- const MessageTemplate(MessageKind.NOT_ASSIGNABLE,
- "'#{fromType}' is not assignable to '#{toType}'."),
-
- MessageKind.FORIN_NOT_ASSIGNABLE:
- const MessageTemplate(MessageKind.FORIN_NOT_ASSIGNABLE,
- "The element type '#{currentType}' of '#{expressionType}' "
- "is not assignable to '#{elementType}'."),
-
- MessageKind.VOID_EXPRESSION:
- const MessageTemplate(MessageKind.VOID_EXPRESSION,
- "Expression does not yield a value."),
-
- MessageKind.VOID_VARIABLE:
- const MessageTemplate(MessageKind.VOID_VARIABLE,
- "Variable cannot be of type void."),
-
- MessageKind.RETURN_VALUE_IN_VOID:
- const MessageTemplate(MessageKind.RETURN_VALUE_IN_VOID,
- "Cannot return value from void function."),
-
- MessageKind.RETURN_NOTHING:
- const MessageTemplate(MessageKind.RETURN_NOTHING,
- "Value of type '#{returnType}' expected."),
-
- MessageKind.MISSING_ARGUMENT:
- const MessageTemplate(MessageKind.MISSING_ARGUMENT,
- "Missing argument of type '#{argumentType}'."),
-
- MessageKind.ADDITIONAL_ARGUMENT:
- const MessageTemplate(MessageKind.ADDITIONAL_ARGUMENT,
- "Additional argument."),
-
- MessageKind.NAMED_ARGUMENT_NOT_FOUND:
- const MessageTemplate(MessageKind.NAMED_ARGUMENT_NOT_FOUND,
- "No named argument '#{argumentName}' found on method."),
-
- MessageKind.MEMBER_NOT_FOUND:
- const MessageTemplate(MessageKind.MEMBER_NOT_FOUND,
- "No member named '#{memberName}' in class '#{className}'."),
-
- MessageKind.AWAIT_MEMBER_NOT_FOUND:
- const MessageTemplate(MessageKind.AWAIT_MEMBER_NOT_FOUND,
- "No member named 'await' in class '#{className}'.",
- howToFix: "Did you mean to add the 'async' marker "
- "to '#{functionName}'?",
- examples: const ["""
-class A {
- m() => await -3;
-}
-main() => new A().m();
-"""]),
-
- MessageKind.AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE:
- const MessageTemplate(MessageKind.AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE,
- "No member named 'await' in class '#{className}'.",
- howToFix: "Did you mean to add the 'async' marker "
- "to the enclosing function?",
- examples: const ["""
-class A {
- m() => () => await -3;
-}
-main() => new A().m();
-"""]),
-
- MessageKind.METHOD_NOT_FOUND:
- const MessageTemplate(MessageKind.METHOD_NOT_FOUND,
- "No method named '#{memberName}' in class '#{className}'."),
-
- MessageKind.OPERATOR_NOT_FOUND:
- const MessageTemplate(MessageKind.OPERATOR_NOT_FOUND,
- "No operator '#{memberName}' in class '#{className}'."),
-
- MessageKind.SETTER_NOT_FOUND:
- const MessageTemplate(MessageKind.SETTER_NOT_FOUND,
- "No setter named '#{memberName}' in class '#{className}'."),
-
- MessageKind.SETTER_NOT_FOUND_IN_SUPER:
- const MessageTemplate(MessageKind.SETTER_NOT_FOUND_IN_SUPER,
- "No setter named '#{name}' in superclass of '#{className}'."),
-
- MessageKind.GETTER_NOT_FOUND:
- const MessageTemplate(MessageKind.GETTER_NOT_FOUND,
- "No getter named '#{memberName}' in class '#{className}'."),
-
- MessageKind.NOT_CALLABLE:
- const MessageTemplate(MessageKind.NOT_CALLABLE,
- "'#{elementName}' is not callable."),
-
- MessageKind.MEMBER_NOT_STATIC:
- const MessageTemplate(MessageKind.MEMBER_NOT_STATIC,
- "'#{className}.#{memberName}' is not static."),
-
- MessageKind.NO_INSTANCE_AVAILABLE:
- const MessageTemplate(MessageKind.NO_INSTANCE_AVAILABLE,
- "'#{name}' is only available in instance methods."),
-
- MessageKind.NO_THIS_AVAILABLE:
- const MessageTemplate(MessageKind.NO_THIS_AVAILABLE,
- "'this' is only available in instance methods."),
-
- MessageKind.PRIVATE_ACCESS:
- const MessageTemplate(MessageKind.PRIVATE_ACCESS,
- "'#{name}' is declared private within library "
- "'#{libraryName}'."),
-
- MessageKind.THIS_IS_THE_DECLARATION:
- const MessageTemplate(MessageKind.THIS_IS_THE_DECLARATION,
- "This is the declaration of '#{name}'."),
-
- MessageKind.THIS_IS_THE_METHOD:
- const MessageTemplate(MessageKind.THIS_IS_THE_METHOD,
- "This is the method declaration."),
-
- MessageKind.CANNOT_RESOLVE:
- const MessageTemplate(MessageKind.CANNOT_RESOLVE,
- "Cannot resolve '#{name}'."),
-
- MessageKind.CANNOT_RESOLVE_AWAIT:
- const MessageTemplate(MessageKind.CANNOT_RESOLVE_AWAIT,
- "Cannot resolve '#{name}'.",
- howToFix: "Did you mean to add the 'async' marker "
- "to '#{functionName}'?",
- examples: const [
- "main() => await -3;",
- "foo() => await -3; main() => foo();"
- ]),
-
- MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE:
- const MessageTemplate(MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE,
- "Cannot resolve '#{name}'.",
- howToFix: "Did you mean to add the 'async' marker "
- "to the enclosing function?",
- examples: const [
- "main() { (() => await -3)(); }",
- ]),
-
- MessageKind.CANNOT_RESOLVE_IN_INITIALIZER:
- const MessageTemplate(MessageKind.CANNOT_RESOLVE_IN_INITIALIZER,
- "Cannot resolve '#{name}'. It would be implicitly looked up on this "
- "instance, but instances are not available in initializers.",
- howToFix: "Try correcting the unresolved reference or move the "
- "initialization to a constructor body.",
- examples: const ["""
-class A {
- var test = unresolvedName;
-}
-main() => new A();
-"""]),
-
- MessageKind.CANNOT_RESOLVE_CONSTRUCTOR:
- const MessageTemplate(MessageKind.CANNOT_RESOLVE_CONSTRUCTOR,
- "Cannot resolve constructor '#{constructorName}'."),
-
- MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT:
- const MessageTemplate(
- MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT,
- "cannot resolve constructor '#{constructorName}' "
- "for implicit super call.",
- howToFix: "Try explicitly invoking a constructor of the super class",
- examples: const ["""
-class A {
- A.foo() {}
-}
-class B extends A {
- B();
-}
-main() => new B();
-"""]),
-
- MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME:
- const MessageTemplate(MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME,
- "Unnamed constructor name must be '#{name}'."),
-
- MessageKind.INVALID_CONSTRUCTOR_NAME:
- const MessageTemplate(MessageKind.INVALID_CONSTRUCTOR_NAME,
- "Constructor name must start with '#{name}'."),
-
- MessageKind.CANNOT_RESOLVE_TYPE:
- const MessageTemplate(MessageKind.CANNOT_RESOLVE_TYPE,
- "Cannot resolve type '#{typeName}'."),
-
- MessageKind.DUPLICATE_DEFINITION:
- const MessageTemplate(MessageKind.DUPLICATE_DEFINITION,
- "Duplicate definition of '#{name}'.",
- howToFix: "Try to rename or remove this definition.",
- examples: const ["""
-class C {
- void f() {}
- int get f => 1;
-}
-
-main() {
- new C();
-}
-
-"""]),
-
- MessageKind.EXISTING_DEFINITION:
- const MessageTemplate(MessageKind.EXISTING_DEFINITION,
- "Existing definition of '#{name}'."),
-
- MessageKind.DUPLICATE_IMPORT:
- const MessageTemplate(MessageKind.DUPLICATE_IMPORT,
- "Duplicate import of '#{name}'."),
-
- MessageKind.HIDDEN_IMPORT:
- const MessageTemplate(MessageKind.HIDDEN_IMPORT,
- "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
- "from library '#{hidingUri}'.",
- howToFix:
- "Try adding 'hide #{name}' to the import of '#{hiddenUri}'.",
- examples: const [
- const {
-'main.dart':
-"""
-import 'dart:async'; // This imports a class Future.
-import 'future.dart';
-
-void main() => new Future();""",
-
-'future.dart':
-"""
-library future;
-
-class Future {}"""},
-
- const {
-'main.dart':
-"""
-import 'future.dart';
-import 'dart:async'; // This imports a class Future.
-
-void main() => new Future();""",
-
-'future.dart':
-"""
-library future;
-
-class Future {}"""},
-
- const {
-'main.dart':
-"""
-import 'export.dart';
-import 'dart:async'; // This imports a class Future.
-
-void main() => new Future();""",
-
-'future.dart':
-"""
-library future;
-
-class Future {}""",
-
-'export.dart':
-"""
-library export;
-
-export 'future.dart';"""},
-
- const {
-'main.dart':
-"""
-import 'future.dart' as prefix;
-import 'dart:async' as prefix; // This imports a class Future.
-
-void main() => new prefix.Future();""",
-
-'future.dart':
-"""
-library future;
-
-class Future {}"""}]),
-
-
- MessageKind.HIDDEN_IMPLICIT_IMPORT:
- const MessageTemplate(MessageKind.HIDDEN_IMPLICIT_IMPORT,
- "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
- "from library '#{hidingUri}'.",
- howToFix: "Try adding an explicit "
- "'import \"#{hiddenUri}\" hide #{name}'.",
- examples: const [
- const {
-'main.dart':
-"""
-// This hides the implicit import of class Type from dart:core.
-import 'type.dart';
-
-void main() => new Type();""",
-
-'type.dart':
-"""
-library type;
-
-class Type {}"""},
- const {
-'conflictsWithDart.dart':
-"""
-library conflictsWithDart;
-
-class Duration {
- static var x = 100;
-}
-""",
-
-'conflictsWithDartAsWell.dart':
-"""
-library conflictsWithDartAsWell;
-
-class Duration {
- static var x = 100;
-}
-""",
-
-'main.dart':
-r"""
-library testDartConflicts;
-
-import 'conflictsWithDart.dart';
-import 'conflictsWithDartAsWell.dart';
-
-main() {
- print("Hail Caesar ${Duration.x}");
-}
-"""}]),
-
- MessageKind.DUPLICATE_EXPORT:
- const MessageTemplate(MessageKind.DUPLICATE_EXPORT,
- "Duplicate export of '#{name}'.",
- howToFix: "Try adding 'hide #{name}' to one of the exports.",
- examples: const [const {
-'main.dart': """
-export 'decl1.dart';
-export 'decl2.dart';
-
-main() {}""",
-'decl1.dart': "class Class {}",
-'decl2.dart': "class Class {}"}]),
-
- MessageKind.DUPLICATE_EXPORT_CONT:
- const MessageTemplate(MessageKind.DUPLICATE_EXPORT_CONT,
- "This is another export of '#{name}'."),
-
- MessageKind.DUPLICATE_EXPORT_DECL:
- const MessageTemplate(MessageKind.DUPLICATE_EXPORT_DECL,
- "The exported '#{name}' from export #{uriString} is defined here."),
-
- MessageKind.EMPTY_HIDE:
- const MessageTemplate(MessageKind.EMPTY_HIDE,
- "Library '#{uri}' doesn't export a '#{name}' declaration.",
- howToFix: "Try removing '#{name}' the 'hide' clause.",
- examples: const [
- const {
- 'main.dart': """
-import 'dart:core' hide Foo;
-
-main() {}"""},
- const {
-'main.dart': """
-export 'dart:core' hide Foo;
-
-main() {}"""},
-]),
-
- MessageKind.EMPTY_SHOW:
- const MessageTemplate(MessageKind.EMPTY_SHOW,
- "Library '#{uri}' doesn't export a '#{name}' declaration.",
- howToFix: "Try removing '#{name}' from the 'show' clause.",
- examples: const [
- const {
- 'main.dart': """
-import 'dart:core' show Foo;
-
-main() {}"""},
- const {
-'main.dart': """
-export 'dart:core' show Foo;
-
-main() {}"""},
-]),
-
- MessageKind.NOT_A_TYPE:
- const MessageTemplate(MessageKind.NOT_A_TYPE,
- "'#{node}' is not a type."),
-
- MessageKind.NOT_A_PREFIX:
- const MessageTemplate(MessageKind.NOT_A_PREFIX,
- "'#{node}' is not a prefix."),
-
- MessageKind.PREFIX_AS_EXPRESSION:
- const MessageTemplate(MessageKind.PREFIX_AS_EXPRESSION,
- "Library prefix '#{prefix}' is not a valid expression."),
-
- MessageKind.CANNOT_FIND_CONSTRUCTOR:
- const MessageTemplate(MessageKind.CANNOT_FIND_CONSTRUCTOR,
- "Cannot find constructor '#{constructorName}' in class "
- "'#{className}'."),
-
- MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR:
- const MessageTemplate(MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR,
- "Cannot find unnamed constructor in class "
- "'#{className}'."),
-
- MessageKind.CYCLIC_CLASS_HIERARCHY:
- const MessageTemplate(MessageKind.CYCLIC_CLASS_HIERARCHY,
- "'#{className}' creates a cycle in the class hierarchy."),
-
- MessageKind.CYCLIC_REDIRECTING_FACTORY:
- const MessageTemplate(MessageKind.CYCLIC_REDIRECTING_FACTORY,
- 'Redirecting factory leads to a cyclic redirection.'),
-
- MessageKind.INVALID_RECEIVER_IN_INITIALIZER:
- const MessageTemplate(MessageKind.INVALID_RECEIVER_IN_INITIALIZER,
- "Field initializer expected."),
-
- MessageKind.NO_SUPER_IN_STATIC:
- const MessageTemplate(MessageKind.NO_SUPER_IN_STATIC,
- "'super' is only available in instance methods."),
-
- MessageKind.DUPLICATE_INITIALIZER:
- const MessageTemplate(MessageKind.DUPLICATE_INITIALIZER,
- "Field '#{fieldName}' is initialized more than once."),
-
- MessageKind.ALREADY_INITIALIZED:
- const MessageTemplate(MessageKind.ALREADY_INITIALIZED,
- "'#{fieldName}' was already initialized here."),
-
- MessageKind.INIT_STATIC_FIELD:
- const MessageTemplate(MessageKind.INIT_STATIC_FIELD,
- "Cannot initialize static field '#{fieldName}'."),
-
- MessageKind.NOT_A_FIELD:
- const MessageTemplate(MessageKind.NOT_A_FIELD,
- "'#{fieldName}' is not a field."),
-
- MessageKind.CONSTRUCTOR_CALL_EXPECTED:
- const MessageTemplate(MessageKind.CONSTRUCTOR_CALL_EXPECTED,
- "only call to 'this' or 'super' constructor allowed."),
-
- MessageKind.INVALID_FOR_IN:
- const MessageTemplate(MessageKind.INVALID_FOR_IN,
- "Invalid for-in variable declaration."),
-
- MessageKind.INVALID_INITIALIZER:
- const MessageTemplate(MessageKind.INVALID_INITIALIZER,
- "Invalid initializer."),
-
- MessageKind.FUNCTION_WITH_INITIALIZER:
- const MessageTemplate(MessageKind.FUNCTION_WITH_INITIALIZER,
- "Only constructors can have initializers."),
-
- MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE:
- const MessageTemplate(MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE,
- "Cyclic constructor redirection."),
-
- MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY:
- const MessageTemplate(MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY,
- "Redirecting constructor can't have a body."),
-
- MessageKind.CONST_CONSTRUCTOR_HAS_BODY:
- const MessageTemplate(MessageKind.CONST_CONSTRUCTOR_HAS_BODY,
- "Const constructor or factory can't have a body.",
- howToFix: "Remove the 'const' keyword or the body",
- examples: const ["""
-class C {
- const C() {}
-}
-
-main() => new C();"""]),
-
- MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER:
- const MessageTemplate(
- MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER,
- "Redirecting constructor cannot have other initializers."),
-
- MessageKind.SUPER_INITIALIZER_IN_OBJECT:
- const MessageTemplate(MessageKind.SUPER_INITIALIZER_IN_OBJECT,
- "'Object' cannot have a super initializer."),
-
- MessageKind.DUPLICATE_SUPER_INITIALIZER:
- const MessageTemplate(MessageKind.DUPLICATE_SUPER_INITIALIZER,
- "Cannot have more than one super initializer."),
-
- MessageKind.SUPER_CALL_TO_FACTORY:
- const MessageTemplate(MessageKind.SUPER_CALL_TO_FACTORY,
- "The target of the superinitializer must be a generative "
- "constructor.",
- howToFix: "Try calling another constructor on the superclass.",
- examples: const ["""
-class Super {
- factory Super() => null;
-}
-class Class extends Super {}
-main() => new Class();
-""", """
-class Super {
- factory Super() => null;
-}
-class Class extends Super {
- Class();
-}
-main() => new Class();
-""", """
-class Super {
- factory Super() => null;
-}
-class Class extends Super {
- Class() : super();
-}
-main() => new Class();
-""", """
-class Super {
- factory Super.foo() => null;
-}
-class Class extends Super {
- Class() : super.foo();
-}
-main() => new Class();
-"""]),
-
- MessageKind.THIS_CALL_TO_FACTORY:
- const MessageTemplate(MessageKind.THIS_CALL_TO_FACTORY,
- "The target of the redirection clause must be a generative "
- "constructor",
- howToFix: "Try redirecting to another constructor.",
- examples: const ["""
-class Class {
- factory Class() => null;
- Class.foo() : this();
-}
-main() => new Class.foo();
-""", """
-class Class {
- factory Class.foo() => null;
- Class() : this.foo();
-}
-main() => new Class();
-"""]),
-
- MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS:
- const MessageTemplate(MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS,
- "Arguments do not match the expected parameters of constructor "
- "'#{constructorName}'."),
-
- MessageKind.NO_MATCHING_CONSTRUCTOR:
- const MessageTemplate(MessageKind.NO_MATCHING_CONSTRUCTOR,
- "'super' call arguments and constructor parameters do not match."),
-
- MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT:
- const MessageTemplate(MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT,
- "Implicit 'super' call arguments and constructor parameters "
- "do not match."),
-
- MessageKind.CONST_CALLS_NON_CONST:
- const MessageTemplate(MessageKind.CONST_CALLS_NON_CONST,
- "'const' constructor cannot call a non-const constructor."),
-
- MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT:
- const MessageTemplate(MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT,
- "'const' constructor cannot call a non-const constructor. "
- "This constructor has an implicit call to a "
- "super non-const constructor.",
- howToFix: "Try making the super constructor const.",
- examples: const ["""
-class C {
- C(); // missing const
-}
-class D extends C {
- final d;
- const D(this.d);
-}
-main() => new D(0);"""]),
-
- MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS:
- const MessageTemplate(
- MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
- "Can't declare constructor 'const' on class #{className} "
- "because the class contains non-final instance fields.",
- howToFix: "Try making all fields final.",
- examples: const ["""
-class C {
- // 'a' must be declared final to allow for the const constructor.
- var a;
- const C(this.a);
-}
-
-main() => new C(0);"""]),
-
- MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD:
- const MessageTemplate(
- MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD,
- "This non-final field prevents using const constructors."),
-
- MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR:
- const MessageTemplate(
- MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR,
- "This const constructor is not allowed due to "
- "non-final fields."),
-
-
- MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED:
- const MessageTemplate(MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED,
- "Initializing formal parameter only allowed in generative "
- "constructor."),
-
- MessageKind.INVALID_PARAMETER:
- const MessageTemplate(MessageKind.INVALID_PARAMETER,
- "Cannot resolve parameter."),
-
- MessageKind.NOT_INSTANCE_FIELD:
- const MessageTemplate(MessageKind.NOT_INSTANCE_FIELD,
- "'#{fieldName}' is not an instance field."),
-
- MessageKind.THIS_PROPERTY:
- const MessageTemplate(MessageKind.THIS_PROPERTY,
- "Expected an identifier."),
-
- MessageKind.NO_CATCH_NOR_FINALLY:
- const MessageTemplate(MessageKind.NO_CATCH_NOR_FINALLY,
- "Expected 'catch' or 'finally'."),
-
- MessageKind.EMPTY_CATCH_DECLARATION:
- const MessageTemplate(MessageKind.EMPTY_CATCH_DECLARATION,
- "Expected an identifier in catch declaration."),
-
- MessageKind.EXTRA_CATCH_DECLARATION:
- const MessageTemplate(MessageKind.EXTRA_CATCH_DECLARATION,
- "Extra parameter in catch declaration."),
-
- MessageKind.PARAMETER_WITH_TYPE_IN_CATCH:
- const MessageTemplate(MessageKind.PARAMETER_WITH_TYPE_IN_CATCH,
- "Cannot use type annotations in catch."),
-
- MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH:
- const MessageTemplate(MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH,
- "Cannot use modifiers in catch."),
-
- MessageKind.OPTIONAL_PARAMETER_IN_CATCH:
- const MessageTemplate(MessageKind.OPTIONAL_PARAMETER_IN_CATCH,
- "Cannot use optional parameters in catch."),
-
- MessageKind.THROW_WITHOUT_EXPRESSION:
- const MessageTemplate(MessageKind.THROW_WITHOUT_EXPRESSION,
- "Cannot use re-throw outside of catch block "
- "(expression expected after 'throw')."),
-
- MessageKind.UNBOUND_LABEL:
- const MessageTemplate(MessageKind.UNBOUND_LABEL,
- "Cannot resolve label '#{labelName}'."),
-
- MessageKind.NO_BREAK_TARGET:
- const MessageTemplate(MessageKind.NO_BREAK_TARGET,
- "'break' statement not inside switch or loop."),
-
- MessageKind.NO_CONTINUE_TARGET:
- const MessageTemplate(MessageKind.NO_CONTINUE_TARGET,
- "'continue' statement not inside loop."),
-
- MessageKind.EXISTING_LABEL:
- const MessageTemplate(MessageKind.EXISTING_LABEL,
- "Original declaration of duplicate label '#{labelName}'."),
-
- MessageKind.DUPLICATE_LABEL:
- const MessageTemplate(MessageKind.DUPLICATE_LABEL,
- "Duplicate declaration of label '#{labelName}'."),
-
- MessageKind.UNUSED_LABEL:
- const MessageTemplate(MessageKind.UNUSED_LABEL,
- "Unused label '#{labelName}'."),
-
- MessageKind.INVALID_CONTINUE:
- const MessageTemplate(MessageKind.INVALID_CONTINUE,
- "Target of continue is not a loop or switch case."),
-
- MessageKind.INVALID_BREAK:
- const MessageTemplate(MessageKind.INVALID_BREAK,
- "Target of break is not a statement."),
-
- MessageKind.DUPLICATE_TYPE_VARIABLE_NAME:
- const MessageTemplate(MessageKind.DUPLICATE_TYPE_VARIABLE_NAME,
- "Type variable '#{typeVariableName}' already declared."),
-
- MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER:
- const MessageTemplate(MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
- "Cannot refer to type variable '#{typeVariableName}' "
- "within a static member."),
-
- MessageKind.TYPE_VARIABLE_IN_CONSTANT:
- const MessageTemplate(MessageKind.TYPE_VARIABLE_IN_CONSTANT,
- "Constant expressions can't refer to type variables.",
- howToFix: "Try removing the type variable or replacing it with a "
- "concrete type.",
- examples: const ["""
-class C<T> {
- const C();
-
- m(T t) => const C<T>();
-}
-
-void main() => new C().m(null);
-"""
-]),
-
- MessageKind.INVALID_TYPE_VARIABLE_BOUND:
- const MessageTemplate(MessageKind.INVALID_TYPE_VARIABLE_BOUND,
- "'#{typeArgument}' is not a subtype of bound '#{bound}' for "
- "type variable '#{typeVariable}' of type '#{thisType}'.",
- howToFix: "Try to change or remove the type argument.",
- examples: const ["""
-class C<T extends num> {}
-
-// 'String' is not a valid instantiation of T with bound num.'.
-main() => new C<String>();
-"""]),
-
- MessageKind.INVALID_USE_OF_SUPER:
- const MessageTemplate(MessageKind.INVALID_USE_OF_SUPER,
- "'super' not allowed here."),
-
- MessageKind.INVALID_CASE_DEFAULT:
- const MessageTemplate(MessageKind.INVALID_CASE_DEFAULT,
- "'default' only allowed on last case of a switch."),
-
- MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL:
- const MessageTemplate(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL,
- "'case' expressions do not all have type '#{type}'."),
-
- MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE:
- const MessageTemplate(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
- "'case' expression of type '#{type}'."),
-
- MessageKind.SWITCH_CASE_FORBIDDEN:
- const MessageTemplate(MessageKind.SWITCH_CASE_FORBIDDEN,
- "'case' expression may not be of type '#{type}'."),
-
- MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS:
- const MessageTemplate(MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
- "'case' expression type '#{type}' overrides 'operator =='."),
-
- MessageKind.INVALID_ARGUMENT_AFTER_NAMED:
- const MessageTemplate(MessageKind.INVALID_ARGUMENT_AFTER_NAMED,
- "Unnamed argument after named argument."),
-
- MessageKind.NOT_A_COMPILE_TIME_CONSTANT:
- const MessageTemplate(MessageKind.NOT_A_COMPILE_TIME_CONSTANT,
- "Not a compile-time constant."),
-
- MessageKind.DEFERRED_COMPILE_TIME_CONSTANT:
- const MessageTemplate(MessageKind.DEFERRED_COMPILE_TIME_CONSTANT,
- "A deferred value cannot be used as a compile-time constant."),
-
- MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION:
- const MessageTemplate(
- MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION,
- "A deferred class cannot be used to create a "
- "compile-time constant."),
-
- MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS:
- const MessageTemplate(MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS,
- "Cycle in the compile-time constant computation."),
-
- MessageKind.CONSTRUCTOR_IS_NOT_CONST:
- const MessageTemplate(MessageKind.CONSTRUCTOR_IS_NOT_CONST,
- "Constructor is not a 'const' constructor."),
-
- MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS:
- const MessageTemplate(MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS,
- "Const-map key type '#{type}' overrides 'operator =='."),
-
- MessageKind.NO_SUCH_LIBRARY_MEMBER:
- const MessageTemplate(MessageKind.NO_SUCH_LIBRARY_MEMBER,
- "'#{libraryName}' has no member named '#{memberName}'."),
-
- MessageKind.CANNOT_INSTANTIATE_TYPEDEF:
- const MessageTemplate(MessageKind.CANNOT_INSTANTIATE_TYPEDEF,
- "Cannot instantiate typedef '#{typedefName}'."),
-
- MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT:
- const MessageTemplate(MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT,
- "Non-optional parameters can't have a default value.",
- howToFix:
- "Try removing the default value or making the parameter optional.",
- examples: const ["""
-main() {
- foo(a: 1) => print(a);
- foo(2);
-}""", """
-main() {
- foo(a = 1) => print(a);
- foo(2);
-}"""]),
-
- MessageKind.NAMED_PARAMETER_WITH_EQUALS:
- const MessageTemplate(MessageKind.NAMED_PARAMETER_WITH_EQUALS,
- "Named optional parameters can't use '=' to specify a default "
- "value.",
- howToFix: "Try replacing '=' with ':'.",
- examples: const ["""
-main() {
- foo({a = 1}) => print(a);
- foo(a: 2);
-}"""]),
-
- MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS:
- const MessageTemplate(MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS,
- "Positional optional parameters can't use ':' to specify a "
- "default value.",
- howToFix: "Try replacing ':' with '='.",
- examples: const ["""
-main() {
- foo([a: 1]) => print(a);
- foo(2);
-}"""]),
-
- MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT:
- const MessageTemplate(MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT,
- "A parameter of a typedef can't specify a default value.",
- howToFix:
- "Try removing the default value.",
- examples: const ["""
-typedef void F([int arg = 0]);
-
-main() {
- F f;
-}""", """
-typedef void F({int arg: 0});
-
-main() {
- F f;
-}"""]),
-
- MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT:
- const MessageTemplate(MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT,
- "A function type parameter can't specify a default value.",
- howToFix:
- "Try removing the default value.",
- examples: const ["""
-foo(f(int i, [a = 1])) {}
-
-main() {
- foo(1, 2);
-}""", """
-foo(f(int i, {a: 1})) {}
-
-main() {
- foo(1, a: 2);
-}"""]),
-
- MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT:
- const MessageTemplate(MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT,
- "A parameter of a redirecting factory constructor can't specify a "
- "default value.",
- howToFix:
- "Try removing the default value.",
- examples: const ["""
-class A {
- A([a]);
- factory A.foo([a = 1]) = A;
-}
-
-main() {
- new A.foo(1);
-}""", """
-class A {
- A({a});
- factory A.foo({a: 1}) = A;
-}
-
-main() {
- new A.foo(a: 1);
-}"""]),
-
- MessageKind.FORMAL_DECLARED_CONST:
- const MessageTemplate(MessageKind.FORMAL_DECLARED_CONST,
- "A formal parameter can't be declared const.",
- howToFix: "Try removing 'const'.",
- examples: const ["""
-foo(const x) {}
-main() => foo(42);
-""", """
-foo({const x}) {}
-main() => foo(42);
-""", """
-foo([const x]) {}
-main() => foo(42);
-"""]),
-
- MessageKind.FORMAL_DECLARED_STATIC:
- const MessageTemplate(MessageKind.FORMAL_DECLARED_STATIC,
- "A formal parameter can't be declared static.",
- howToFix: "Try removing 'static'.",
- examples: const ["""
-foo(static x) {}
-main() => foo(42);
-""", """
-foo({static x}) {}
-main() => foo(42);
-""", """
-foo([static x]) {}
-main() => foo(42);
-"""]),
-
- MessageKind.FINAL_FUNCTION_TYPE_PARAMETER:
- const MessageTemplate(MessageKind.FINAL_FUNCTION_TYPE_PARAMETER,
- "A function type parameter can't be declared final.",
- howToFix: "Try removing 'final'.",
- examples: const ["""
-foo(final int x(int a)) {}
-main() => foo((y) => 42);
-""", """
-foo({final int x(int a)}) {}
-main() => foo((y) => 42);
-""", """
-foo([final int x(int a)]) {}
-main() => foo((y) => 42);
-"""]),
-
- MessageKind.VAR_FUNCTION_TYPE_PARAMETER:
- const MessageTemplate(MessageKind.VAR_FUNCTION_TYPE_PARAMETER,
- "A function type parameter can't be declared with 'var'.",
- howToFix: "Try removing 'var'.",
- examples: const ["""
-foo(var int x(int a)) {}
-main() => foo((y) => 42);
-""", """
-foo({var int x(int a)}) {}
-main() => foo((y) => 42);
-""", """
-foo([var int x(int a)]) {}
-main() => foo((y) => 42);
-"""]),
-
- MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE:
- const MessageTemplate(MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
- "Cannot instantiate type variable '#{typeVariableName}'."),
-
- MessageKind.CYCLIC_TYPE_VARIABLE:
- const MessageTemplate(MessageKind.CYCLIC_TYPE_VARIABLE,
- "Type variable '#{typeVariableName}' is a supertype of itself."),
-
- MessageKind.CYCLIC_TYPEDEF:
- const MessageTemplate(MessageKind.CYCLIC_TYPEDEF,
- "A typedef can't refer to itself.",
- howToFix: "Try removing all references to '#{typedefName}' "
- "in the definition of '#{typedefName}'.",
- examples: const ["""
-typedef F F(); // The return type 'F' is a self-reference.
-main() { F f = null; }"""]),
-
- MessageKind.CYCLIC_TYPEDEF_ONE:
- const MessageTemplate(MessageKind.CYCLIC_TYPEDEF_ONE,
- "A typedef can't refer to itself through another typedef.",
- howToFix:
- "Try removing all references to "
- "'#{otherTypedefName}' in the definition of '#{typedefName}'.",
- examples: const ["""
-typedef G F(); // The return type 'G' is a self-reference through typedef 'G'.
-typedef F G(); // The return type 'F' is a self-reference through typedef 'F'.
-main() { F f = null; }""",
-"""
-typedef G F(); // The return type 'G' creates a self-reference.
-typedef H G(); // The return type 'H' creates a self-reference.
-typedef H(F f); // The argument type 'F' creates a self-reference.
-main() { F f = null; }"""]),
-
- MessageKind.CLASS_NAME_EXPECTED:
- const MessageTemplate(MessageKind.CLASS_NAME_EXPECTED,
- "Class name expected."),
-
- MessageKind.CANNOT_EXTEND:
- const MessageTemplate(MessageKind.CANNOT_EXTEND,
- "'#{type}' cannot be extended."),
-
- MessageKind.CANNOT_IMPLEMENT:
- const MessageTemplate(MessageKind.CANNOT_IMPLEMENT,
- "'#{type}' cannot be implemented."),
-
- // TODO(johnnwinther): Split messages into reasons for malformedness.
- MessageKind.CANNOT_EXTEND_MALFORMED:
- const MessageTemplate(MessageKind.CANNOT_EXTEND_MALFORMED,
- "Class '#{className}' can't extend the type '#{malformedType}' "
- "because it is malformed.",
- howToFix:
- "Try correcting the malformed type annotation or removing the "
- "'extends' clause.",
- examples: const ["""
-class A extends Malformed {}
-main() => new A();"""]),
-
- MessageKind.CANNOT_IMPLEMENT_MALFORMED:
- const MessageTemplate(MessageKind.CANNOT_IMPLEMENT_MALFORMED,
- "Class '#{className}' can't implement the type '#{malformedType}' "
- "because it is malformed.",
- howToFix:
- "Try correcting the malformed type annotation or removing the "
- "type from the 'implements' clause.",
- examples: const ["""
-class A implements Malformed {}
-main() => new A();"""]),
-
- MessageKind.CANNOT_MIXIN_MALFORMED:
- const MessageTemplate(MessageKind.CANNOT_MIXIN_MALFORMED,
- "Class '#{className}' can't mixin the type '#{malformedType}' "
- "because it is malformed.",
- howToFix:
- "Try correcting the malformed type annotation or removing the "
- "type from the 'with' clause.",
- examples: const ["""
-class A extends Object with Malformed {}
-main() => new A();"""]),
-
- MessageKind.CANNOT_MIXIN:
- const MessageTemplate(MessageKind.CANNOT_MIXIN,
- "The type '#{type}' can't be mixed in.",
- howToFix: "Try removing '#{type}' from the 'with' clause.",
- examples: const ["""
-class C extends Object with String {}
-
-main() => new C();
-""", """
-typedef C = Object with String;
-
-main() => new C();
-"""]),
-
- MessageKind.CANNOT_EXTEND_ENUM:
- const MessageTemplate(MessageKind.CANNOT_EXTEND_ENUM,
- "Class '#{className}' can't extend the type '#{enumType}' because "
- "it is declared by an enum.",
- howToFix: "Try making '#{enumType}' a normal class or removing the "
- "'extends' clause.",
- examples: const ["""
-enum Enum { A }
-class B extends Enum {}
-main() => new B();"""]),
-
- MessageKind.CANNOT_IMPLEMENT_ENUM:
- const MessageTemplate(MessageKind.CANNOT_IMPLEMENT_ENUM,
- "Class '#{className}' can't implement the type '#{enumType}' "
- "because it is declared by an enum.",
- howToFix: "Try making '#{enumType}' a normal class or removing the "
- "type from the 'implements' clause.",
- examples: const ["""
-enum Enum { A }
-class B implements Enum {}
-main() => new B();"""]),
-
- MessageKind.CANNOT_MIXIN_ENUM:
- const MessageTemplate(MessageKind.CANNOT_MIXIN_ENUM,
- "Class '#{className}' can't mixin the type '#{enumType}' because it "
- "is declared by an enum.",
- howToFix: "Try making '#{enumType}' a normal class or removing the "
- "type from the 'with' clause.",
- examples: const ["""
-enum Enum { A }
-class B extends Object with Enum {}
-main() => new B();"""]),
-
- MessageKind.CANNOT_INSTANTIATE_ENUM:
- const MessageTemplate(MessageKind.CANNOT_INSTANTIATE_ENUM,
- "Enum type '#{enumName}' cannot be instantiated.",
- howToFix: "Try making '#{enumType}' a normal class or use an enum "
- "constant.",
- examples: const ["""
-enum Enum { A }
-main() => new Enum(0);""", """
-enum Enum { A }
-main() => const Enum(0);"""]),
-
- MessageKind.EMPTY_ENUM_DECLARATION:
- const MessageTemplate(MessageKind.EMPTY_ENUM_DECLARATION,
- "Enum '#{enumName}' must contain at least one value.",
- howToFix: "Try adding an enum constant or making #{enumName} a "
- "normal class.",
- examples: const ["""
-enum Enum {}
-main() { Enum e; }"""]),
-
- MessageKind.MISSING_ENUM_CASES:
- const MessageTemplate(MessageKind.MISSING_ENUM_CASES,
- "Missing enum constants in switch statement: #{enumValues}.",
- howToFix: "Try adding the missing constants or a default case.",
- examples: const ["""
-enum Enum { A, B }
-main() {
- switch (Enum.A) {
- case Enum.B: break;
- }
-}""", """
-enum Enum { A, B, C }
-main() {
- switch (Enum.A) {
- case Enum.B: break;
- }
-}"""]),
-
- MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS:
- const MessageTemplate(MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
- "'#{type}' can not be both extended and implemented."),
-
- MessageKind.DUPLICATE_IMPLEMENTS:
- const MessageTemplate(MessageKind.DUPLICATE_IMPLEMENTS,
- "'#{type}' must not occur more than once "
- "in the implements clause."),
-
- MessageKind.MULTI_INHERITANCE:
- const MessageTemplate(MessageKind.MULTI_INHERITANCE,
- "Dart2js does not currently support inheritance of the same class "
- "with different type arguments: Both #{firstType} and #{secondType} "
- "are supertypes of #{thisType}."),
-
- MessageKind.ILLEGAL_SUPER_SEND:
- const MessageTemplate(MessageKind.ILLEGAL_SUPER_SEND,
- "'#{name}' cannot be called on super."),
-
- MessageKind.NO_SUCH_SUPER_MEMBER:
- const MessageTemplate(MessageKind.NO_SUCH_SUPER_MEMBER,
- "Cannot resolve '#{memberName}' in a superclass of '#{className}'."),
-
- MessageKind.ADDITIONAL_TYPE_ARGUMENT:
- const MessageTemplate(MessageKind.ADDITIONAL_TYPE_ARGUMENT,
- "Additional type argument."),
-
- MessageKind.MISSING_TYPE_ARGUMENT:
- const MessageTemplate(MessageKind.MISSING_TYPE_ARGUMENT,
- "Missing type argument."),
-
- // TODO(johnniwinther): Use ADDITIONAL_TYPE_ARGUMENT or
- // MISSING_TYPE_ARGUMENT instead.
- MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH:
- const MessageTemplate(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
- "Incorrect number of type arguments on '#{type}'."),
-
- MessageKind.GETTER_MISMATCH:
- const MessageTemplate(MessageKind.GETTER_MISMATCH,
- "Setter disagrees on: '#{modifiers}'."),
-
- MessageKind.SETTER_MISMATCH:
- const MessageTemplate(MessageKind.SETTER_MISMATCH,
- "Getter disagrees on: '#{modifiers}'."),
-
- MessageKind.ILLEGAL_SETTER_FORMALS:
- const MessageTemplate(MessageKind.ILLEGAL_SETTER_FORMALS,
- "A setter must have exactly one argument."),
-
- MessageKind.NO_STATIC_OVERRIDE:
- const MessageTemplate(MessageKind.NO_STATIC_OVERRIDE,
- "Static member cannot override instance member '#{memberName}' of "
- "'#{className}'."),
-
- MessageKind.NO_STATIC_OVERRIDE_CONT:
- const MessageTemplate(MessageKind.NO_STATIC_OVERRIDE_CONT,
- "This is the instance member that cannot be overridden "
- "by a static member."),
-
- MessageKind.INSTANCE_STATIC_SAME_NAME:
- const MessageTemplate(MessageKind.INSTANCE_STATIC_SAME_NAME,
- "Instance member '#{memberName}' and static member of "
- "superclass '#{className}' have the same name."),
-
- MessageKind.INSTANCE_STATIC_SAME_NAME_CONT:
- const MessageTemplate(MessageKind.INSTANCE_STATIC_SAME_NAME_CONT,
- "This is the static member with the same name."),
-
- MessageKind.INVALID_OVERRIDE_METHOD:
- const MessageTemplate(MessageKind.INVALID_OVERRIDE_METHOD,
- "The type '#{declaredType}' of method '#{name}' declared in "
- "'#{class}' is not a subtype of the overridden method type "
- "'#{inheritedType}' inherited from '#{inheritedClass}'."),
-
- MessageKind.INVALID_OVERRIDDEN_METHOD:
- const MessageTemplate(MessageKind.INVALID_OVERRIDDEN_METHOD,
- "This is the overridden method '#{name}' declared in class "
- "'#{class}'."),
-
- MessageKind.INVALID_OVERRIDE_GETTER:
- const MessageTemplate(MessageKind.INVALID_OVERRIDE_GETTER,
- "The type '#{declaredType}' of getter '#{name}' declared in "
- "'#{class}' is not assignable to the type '#{inheritedType}' of the "
- "overridden getter inherited from '#{inheritedClass}'."),
-
- MessageKind.INVALID_OVERRIDDEN_GETTER:
- const MessageTemplate(MessageKind.INVALID_OVERRIDDEN_GETTER,
- "This is the overridden getter '#{name}' declared in class "
- "'#{class}'."),
-
- MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD:
- const MessageTemplate(MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD,
- "The type '#{declaredType}' of field '#{name}' declared in "
- "'#{class}' is not assignable to the type '#{inheritedType}' of the "
- "overridden getter inherited from '#{inheritedClass}'."),
-
- MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER:
- const MessageTemplate(MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER,
- "The type '#{declaredType}' of getter '#{name}' declared in "
- "'#{class}' is not assignable to the type '#{inheritedType}' of the "
- "overridden field inherited from '#{inheritedClass}'."),
-
- MessageKind.INVALID_OVERRIDE_SETTER:
- const MessageTemplate(MessageKind.INVALID_OVERRIDE_SETTER,
- "The type '#{declaredType}' of setter '#{name}' declared in "
- "'#{class}' is not assignable to the type '#{inheritedType}' of the "
- "overridden setter inherited from '#{inheritedClass}'."),
-
- MessageKind.INVALID_OVERRIDDEN_SETTER:
- const MessageTemplate(MessageKind.INVALID_OVERRIDDEN_SETTER,
- "This is the overridden setter '#{name}' declared in class "
- "'#{class}'."),
-
- MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD:
- const MessageTemplate(MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD,
- "The type '#{declaredType}' of field '#{name}' declared in "
- "'#{class}' is not assignable to the type '#{inheritedType}' of the "
- "overridden setter inherited from '#{inheritedClass}'."),
-
- MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER:
- const MessageTemplate(MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER,
- "The type '#{declaredType}' of setter '#{name}' declared in "
- "'#{class}' is not assignable to the type '#{inheritedType}' of the "
- "overridden field inherited from '#{inheritedClass}'."),
-
- MessageKind.INVALID_OVERRIDE_FIELD:
- const MessageTemplate(MessageKind.INVALID_OVERRIDE_FIELD,
- "The type '#{declaredType}' of field '#{name}' declared in "
- "'#{class}' is not assignable to the type '#{inheritedType}' of the "
- "overridden field inherited from '#{inheritedClass}'."),
-
- MessageKind.INVALID_OVERRIDDEN_FIELD:
- const MessageTemplate(MessageKind.INVALID_OVERRIDDEN_FIELD,
- "This is the overridden field '#{name}' declared in class "
- "'#{class}'."),
-
- MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD:
- const MessageTemplate(MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD,
- "Method '#{name}' in '#{class}' can't override field from "
- "'#{inheritedClass}'."),
-
- MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT:
- const MessageTemplate(
- MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT,
- "This is the field that cannot be overridden by a method."),
-
- MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD:
- const MessageTemplate(
- MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD,
- "Field '#{name}' in '#{class}' can't override method from "
- "'#{inheritedClass}'."),
-
- MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT:
- const MessageTemplate(
- MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT,
- "This is the method that cannot be overridden by a field."),
-
- MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD:
- const MessageTemplate(MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD,
- "Method '#{name}' in '#{class}' can't override getter from "
- "'#{inheritedClass}'."),
-
- MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT:
- const MessageTemplate(
- MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT,
- "This is the getter that cannot be overridden by a method."),
-
- MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER:
- const MessageTemplate(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER,
- "Getter '#{name}' in '#{class}' can't override method from "
- "'#{inheritedClass}'."),
-
- MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT:
- const MessageTemplate(
- MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT,
- "This is the method that cannot be overridden by a getter."),
-
- MessageKind.MISSING_FORMALS:
- const MessageTemplate(MessageKind.MISSING_FORMALS,
- "Formal parameters are missing."),
-
- MessageKind.EXTRA_FORMALS:
- const MessageTemplate(MessageKind.EXTRA_FORMALS,
- "Formal parameters are not allowed here."),
-
- MessageKind.UNARY_OPERATOR_BAD_ARITY:
- const MessageTemplate(MessageKind.UNARY_OPERATOR_BAD_ARITY,
- "Operator '#{operatorName}' must have no parameters."),
-
- MessageKind.MINUS_OPERATOR_BAD_ARITY:
- const MessageTemplate(MessageKind.MINUS_OPERATOR_BAD_ARITY,
- "Operator '-' must have 0 or 1 parameters."),
-
- MessageKind.BINARY_OPERATOR_BAD_ARITY:
- const MessageTemplate(MessageKind.BINARY_OPERATOR_BAD_ARITY,
- "Operator '#{operatorName}' must have exactly 1 parameter."),
-
- MessageKind.TERNARY_OPERATOR_BAD_ARITY:
- const MessageTemplate(MessageKind.TERNARY_OPERATOR_BAD_ARITY,
- "Operator '#{operatorName}' must have exactly 2 parameters."),
-
- MessageKind.OPERATOR_OPTIONAL_PARAMETERS:
- const MessageTemplate(MessageKind.OPERATOR_OPTIONAL_PARAMETERS,
- "Operator '#{operatorName}' cannot have optional parameters."),
-
- MessageKind.OPERATOR_NAMED_PARAMETERS:
- const MessageTemplate(MessageKind.OPERATOR_NAMED_PARAMETERS,
- "Operator '#{operatorName}' cannot have named parameters."),
-
- MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE:
- const MessageTemplate(MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE,
- "Cannot have return type for constructor."),
-
- MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR:
- const MessageTemplate(MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR,
- "Constructors can't return values.",
- howToFix: "Remove the return statement or use a factory constructor.",
- examples: const ["""
-class C {
- C() {
- return 1;
- }
-}
-
-main() => new C();"""]),
-
- MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER:
- const MessageTemplate(MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER,
- "Cannot have final modifier on method."),
-
- MessageKind.ILLEGAL_CONST_FIELD_MODIFIER:
- const MessageTemplate(MessageKind.ILLEGAL_CONST_FIELD_MODIFIER,
- "Cannot have const modifier on non-static field.",
- howToFix:
- "Try adding a static modifier, or removing the const modifier.",
- examples: const ["""
-class C {
- const int a = 1;
-}
-
-main() => new C();"""]),
-
- MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS:
- const MessageTemplate(MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS,
- "Illegal constructor modifiers: '#{modifiers}'."),
-
- MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS:
- const MessageTemplate(MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS,
- "Illegal mixin application modifiers: '#{modifiers}'."),
-
- MessageKind.ILLEGAL_MIXIN_SUPERCLASS:
- const MessageTemplate(MessageKind.ILLEGAL_MIXIN_SUPERCLASS,
- "Class used as mixin must have Object as superclass."),
-
- MessageKind.ILLEGAL_MIXIN_OBJECT:
- const MessageTemplate(MessageKind.ILLEGAL_MIXIN_OBJECT,
- "Cannot use Object as mixin."),
-
- MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR:
- const MessageTemplate(MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR,
- "Class used as mixin cannot have non-factory constructor."),
-
- MessageKind.ILLEGAL_MIXIN_CYCLE:
- const MessageTemplate(MessageKind.ILLEGAL_MIXIN_CYCLE,
- "Class used as mixin introduces mixin cycle: "
- "'#{mixinName1}' <-> '#{mixinName2}'."),
-
- MessageKind.ILLEGAL_MIXIN_WITH_SUPER:
- const MessageTemplate(MessageKind.ILLEGAL_MIXIN_WITH_SUPER,
- "Cannot use class '#{className}' as a mixin because it uses "
- "'super'."),
-
- MessageKind.ILLEGAL_MIXIN_SUPER_USE:
- const MessageTemplate(MessageKind.ILLEGAL_MIXIN_SUPER_USE,
- "Use of 'super' in class used as mixin."),
-
- MessageKind.PARAMETER_NAME_EXPECTED:
- const MessageTemplate(MessageKind.PARAMETER_NAME_EXPECTED,
- "parameter name expected."),
-
- MessageKind.CANNOT_RESOLVE_GETTER:
- const MessageTemplate(MessageKind.CANNOT_RESOLVE_GETTER,
- "Cannot resolve getter."),
-
- MessageKind.CANNOT_RESOLVE_SETTER:
- const MessageTemplate(MessageKind.CANNOT_RESOLVE_SETTER,
- "Cannot resolve setter."),
-
- MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER:
- const MessageTemplate(MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER,
- "Cannot assign a value to final field '#{name}' "
- "in superclass '#{superclassName}'."),
-
- MessageKind.ASSIGNING_METHOD:
- const MessageTemplate(MessageKind.ASSIGNING_METHOD,
- "Cannot assign a value to a method."),
-
- MessageKind.ASSIGNING_METHOD_IN_SUPER:
- const MessageTemplate(MessageKind.ASSIGNING_METHOD_IN_SUPER,
- "Cannot assign a value to method '#{name}' "
- "in superclass '#{superclassName}'."),
-
- MessageKind.ASSIGNING_TYPE:
- const MessageTemplate(MessageKind.ASSIGNING_TYPE,
- "Cannot assign a value to a type."),
-
- MessageKind.IF_NULL_ASSIGNING_TYPE:
- const MessageTemplate(MessageKind.IF_NULL_ASSIGNING_TYPE,
- "Cannot assign a value to a type. Note that types are never null, "
- "so this ??= assignment has no effect.",
- howToFix: "Try removing the '??=' assignment.",
- examples: const [
- "class A {} main() { print(A ??= 3);}",
- ]),
-
- MessageKind.VOID_NOT_ALLOWED:
- const MessageTemplate(MessageKind.VOID_NOT_ALLOWED,
- "Type 'void' can't be used here because it isn't a return type.",
- howToFix:
- "Try removing 'void' keyword or replace it with 'var', 'final', "
- "or a type.",
- examples: const [
- "void x; main() {}",
- "foo(void x) {} main() { foo(null); }",
- ]),
-
- MessageKind.NULL_NOT_ALLOWED:
- const MessageTemplate(MessageKind.NULL_NOT_ALLOWED,
- "`null` can't be used here."),
-
- MessageKind.BEFORE_TOP_LEVEL:
- const MessageTemplate(MessageKind.BEFORE_TOP_LEVEL,
- "Part header must come before top-level definitions."),
-
- MessageKind.IMPORT_PART_OF:
- const MessageTemplate(MessageKind.IMPORT_PART_OF,
- "The imported library must not have a 'part-of' directive.",
- howToFix: "Try removing the 'part-of' directive or replacing the "
- "import of the library with a 'part' directive.",
- examples: const [const {
-'main.dart': """
-library library;
-
-import 'part.dart';
-
-main() {}
-""",
-
-'part.dart': """
-part of library;
-"""}]),
-
- MessageKind.LIBRARY_NAME_MISMATCH:
- const MessageTemplate(MessageKind.LIBRARY_NAME_MISMATCH,
- "Expected part of library name '#{libraryName}'.",
- howToFix: "Try changing the directive to 'part of #{libraryName};'.",
- examples: const [const {
-'main.dart': """
-library lib.foo;
-
-part 'part.dart';
-
-main() {}
-""",
-
-'part.dart': """
-part of lib.bar;
-"""}]),
-
- MessageKind.MISSING_LIBRARY_NAME:
- const MessageTemplate(MessageKind.MISSING_LIBRARY_NAME,
- "Library has no name. Part directive expected library name "
- "to be '#{libraryName}'.",
- howToFix: "Try adding 'library #{libraryName};' to the library.",
- examples: const [const {
-'main.dart': """
-part 'part.dart';
-
-main() {}
-""",
-
-'part.dart': """
-part of lib.foo;
-"""}]),
-
- MessageKind.THIS_IS_THE_PART_OF_TAG:
- const MessageTemplate(MessageKind.THIS_IS_THE_PART_OF_TAG,
- "This is the part of directive."),
-
- MessageKind.MISSING_PART_OF_TAG:
- const MessageTemplate(MessageKind.MISSING_PART_OF_TAG,
- "This file has no part-of tag, but it is being used as a part."),
-
- MessageKind.DUPLICATED_PART_OF:
- const MessageTemplate(MessageKind.DUPLICATED_PART_OF,
- "Duplicated part-of directive."),
-
- MessageKind.DUPLICATED_LIBRARY_NAME:
- const MessageTemplate(MessageKind.DUPLICATED_LIBRARY_NAME,
- "Duplicated library name '#{libraryName}'."),
-
- MessageKind.DUPLICATED_RESOURCE:
- const MessageTemplate(MessageKind.DUPLICATED_RESOURCE,
- "The resource '#{resourceUri}' is loaded through both "
- "'#{canonicalUri1}' and '#{canonicalUri2}'."),
-
- MessageKind.DUPLICATED_LIBRARY_RESOURCE:
- const MessageTemplate(MessageKind.DUPLICATED_LIBRARY_RESOURCE,
- "The library '#{libraryName}' in '#{resourceUri}' is loaded through "
- "both '#{canonicalUri1}' and '#{canonicalUri2}'."),
-
- // This is used as an exception.
- MessageKind.INVALID_SOURCE_FILE_LOCATION:
- const MessageTemplate(MessageKind.INVALID_SOURCE_FILE_LOCATION, '''
-Invalid offset (#{offset}) in source map.
-File: #{fileName}
-Length: #{length}'''),
-
- MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC:
- const MessageTemplate(MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC,
- "Top-level variable cannot be declared static."),
-
- MessageKind.REFERENCE_IN_INITIALIZATION:
- const MessageTemplate(MessageKind.REFERENCE_IN_INITIALIZATION,
- "Variable '#{variableName}' is referenced during its "
- "initialization.",
- howToFix:
- "If you are trying to reference a shadowed variable, rename "
- "one of the variables.",
- examples: const ["""
-foo(t) {
- var t = t;
- return t;
-}
-
-main() => foo(1);
-"""]),
-
- MessageKind.CONST_WITHOUT_INITIALIZER:
- const MessageTemplate(MessageKind.CONST_WITHOUT_INITIALIZER,
- "A constant variable must be initialized.",
- howToFix: "Try adding an initializer or "
- "removing the 'const' modifier.",
- examples: const ["""
-void main() {
- const c; // This constant variable must be initialized.
-}"""]),
-
- MessageKind.FINAL_WITHOUT_INITIALIZER:
- const MessageTemplate(MessageKind.FINAL_WITHOUT_INITIALIZER,
- "A final variable must be initialized.",
- howToFix: "Try adding an initializer or "
- "removing the 'final' modifier.",
- examples: const [
- "class C { static final field; } main() => C.field;"]),
-
- MessageKind.MEMBER_USES_CLASS_NAME:
- const MessageTemplate(MessageKind.MEMBER_USES_CLASS_NAME,
- "Member variable can't have the same name as the class it is "
- "declared in.",
- howToFix: "Try renaming the variable.",
- examples: const ["""
-class A { var A; }
-main() {
- var a = new A();
- a.A = 1;
-}
-""", """
-class A { static var A; }
-main() => A.A = 1;
-"""]),
-
- MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT:
- const MessageTemplate(
- MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT,
- "Wrong number of arguments to assert. Should be 1, but given "
- "#{argumentCount}."),
-
- MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS:
- const MessageTemplate(MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS,
- "'assert' takes no named arguments, but given #{argumentCount}."),
-
- MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY:
- const MessageTemplate(MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY,
- "Factory redirection only allowed in factories."),
-
- MessageKind.MISSING_FACTORY_KEYWORD:
- const MessageTemplate(MessageKind.MISSING_FACTORY_KEYWORD,
- "Did you forget a factory keyword here?"),
-
- MessageKind.NO_SUCH_METHOD_IN_NATIVE:
- const MessageTemplate(MessageKind.NO_SUCH_METHOD_IN_NATIVE,
- "'NoSuchMethod' is not supported for classes that extend native "
- "classes."),
-
- MessageKind.DEFERRED_LIBRARY_DART_2_DART:
- const MessageTemplate(MessageKind.DEFERRED_LIBRARY_DART_2_DART,
- "Deferred loading is not supported by the dart backend yet. "
- "The output will not be split."),
-
- MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX:
- const MessageTemplate(MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX,
- "This import is deferred but there is no prefix keyword.",
- howToFix: "Try adding a prefix to the import."),
-
- MessageKind.DEFERRED_OLD_SYNTAX:
- const MessageTemplate(MessageKind.DEFERRED_OLD_SYNTAX,
- "The DeferredLibrary annotation is obsolete.",
- howToFix:
- "Use the \"import 'lib.dart' deferred as prefix\" syntax instead."),
-
- MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX:
- const MessageTemplate(MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX,
- "The prefix of this deferred import is not unique.",
- howToFix: "Try changing the import prefix."),
-
- MessageKind.DEFERRED_TYPE_ANNOTATION:
- const MessageTemplate(MessageKind.DEFERRED_TYPE_ANNOTATION,
- "The type #{node} is deferred. "
- "Deferred types are not valid as type annotations.",
- howToFix:
- "Try using a non-deferred abstract class as an interface."),
-
- MessageKind.ILLEGAL_STATIC:
- const MessageTemplate(MessageKind.ILLEGAL_STATIC,
- "Modifier static is only allowed on functions declared in "
- "a class."),
-
- MessageKind.STATIC_FUNCTION_BLOAT:
- const MessageTemplate(MessageKind.STATIC_FUNCTION_BLOAT,
- "Using '#{class}.#{name}' may lead to unnecessarily large "
- "generated code.",
- howToFix:
- "Try adding '@MirrorsUsed(...)' as described at "
- "https://goo.gl/Akrrog."),
-
- MessageKind.NON_CONST_BLOAT:
- const MessageTemplate(MessageKind.NON_CONST_BLOAT,
- "Using 'new #{name}' may lead to unnecessarily large generated "
- "code.",
- howToFix:
- "Try using 'const #{name}' or adding '@MirrorsUsed(...)' as "
- "described at https://goo.gl/Akrrog."),
-
- MessageKind.STRING_EXPECTED:
- const MessageTemplate(MessageKind.STRING_EXPECTED,
- "Expected a 'String', but got an instance of '#{type}'."),
-
- MessageKind.PRIVATE_IDENTIFIER:
- const MessageTemplate(MessageKind.PRIVATE_IDENTIFIER,
- "'#{value}' is not a valid Symbol name because it starts with "
- "'_'."),
-
- MessageKind.PRIVATE_NAMED_PARAMETER:
- const MessageTemplate(MessageKind.PRIVATE_NAMED_PARAMETER,
- "Named optional parameter can't have a library private name.",
- howToFix:
- "Try removing the '_' or making the parameter positional or "
- "required.",
- examples: const ["""foo({int _p}) {} main() => foo();"""]),
-
- MessageKind.UNSUPPORTED_LITERAL_SYMBOL:
- const MessageTemplate(MessageKind.UNSUPPORTED_LITERAL_SYMBOL,
- "Symbol literal '##{value}' is currently unsupported by dart2js."),
-
- MessageKind.INVALID_SYMBOL:
- const MessageTemplate(MessageKind.INVALID_SYMBOL, '''
-'#{value}' is not a valid Symbol name because is not:
- * an empty String,
- * a user defined operator,
- * a qualified non-private identifier optionally followed by '=', or
- * a qualified non-private identifier followed by '.' and a user-defined '''
-"operator."),
-
- MessageKind.AMBIGUOUS_REEXPORT:
- const MessageTemplate(MessageKind.AMBIGUOUS_REEXPORT,
- "'#{name}' is (re)exported by multiple libraries."),
-
- MessageKind.AMBIGUOUS_LOCATION:
- const MessageTemplate(MessageKind.AMBIGUOUS_LOCATION,
- "'#{name}' is defined here."),
-
- MessageKind.IMPORTED_HERE:
- const MessageTemplate(MessageKind.IMPORTED_HERE,
- "'#{name}' is imported here."),
-
- MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE:
- const MessageTemplate(MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE,
- "The class '#{class}' overrides 'operator==', "
- "but not 'get hashCode'."),
-
- MessageKind.INTERNAL_LIBRARY_FROM:
- const MessageTemplate(MessageKind.INTERNAL_LIBRARY_FROM,
- "Internal library '#{resolvedUri}' is not accessible from "
- "'#{importingUri}'."),
-
- MessageKind.INTERNAL_LIBRARY:
- const MessageTemplate(MessageKind.INTERNAL_LIBRARY,
- "Internal library '#{resolvedUri}' is not accessible."),
-
- MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS:
- const MessageTemplate(
- MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS,
- "Js-interop class '#{cls}' cannot extend from the non js-interop "
- "class '#{superclass}'.",
- howToFix: "Annotate the superclass with @JS.",
- examples: const [
- """
- import 'package:js/js.dart';
-
- class Foo { }
-
- @JS()
- class Bar extends Foo { }
-
- main() {
- new Bar();
- }
- """]),
-
- MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER:
- const MessageTemplate(
- MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER,
- "Member '#{member}' in js-interop class '#{cls}' is not external.",
- howToFix: "Mark all interop methods external",
- examples: const [
- """
- import 'package:js/js.dart';
-
- @JS()
- class Foo {
- bar() {}
- }
-
- main() {
- new Foo().bar();
- }
- """]),
-
- MessageKind.JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS:
- const MessageTemplate(
- MessageKind.JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS,
- "Js-interop method '#{method}' has named arguments but is not "
- "a factory constructor of an @anonymous @JS class.",
- howToFix: "Remove all named arguments from js-interop method or "
- "in the case of a factory constructor annotate the class "
- "as @anonymous.",
- examples: const [
- """
- import 'package:js/js.dart';
-
- @JS()
- class Foo {
- external bar(foo, {baz});
- }
-
- main() {
- new Foo().bar(4, baz: 5);
- }
- """]),
-
- MessageKind.JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS:
- const MessageTemplate(
- MessageKind.JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS,
- "Parameter '#{parameter}' in anonymous js-interop class '#{cls}' "
- "object literal constructor is positional instead of named."
- ".",
- howToFix: "Make all arguments in external factory object literal "
- "constructors named.",
- examples: const [
- """
- import 'package:js/js.dart';
-
- @anonymous
- @JS()
- class Foo {
- external factory Foo(foo, {baz});
- }
-
- main() {
- new Foo(5, baz: 5);
- }
- """]),
-
- MessageKind.LIBRARY_NOT_FOUND:
- const MessageTemplate(MessageKind.LIBRARY_NOT_FOUND,
- "Library not found '#{resolvedUri}'."),
-
- MessageKind.LIBRARY_NOT_SUPPORTED:
- const MessageTemplate(MessageKind.LIBRARY_NOT_SUPPORTED,
- "Library not supported '#{resolvedUri}'.",
- howToFix: "Try removing the dependency or enabling support using "
- "the '--categories' option.",
- examples: const [/*
- """
- import 'dart:io';
- main() {}
- """
- */]),
- // TODO(johnniwinther): Enable example when message_kind_test.dart
- // supports library loader callbacks.
-
- MessageKind.UNSUPPORTED_EQ_EQ_EQ:
- const MessageTemplate(MessageKind.UNSUPPORTED_EQ_EQ_EQ,
- "'===' is not an operator. "
- "Did you mean '#{lhs} == #{rhs}' or 'identical(#{lhs}, #{rhs})'?"),
-
- MessageKind.UNSUPPORTED_BANG_EQ_EQ:
- const MessageTemplate(MessageKind.UNSUPPORTED_BANG_EQ_EQ,
- "'!==' is not an operator. "
- "Did you mean '#{lhs} != #{rhs}' or '!identical(#{lhs}, #{rhs})'?"),
-
- MessageKind.UNSUPPORTED_PREFIX_PLUS:
- const MessageTemplate(MessageKind.UNSUPPORTED_PREFIX_PLUS,
- "'+' is not a prefix operator. ",
- howToFix: "Try removing '+'.",
- examples: const [
- "main() => +2; // No longer a valid way to write '2'"
- ]),
-
- MessageKind.UNSUPPORTED_THROW_WITHOUT_EXP:
- const MessageTemplate(MessageKind.UNSUPPORTED_THROW_WITHOUT_EXP,
- "No expression after 'throw'. "
- "Did you mean 'rethrow'?"),
-
- MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX:
- const MessageTemplate(MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX,
- "'typedef' not allowed here. ",
- howToFix: "Try replacing 'typedef' with 'class'.",
- examples: const [
- """
-class B { }
-class M1 { }
-typedef C = B with M1; // Need to replace 'typedef' with 'class'.
-main() { new C(); }
-"""]),
-
- MessageKind.MIRRORS_EXPECTED_STRING:
- const MessageTemplate(MessageKind.MIRRORS_EXPECTED_STRING,
- "Can't use '#{name}' here because it's an instance of '#{type}' "
- "and a 'String' value is expected.",
- howToFix: "Did you forget to add quotes?",
- examples: const [
- """
-// 'Foo' is a type literal, not a string.
-@MirrorsUsed(symbols: const [Foo])
-import 'dart:mirrors';
-
-class Foo {}
-
-main() {}
-"""]),
-
- MessageKind.MIRRORS_EXPECTED_STRING_OR_TYPE:
- const MessageTemplate(MessageKind.MIRRORS_EXPECTED_STRING_OR_TYPE,
- "Can't use '#{name}' here because it's an instance of '#{type}' "
- "and a 'String' or 'Type' value is expected.",
- howToFix: "Did you forget to add quotes?",
- examples: const [
- """
-// 'main' is a method, not a class.
-@MirrorsUsed(targets: const [main])
-import 'dart:mirrors';
-
-main() {}
-"""]),
-
- MessageKind.MIRRORS_EXPECTED_STRING_OR_LIST:
- const MessageTemplate(MessageKind.MIRRORS_EXPECTED_STRING_OR_LIST,
- "Can't use '#{name}' here because it's an instance of '#{type}' "
- "and a 'String' or 'List' value is expected.",
- howToFix: "Did you forget to add quotes?",
- examples: const [
- """
-// 'Foo' is not a string.
-@MirrorsUsed(symbols: Foo)
-import 'dart:mirrors';
-
-class Foo {}
-
-main() {}
-"""]),
-
- MessageKind.MIRRORS_EXPECTED_STRING_TYPE_OR_LIST:
- const MessageTemplate(MessageKind.MIRRORS_EXPECTED_STRING_TYPE_OR_LIST,
- "Can't use '#{name}' here because it's an instance of '#{type}' "
- "but a 'String', 'Type', or 'List' value is expected.",
- howToFix: "Did you forget to add quotes?",
- examples: const [
- """
-// '1' is not a string.
-@MirrorsUsed(targets: 1)
-import 'dart:mirrors';
-
-main() {}
-"""]),
-
- MessageKind.MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY:
- const MessageTemplate(
- MessageKind.MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY,
- "Can't find '#{name}' in the current library.",
- // TODO(ahe): The closest identifiers in edit distance would be nice.
- howToFix: "Did you forget to add an import?",
- examples: const [
- """
-// 'window' is not in scope because dart:html isn't imported.
-@MirrorsUsed(targets: 'window')
-import 'dart:mirrors';
-
-main() {}
-"""]),
-
- MessageKind.MIRRORS_CANNOT_RESOLVE_IN_LIBRARY:
- const MessageTemplate(MessageKind.MIRRORS_CANNOT_RESOLVE_IN_LIBRARY,
- "Can't find '#{name}' in the library '#{library}'.",
- // TODO(ahe): The closest identifiers in edit distance would be nice.
- howToFix: "Is '#{name}' spelled right?",
- examples: const [
- """
-// 'List' is misspelled.
-@MirrorsUsed(targets: 'dart.core.Lsit')
-import 'dart:mirrors';
-
-main() {}
-"""]),
-
- MessageKind.MIRRORS_CANNOT_FIND_IN_ELEMENT:
- const MessageTemplate(MessageKind.MIRRORS_CANNOT_FIND_IN_ELEMENT,
- "Can't find '#{name}' in '#{element}'.",
- // TODO(ahe): The closest identifiers in edit distance would be nice.
- howToFix: "Is '#{name}' spelled right?",
- examples: const [
- """
-// 'addAll' is misspelled.
-@MirrorsUsed(targets: 'dart.core.List.addAl')
-import 'dart:mirrors';
-
-main() {}
-"""]),
-
- MessageKind.INVALID_URI:
- const MessageTemplate(MessageKind.INVALID_URI,
- "'#{uri}' is not a valid URI.",
- howToFix: DONT_KNOW_HOW_TO_FIX,
- examples: const [
- """
-// can't have a '[' in a URI
-import '../../Udyn[mic ils/expect.dart';
-
-main() {}
-"""]),
-
- MessageKind.INVALID_PACKAGE_CONFIG:
- const MessageTemplate(MessageKind.INVALID_PACKAGE_CONFIG,
- """Package config file '#{uri}' is invalid.
-#{exception}""",
- howToFix: DONT_KNOW_HOW_TO_FIX
- ),
-
- MessageKind.INVALID_PACKAGE_URI:
- const MessageTemplate(MessageKind.INVALID_PACKAGE_URI,
- "'#{uri}' is not a valid package URI (#{exception}).",
- howToFix: DONT_KNOW_HOW_TO_FIX,
- examples: const [
- """
-// can't have a 'top level' package URI
-import 'package:foo.dart';
-
-main() {}
-""", """
-// can't have 2 slashes
-import 'package://foo/foo.dart';
-
-main() {}
-""", """
-// package name must be valid
-import 'package:not\valid/foo.dart';
-
-main() {}
-"""]),
-
- MessageKind.READ_SCRIPT_ERROR:
- const MessageTemplate(MessageKind.READ_SCRIPT_ERROR,
- "Can't read '#{uri}' (#{exception}).",
- // Don't know how to fix since the underlying error is unknown.
- howToFix: DONT_KNOW_HOW_TO_FIX,
- examples: const [
- """
-// 'foo.dart' does not exist.
-import 'foo.dart';
-
-main() {}
-"""]),
-
- MessageKind.READ_SELF_ERROR:
- const MessageTemplate(MessageKind.READ_SELF_ERROR,
- "#{exception}",
- // Don't know how to fix since the underlying error is unknown.
- howToFix: DONT_KNOW_HOW_TO_FIX),
-
- MessageKind.EXTRANEOUS_MODIFIER:
- const MessageTemplate(MessageKind.EXTRANEOUS_MODIFIER,
- "Can't have modifier '#{modifier}' here.",
- howToFix: "Try removing '#{modifier}'.",
- examples: const [
- "var String foo; main(){}",
- // "var get foo; main(){}",
- "var set foo; main(){}",
- "var final foo; main(){}",
- "var var foo; main(){}",
- "var const foo; main(){}",
- "var abstract foo; main(){}",
- "var static foo; main(){}",
- "var external foo; main(){}",
- "get var foo; main(){}",
- "set var foo; main(){}",
- "final var foo; main(){}",
- "var var foo; main(){}",
- "const var foo; main(){}",
- "abstract var foo; main(){}",
- "static var foo; main(){}",
- "external var foo; main(){}"]),
-
- MessageKind.EXTRANEOUS_MODIFIER_REPLACE:
- const MessageTemplate(MessageKind.EXTRANEOUS_MODIFIER_REPLACE,
- "Can't have modifier '#{modifier}' here.",
- howToFix:
- "Try replacing modifier '#{modifier}' with 'var', 'final', "
- "or a type.",
- examples: const [
- // "get foo; main(){}",
- "set foo; main(){}",
- "abstract foo; main(){}",
- "static foo; main(){}",
- "external foo; main(){}"]),
-
- MessageKind.ABSTRACT_CLASS_INSTANTIATION:
- const MessageTemplate(MessageKind.ABSTRACT_CLASS_INSTANTIATION,
- "Can't instantiate abstract class.",
- howToFix: DONT_KNOW_HOW_TO_FIX,
- examples: const ["abstract class A {} main() { new A(); }"]),
-
- MessageKind.BODY_EXPECTED:
- const MessageTemplate(MessageKind.BODY_EXPECTED,
- "Expected a function body or '=>'.",
- // TODO(ahe): In some scenarios, we can suggest removing the 'static'
- // keyword.
- howToFix: "Try adding {}.",
- examples: const [
- "main();"]),
-
- MessageKind.MIRROR_BLOAT:
- const MessageTemplate(MessageKind.MIRROR_BLOAT,
- "#{count} methods retained for use by dart:mirrors out of #{total}"
- " total methods (#{percentage}%)."),
-
- MessageKind.MIRROR_IMPORT:
- const MessageTemplate(MessageKind.MIRROR_IMPORT,
- "Import of 'dart:mirrors'."),
-
- MessageKind.MIRROR_IMPORT_NO_USAGE:
- const MessageTemplate(MessageKind.MIRROR_IMPORT_NO_USAGE,
- "This import is not annotated with @MirrorsUsed, which may lead to "
- "unnecessarily large generated code.",
- howToFix:
- "Try adding '@MirrorsUsed(...)' as described at "
- "https://goo.gl/Akrrog."),
-
- MessageKind.JS_PLACEHOLDER_CAPTURE:
- const MessageTemplate(
- MessageKind.JS_PLACEHOLDER_CAPTURE,
- "JS code must not use '#' placeholders inside functions.",
- howToFix:
- "Use an immediately called JavaScript function to capture the"
- " the placeholder values as JavaScript function parameters."),
-
- MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT:
- const MessageTemplate(
- MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT,
- "Argument for 'JS_INTERCEPTOR_CONSTANT' must be a type constant."),
-
- MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD:
- const MessageTemplate(MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD,
- "'#{keyword}' is a reserved word and can't be used here.",
- howToFix: "Try using a different name.",
- examples: const ["do() {} main() {}"]),
-
- MessageKind. NAMED_FUNCTION_EXPRESSION:
- const MessageTemplate(MessageKind.NAMED_FUNCTION_EXPRESSION,
- "Function expression '#{name}' cannot be named.",
- howToFix: "Try removing the name.",
- examples: const ["main() { var f = func() {}; }"]),
-
- MessageKind.UNUSED_METHOD:
- const MessageTemplate(MessageKind.UNUSED_METHOD,
- "The method '#{name}' is never called.",
- howToFix: "Consider deleting it.",
- examples: const ["deadCode() {} main() {}"]),
-
- MessageKind.UNUSED_CLASS:
- const MessageTemplate(MessageKind.UNUSED_CLASS,
- "The class '#{name}' is never used.",
- howToFix: "Consider deleting it.",
- examples: const ["class DeadCode {} main() {}"]),
-
- MessageKind.UNUSED_TYPEDEF:
- const MessageTemplate(MessageKind.UNUSED_TYPEDEF,
- "The typedef '#{name}' is never used.",
- howToFix: "Consider deleting it.",
- examples: const ["typedef DeadCode(); main() {}"]),
-
- MessageKind.ABSTRACT_METHOD:
- const MessageTemplate(MessageKind.ABSTRACT_METHOD,
- "The method '#{name}' has no implementation in "
- "class '#{class}'.",
- howToFix: "Try adding a body to '#{name}' or declaring "
- "'#{class}' to be 'abstract'.",
- examples: const ["""
-class Class {
- method();
-}
-main() => new Class().method();
-"""]),
-
- MessageKind.ABSTRACT_GETTER:
- const MessageTemplate(MessageKind.ABSTRACT_GETTER,
- "The getter '#{name}' has no implementation in "
- "class '#{class}'.",
- howToFix: "Try adding a body to '#{name}' or declaring "
- "'#{class}' to be 'abstract'.",
- examples: const ["""
-class Class {
- get getter;
-}
-main() => new Class();
-"""]),
-
- MessageKind.ABSTRACT_SETTER:
- const MessageTemplate(MessageKind.ABSTRACT_SETTER,
- "The setter '#{name}' has no implementation in "
- "class '#{class}'.",
- howToFix: "Try adding a body to '#{name}' or declaring "
- "'#{class}' to be 'abstract'.",
- examples: const ["""
-class Class {
- set setter(_);
-}
-main() => new Class();
-"""]),
-
- MessageKind.INHERIT_GETTER_AND_METHOD:
- const MessageTemplate(MessageKind.INHERIT_GETTER_AND_METHOD,
- "The class '#{class}' can't inherit both getters and methods "
- "by the named '#{name}'.",
- howToFix: DONT_KNOW_HOW_TO_FIX,
- examples: const ["""
-class A {
- get member => null;
-}
-class B {
- member() {}
-}
-class Class implements A, B {
-}
-main() => new Class();
-"""]),
-
- MessageKind.INHERITED_METHOD:
- const MessageTemplate(MessageKind.INHERITED_METHOD,
- "The inherited method '#{name}' is declared here in class "
- "'#{class}'."),
-
- MessageKind.INHERITED_EXPLICIT_GETTER:
- const MessageTemplate(MessageKind.INHERITED_EXPLICIT_GETTER,
- "The inherited getter '#{name}' is declared here in class "
- "'#{class}'."),
-
- MessageKind.INHERITED_IMPLICIT_GETTER:
- const MessageTemplate(MessageKind.INHERITED_IMPLICIT_GETTER,
- "The inherited getter '#{name}' is implicitly declared by this "
- "field in class '#{class}'."),
-
- MessageKind.UNIMPLEMENTED_METHOD_ONE:
- const MessageTemplate(MessageKind.UNIMPLEMENTED_METHOD_ONE,
- "'#{class}' doesn't implement '#{method}' "
- "declared in '#{declarer}'.",
- howToFix: "Try adding an implementation of '#{name}' or declaring "
- "'#{class}' to be 'abstract'.",
- examples: const ["""
-abstract class I {
- m();
-}
-class C implements I {}
-main() => new C();
-""", """
-abstract class I {
- m();
-}
-class C extends I {}
-main() => new C();
-"""]),
-
- MessageKind.UNIMPLEMENTED_METHOD:
- const MessageTemplate(MessageKind.UNIMPLEMENTED_METHOD,
- "'#{class}' doesn't implement '#{method}'.",
- howToFix: "Try adding an implementation of '#{name}' or declaring "
- "'#{class}' to be 'abstract'.",
- examples: const ["""
-abstract class I {
- m();
-}
-
-abstract class J {
- m();
-}
-
-class C implements I, J {}
-
-main() {
- new C();
-}
-""", """
-abstract class I {
- m();
-}
-
-abstract class J {
- m();
-}
-
-class C extends I implements J {}
-
-main() {
- new C();
-}
-"""]),
-
- MessageKind.UNIMPLEMENTED_METHOD_CONT:
- const MessageTemplate(MessageKind.UNIMPLEMENTED_METHOD_CONT,
- "The method '#{name}' is declared here in class '#{class}'."),
-
- MessageKind.UNIMPLEMENTED_SETTER_ONE:
- const MessageTemplate(MessageKind.UNIMPLEMENTED_SETTER_ONE,
- "'#{class}' doesn't implement the setter '#{name}' "
- "declared in '#{declarer}'.",
- howToFix: "Try adding an implementation of '#{name}' or declaring "
- "'#{class}' to be 'abstract'.",
- examples: const ["""
-abstract class I {
- set m(_);
-}
-class C implements I {}
-class D implements I {
- set m(_) {}
-}
-main() {
- new D().m = 0;
- new C();
-}
-"""]),
-
- MessageKind.UNIMPLEMENTED_SETTER:
- const MessageTemplate(MessageKind.UNIMPLEMENTED_SETTER,
- "'#{class}' doesn't implement the setter '#{name}'.",
- howToFix: "Try adding an implementation of '#{name}' or declaring "
- "'#{class}' to be 'abstract'.",
- examples: const ["""
-abstract class I {
- set m(_);
-}
-abstract class J {
- set m(_);
-}
-class C implements I, J {}
-main() => new C();
-""", """
-abstract class I {
- set m(_);
-}
-abstract class J {
- set m(_);
-}
-class C extends I implements J {}
-main() => new C();
-"""]),
-
- MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER:
- const MessageTemplate(MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,
- "The setter '#{name}' is declared here in class '#{class}'."),
-
- MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER:
- const MessageTemplate(MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER,
- "The setter '#{name}' is implicitly declared by this field "
- "in class '#{class}'."),
-
- MessageKind.UNIMPLEMENTED_GETTER_ONE:
- const MessageTemplate(MessageKind.UNIMPLEMENTED_GETTER_ONE,
- "'#{class}' doesn't implement the getter '#{name}' "
- "declared in '#{declarer}'.",
- howToFix: "Try adding an implementation of '#{name}' or declaring "
- "'#{class}' to be 'abstract'.",
- examples: const ["""
-abstract class I {
- get m;
-}
-class C implements I {}
-main() => new C();
-""", """
-abstract class I {
- get m;
-}
-class C extends I {}
-main() => new C();
-"""]),
-
- MessageKind.UNIMPLEMENTED_GETTER:
- const MessageTemplate(MessageKind.UNIMPLEMENTED_GETTER,
- "'#{class}' doesn't implement the getter '#{name}'.",
- howToFix: "Try adding an implementation of '#{name}' or declaring "
- "'#{class}' to be 'abstract'.",
- examples: const ["""
-abstract class I {
- get m;
-}
-abstract class J {
- get m;
-}
-class C implements I, J {}
-main() => new C();
-""", """
-abstract class I {
- get m;
-}
-abstract class J {
- get m;
-}
-class C extends I implements J {}
-main() => new C();
-"""]),
-
- MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER:
- const MessageTemplate(MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,
- "The getter '#{name}' is declared here in class '#{class}'."),
-
- MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER:
- const MessageTemplate(MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,
- "The getter '#{name}' is implicitly declared by this field "
- "in class '#{class}'."),
-
- MessageKind.EQUAL_MAP_ENTRY_KEY:
- const MessageTemplate(MessageKind.EQUAL_MAP_ENTRY_KEY,
- "An entry with the same key already exists in the map.",
- howToFix:
- "Try removing the previous entry or changing the key in one "
- "of the entries.",
- examples: const ["""
-main() {
- var m = const {'foo': 1, 'foo': 2};
-}"""]),
-
- MessageKind.BAD_INPUT_CHARACTER:
- const MessageTemplate(MessageKind.BAD_INPUT_CHARACTER,
- "Character U+#{characterHex} isn't allowed here.",
- howToFix: DONT_KNOW_HOW_TO_FIX,
- examples: const ["""
-main() {
- String x = ç;
-}
-"""]),
-
- MessageKind.UNTERMINATED_STRING:
- const MessageTemplate(MessageKind.UNTERMINATED_STRING,
- "String must end with #{quote}.",
- howToFix: DONT_KNOW_HOW_TO_FIX,
- examples: const ["""
-main() {
- return '
-;
-}
-""",
-"""
-main() {
- return \"
-;
-}
-""",
-"""
-main() {
- return r'
-;
-}
-""",
-"""
-main() {
- return r\"
-;
-}
-""",
-"""
-main() => '''
-""",
-"""
-main() => \"\"\"
-""",
-"""
-main() => r'''
-""",
-"""
-main() => r\"\"\"
-"""]),
-
- MessageKind.UNMATCHED_TOKEN:
- const MessageTemplate(MessageKind.UNMATCHED_TOKEN,
- "Can't find '#{end}' to match '#{begin}'.",
- howToFix: DONT_KNOW_HOW_TO_FIX,
- examples: const[
- "main(",
- "main(){",
- "main(){]}",
- ]),
-
- MessageKind.UNTERMINATED_TOKEN:
- const MessageTemplate(MessageKind.UNTERMINATED_TOKEN,
- // This is a fall-back message that shouldn't happen.
- "Incomplete token."),
-
- MessageKind.EXPONENT_MISSING:
- const MessageTemplate(MessageKind.EXPONENT_MISSING,
- "Numbers in exponential notation should always contain an exponent"
- " (an integer number with an optional sign).",
- howToFix:
- "Make sure there is an exponent, and remove any whitespace "
- "before it.",
- examples: const ["""
-main() {
- var i = 1e;
-}
-"""]),
-
- MessageKind.HEX_DIGIT_EXPECTED:
- const MessageTemplate(MessageKind.HEX_DIGIT_EXPECTED,
- "A hex digit (0-9 or A-F) must follow '0x'.",
- howToFix:
- DONT_KNOW_HOW_TO_FIX, // Seems obvious from the error message.
- examples: const ["""
-main() {
- var i = 0x;
-}
-"""]),
-
- MessageKind.MALFORMED_STRING_LITERAL:
- const MessageTemplate(MessageKind.MALFORMED_STRING_LITERAL,
- r"A '$' has special meaning inside a string, and must be followed by "
- "an identifier or an expression in curly braces ({}).",
- howToFix: r"Try adding a backslash (\) to escape the '$'.",
- examples: const [r"""
-main() {
- return '$';
-}
-""",
-r'''
-main() {
- return "$";
-}
-''',
-r"""
-main() {
- return '''$''';
-}
-""",
-r'''
-main() {
- return """$""";
-}
-''']),
-
- MessageKind.UNTERMINATED_COMMENT:
- const MessageTemplate(MessageKind.UNTERMINATED_COMMENT,
- "Comment starting with '/*' must end with '*/'.",
- howToFix: DONT_KNOW_HOW_TO_FIX,
- examples: const [r"""
-main() {
-}
-/*"""]),
-
- MessageKind.MISSING_TOKEN_BEFORE_THIS:
- const MessageTemplate(MessageKind.MISSING_TOKEN_BEFORE_THIS,
- "Expected '#{token}' before this.",
- // Consider the second example below: the parser expects a ')' before
- // 'y', but a ',' would also have worked. We don't have enough
- // information to give a good suggestion.
- howToFix: DONT_KNOW_HOW_TO_FIX,
- examples: const [
- "main() => true ? 1;",
- "main() => foo(x: 1 y: 2);",
- ]),
-
- MessageKind.MISSING_TOKEN_AFTER_THIS:
- const MessageTemplate(MessageKind.MISSING_TOKEN_AFTER_THIS,
- "Expected '#{token}' after this.",
- // See [MISSING_TOKEN_BEFORE_THIS], we don't have enough information
- // to give a good suggestion.
- howToFix: DONT_KNOW_HOW_TO_FIX,
- examples: const [
- "main(x) {x}",
-"""
-class S1 {}
-class S2 {}
-class S3 {}
-class A = S1 with S2, S3
-main() => new A();
-"""
-]),
-
- MessageKind.CONSIDER_ANALYZE_ALL:
- const MessageTemplate(MessageKind.CONSIDER_ANALYZE_ALL,
- "Could not find '#{main}'. Nothing will be analyzed.",
- howToFix: "Try using '--analyze-all' to analyze everything.",
- examples: const ['']),
-
- MessageKind.MISSING_MAIN:
- const MessageTemplate(MessageKind.MISSING_MAIN,
- "Could not find '#{main}'.",
- howToFix: "Try adding a method named '#{main}' to your program."
- /* No example, test uses '--analyze-only' which will produce the above
- * message [CONSIDER_ANALYZE_ALL]. An example for a human operator
- * would be an empty file.*/),
-
- MessageKind.MAIN_NOT_A_FUNCTION:
- const MessageTemplate(MessageKind.MAIN_NOT_A_FUNCTION,
- "'#{main}' is not a function.",
- howToFix: DONT_KNOW_HOW_TO_FIX, /* Don't state the obvious. */
- examples: const ['var main;']),
-
- MessageKind.MAIN_WITH_EXTRA_PARAMETER:
- const MessageTemplate(MessageKind.MAIN_WITH_EXTRA_PARAMETER,
- "'#{main}' cannot have more than two parameters.",
- howToFix: DONT_KNOW_HOW_TO_FIX, /* Don't state the obvious. */
- examples: const ['main(a, b, c) {}']),
-
- MessageKind.COMPILER_CRASHED:
- const MessageTemplate(MessageKind.COMPILER_CRASHED,
- "The compiler crashed when compiling this element."),
-
- MessageKind.PLEASE_REPORT_THE_CRASH:
- const MessageTemplate(MessageKind.PLEASE_REPORT_THE_CRASH, '''
-The compiler is broken.
-
-When compiling the above element, the compiler crashed. It is not
-possible to tell if this is caused by a problem in your program or
-not. Regardless, the compiler should not crash.
-
-The Dart team would greatly appreciate if you would take a moment to
-report this problem at http://dartbug.com/new.
-
-Please include the following information:
-
-* the name and version of your operating system,
-
-* the Dart SDK build number (#{buildId}), and
-
-* the entire message you see here (including the full stack trace
- below as well as the source location above).
-'''),
-
- MessageKind.POTENTIAL_MUTATION:
- const MessageTemplate(MessageKind.POTENTIAL_MUTATION,
- "Variable '#{variableName}' is not known to be of type "
- "'#{shownType}' because it is potentially mutated in the scope for "
- "promotion."),
-
- MessageKind.POTENTIAL_MUTATION_HERE:
- const MessageTemplate(MessageKind.POTENTIAL_MUTATION_HERE,
- "Variable '#{variableName}' is potentially mutated here."),
-
- MessageKind.POTENTIAL_MUTATION_IN_CLOSURE:
- const MessageTemplate(MessageKind.POTENTIAL_MUTATION_IN_CLOSURE,
- "Variable '#{variableName}' is not known to be of type "
- "'#{shownType}' because it is potentially mutated within a closure."),
-
- MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE:
- const MessageTemplate(MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE,
- "Variable '#{variableName}' is potentially mutated in a "
- "closure here."),
-
- MessageKind.ACCESSED_IN_CLOSURE:
- const MessageTemplate(MessageKind.ACCESSED_IN_CLOSURE,
- "Variable '#{variableName}' is not known to be of type "
- "'#{shownType}' because it is accessed by a closure in the scope for "
- "promotion and potentially mutated in the scope of "
- "'#{variableName}'."),
-
- MessageKind.ACCESSED_IN_CLOSURE_HERE:
- const MessageTemplate(MessageKind.ACCESSED_IN_CLOSURE_HERE,
- "Variable '#{variableName}' is accessed in a closure here."),
-
- MessageKind.NOT_MORE_SPECIFIC:
- const MessageTemplate(MessageKind.NOT_MORE_SPECIFIC,
- "Variable '#{variableName}' is not shown to have type "
- "'#{shownType}' because '#{shownType}' is not more specific than the "
- "known type '#{knownType}' of '#{variableName}'."),
-
- MessageKind.NOT_MORE_SPECIFIC_SUBTYPE:
- const MessageTemplate(MessageKind.NOT_MORE_SPECIFIC_SUBTYPE,
- "Variable '#{variableName}' is not shown to have type "
- "'#{shownType}' because '#{shownType}' is not a subtype of the "
- "known type '#{knownType}' of '#{variableName}'."),
-
- MessageKind.NOT_MORE_SPECIFIC_SUGGESTION:
- const MessageTemplate(MessageKind.NOT_MORE_SPECIFIC_SUGGESTION,
- "Variable '#{variableName}' is not shown to have type "
- "'#{shownType}' because '#{shownType}' is not more specific than the "
- "known type '#{knownType}' of '#{variableName}'.",
- howToFix:
- "Try replacing '#{shownType}' with '#{shownTypeSuggestion}'."),
-
- MessageKind.NO_COMMON_SUBTYPES:
- const MessageTemplate(MessageKind.NO_COMMON_SUBTYPES,
- "Types '#{left}' and '#{right}' have no common subtypes."),
-
- MessageKind.HIDDEN_WARNINGS_HINTS:
- const MessageTemplate(MessageKind.HIDDEN_WARNINGS_HINTS,
- "#{warnings} warning(s) and #{hints} hint(s) suppressed in #{uri}."),
-
- MessageKind.HIDDEN_WARNINGS:
- const MessageTemplate(MessageKind.HIDDEN_WARNINGS,
- "#{warnings} warning(s) suppressed in #{uri}."),
-
- MessageKind.HIDDEN_HINTS:
- const MessageTemplate(MessageKind.HIDDEN_HINTS,
- "#{hints} hint(s) suppressed in #{uri}."),
-
- MessageKind.PREAMBLE:
- const MessageTemplate(MessageKind.PREAMBLE,
- "When run on the command-line, the compiled output might"
- " require a preamble file located in:\n"
- " <sdk>/lib/_internal/js_runtime/lib/preambles."),
-
- MessageKind.INVALID_SYNC_MODIFIER:
- const MessageTemplate(MessageKind.INVALID_SYNC_MODIFIER,
- "Invalid modifier 'sync'.",
- options: const ['--enable-async'],
- howToFix: "Try replacing 'sync' with 'sync*'.",
- examples: const [
- "main() sync {}"
- ]),
-
- MessageKind.INVALID_AWAIT_FOR:
- const MessageTemplate(MessageKind.INVALID_AWAIT_FOR,
- "'await' is only supported on for-in loops.",
- options: const ['--enable-async'],
- howToFix: "Try rewriting the loop as a for-in loop or removing the "
- "'await' keyword.",
- examples: const ["""
-main() async* {
- await for (int i = 0; i < 10; i++) {}
-}
-"""]),
-
- MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD:
- const MessageTemplate(MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
- "The modifier '#{modifier}' is not allowed on an abstract method.",
- options: const ['--enable-async'],
- howToFix: "Try removing the '#{modifier}' modifier or adding a "
- "body to the method.",
- examples: const ["""
-abstract class A {
- method() async;
-}
-class B extends A {
- method() {}
-}
-main() {
- A a = new B();
- a.method();
-}
-"""]),
-
- MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR:
- const MessageTemplate(MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR,
- "The modifier '#{modifier}' is not allowed on constructors.",
- options: const ['--enable-async'],
- howToFix: "Try removing the '#{modifier}' modifier.",
- examples: const ["""
-class A {
- A() async;
-}
-main() => new A();""",
-
-"""
-class A {
- A();
- factory A.a() async* {}
-}
-main() => new A.a();"""]),
-
- MessageKind.ASYNC_MODIFIER_ON_SETTER:
- const MessageTemplate(MessageKind.ASYNC_MODIFIER_ON_SETTER,
- "The modifier '#{modifier}' is not allowed on setters.",
- options: const ['--enable-async'],
- howToFix: "Try removing the '#{modifier}' modifier.",
- examples: const ["""
-class A {
- set foo(v) async {}
-}
-main() => new A().foo = 0;"""]),
-
- MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY:
- const MessageTemplate(MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY,
- "The modifier '#{modifier}' is not allowed on methods implemented "
- "using '=>'.",
- options: const ['--enable-async'],
- howToFix: "Try removing the '#{modifier}' modifier or implementing "
- "the method body using a block: '{ ... }'.",
- examples: const ["main() sync* => null;", "main() async* => null;"]),
-
- // TODO(johnniwinther): Check for 'async' as identifier.
- MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER:
- const MessageTemplate(MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER,
- "'#{keyword}' cannot be used as an identifier in a function body "
- "marked with '#{modifier}'.",
- options: const ['--enable-async'],
- howToFix: "Try removing the '#{modifier}' modifier or renaming the "
- "identifier.",
- examples: const ["""
-main() async {
- var await;
-}""",
-"""
-main() async* {
- var yield;
-}""",
-"""
-main() sync* {
- var yield;
-}"""]),
-
- MessageKind.RETURN_IN_GENERATOR:
- const MessageTemplate(MessageKind.RETURN_IN_GENERATOR,
- "'return' with a value is not allowed in a method body using the "
- "'#{modifier}' modifier.",
- howToFix: "Try removing the value, replacing 'return' with 'yield' "
- "or changing the method body modifier.",
- examples: const [
-"""
-foo() async* { return 0; }
-main() => foo();
-""",
-
-"""
-foo() sync* { return 0; }
-main() => foo();
-"""]),
-
- MessageKind.NATIVE_NOT_SUPPORTED:
- const MessageTemplate(MessageKind.NATIVE_NOT_SUPPORTED,
- "'native' modifier is not supported.",
- howToFix: "Try removing the 'native' implementation or analyzing the "
- "code with the --allow-native-extensions option.",
- examples: const ["""
-main() native "Main";
-"""]),
-
- MessageKind.DART_EXT_NOT_SUPPORTED:
- const MessageTemplate(MessageKind.DART_EXT_NOT_SUPPORTED,
- "The 'dart-ext' scheme is not supported.",
- howToFix: "Try analyzing the code with the --allow-native-extensions "
- "option.",
- examples: const ["""
-import 'dart-ext:main';
-
-main() {}
-"""]),
-
- MessageKind.LIBRARY_TAG_MUST_BE_FIRST:
- const MessageTemplate(MessageKind.LIBRARY_TAG_MUST_BE_FIRST,
- "The library declaration should come before other declarations.",
- howToFix: "Try moving the declaration to the top of the file.",
- examples: const [
-"""
-import 'dart:core';
-library foo;
-main() {}
-""",
- ]),
-
- MessageKind.ONLY_ONE_LIBRARY_TAG:
- const MessageTemplate(MessageKind.ONLY_ONE_LIBRARY_TAG,
- "There can only be one library declaration.",
- howToFix: "Try removing all other library declarations.",
- examples: const [
-"""
-library foo;
-library bar;
-main() {}
-""",
-"""
-library foo;
-import 'dart:core';
-library bar;
-main() {}
-""",
- ]),
-
- MessageKind.IMPORT_BEFORE_PARTS:
- const MessageTemplate(MessageKind.IMPORT_BEFORE_PARTS,
- "Import declarations should come before parts.",
- howToFix: "Try moving this import further up in the file.",
- examples: const [
- const <String, String>{
- 'main.dart': """
-library test.main;
-part 'part.dart';
-import 'dart:core';
-main() {}
-""",
- 'part.dart': """
-part of test.main;
-""",
- }]),
-
- MessageKind.EXPORT_BEFORE_PARTS:
- const MessageTemplate(MessageKind.EXPORT_BEFORE_PARTS,
- "Export declarations should come before parts.",
- howToFix: "Try moving this export further up in the file.",
- examples: const [
- const <String, String>{
- 'main.dart': """
-library test.main;
-part 'part.dart';
-export 'dart:core';
-main() {}
-""",
- 'part.dart': """
-part of test.main;
-""",
- }]),
-
- //////////////////////////////////////////////////////////////////////////////
- // Patch errors start.
- //////////////////////////////////////////////////////////////////////////////
-
- MessageKind.PATCH_RETURN_TYPE_MISMATCH:
- const MessageTemplate(MessageKind.PATCH_RETURN_TYPE_MISMATCH,
- "Patch return type '#{patchReturnType}' does not match "
- "'#{originReturnType}' on origin method '#{methodName}'."),
-
- MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH:
- const MessageTemplate(
- MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH,
- "Required parameter count of patch method "
- "(#{patchParameterCount}) does not match parameter count on origin "
- "method '#{methodName}' (#{originParameterCount})."),
-
- MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH:
- const MessageTemplate(
- MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH,
- "Optional parameter count of patch method "
- "(#{patchParameterCount}) does not match parameter count on origin "
- "method '#{methodName}' (#{originParameterCount})."),
-
- MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH:
- const MessageTemplate(
- MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH,
- "Optional parameters of origin and patch method "
- "'#{methodName}' must both be either named or positional."),
-
- MessageKind.PATCH_PARAMETER_MISMATCH:
- const MessageTemplate(MessageKind.PATCH_PARAMETER_MISMATCH,
- "Patch method parameter '#{patchParameter}' does not match "
- "'#{originParameter}' on origin method '#{methodName}'."),
-
- MessageKind.PATCH_PARAMETER_TYPE_MISMATCH:
- const MessageTemplate(MessageKind.PATCH_PARAMETER_TYPE_MISMATCH,
- "Patch method parameter '#{parameterName}' type "
- "'#{patchParameterType}' does not match '#{originParameterType}' on "
- "origin method '#{methodName}'."),
-
- MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION:
- const MessageTemplate(MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION,
- "External method without an implementation."),
-
- MessageKind.PATCH_POINT_TO_FUNCTION:
- const MessageTemplate(MessageKind.PATCH_POINT_TO_FUNCTION,
- "This is the function patch '#{functionName}'."),
-
- MessageKind.PATCH_POINT_TO_CLASS:
- const MessageTemplate(MessageKind.PATCH_POINT_TO_CLASS,
- "This is the class patch '#{className}'."),
-
- MessageKind.PATCH_POINT_TO_GETTER:
- const MessageTemplate(MessageKind.PATCH_POINT_TO_GETTER,
- "This is the getter patch '#{getterName}'."),
-
- MessageKind.PATCH_POINT_TO_SETTER:
- const MessageTemplate(MessageKind.PATCH_POINT_TO_SETTER,
- "This is the setter patch '#{setterName}'."),
-
- MessageKind.PATCH_POINT_TO_CONSTRUCTOR:
- const MessageTemplate(MessageKind.PATCH_POINT_TO_CONSTRUCTOR,
- "This is the constructor patch '#{constructorName}'."),
-
- MessageKind.PATCH_POINT_TO_PARAMETER:
- const MessageTemplate(MessageKind.PATCH_POINT_TO_PARAMETER,
- "This is the patch parameter '#{parameterName}'."),
-
- MessageKind.PATCH_NON_EXISTING:
- const MessageTemplate(MessageKind.PATCH_NON_EXISTING,
- "Origin does not exist for patch '#{name}'."),
-
- // TODO(ahe): Eventually, this error should be removed as it will be
- // handled by the regular parser.
- MessageKind.PATCH_NONPATCHABLE:
- const MessageTemplate(MessageKind.PATCH_NONPATCHABLE,
- "Only classes and functions can be patched."),
-
- MessageKind.PATCH_NON_EXTERNAL:
- const MessageTemplate(MessageKind.PATCH_NON_EXTERNAL,
- "Only external functions can be patched."),
-
- MessageKind.PATCH_NON_CLASS:
- const MessageTemplate(MessageKind.PATCH_NON_CLASS,
- "Patching non-class with class patch '#{className}'."),
-
- MessageKind.PATCH_NON_GETTER:
- const MessageTemplate(MessageKind.PATCH_NON_GETTER,
- "Cannot patch non-getter '#{name}' with getter patch."),
-
- MessageKind.PATCH_NO_GETTER:
- const MessageTemplate(MessageKind.PATCH_NO_GETTER,
- "No getter found for getter patch '#{getterName}'."),
-
- MessageKind.PATCH_NON_SETTER:
- const MessageTemplate(MessageKind.PATCH_NON_SETTER,
- "Cannot patch non-setter '#{name}' with setter patch."),
-
- MessageKind.PATCH_NO_SETTER:
- const MessageTemplate(MessageKind.PATCH_NO_SETTER,
- "No setter found for setter patch '#{setterName}'."),
-
- MessageKind.PATCH_NON_CONSTRUCTOR:
- const MessageTemplate(MessageKind.PATCH_NON_CONSTRUCTOR,
- "Cannot patch non-constructor with constructor patch "
- "'#{constructorName}'."),
-
- MessageKind.PATCH_NON_FUNCTION:
- const MessageTemplate(MessageKind.PATCH_NON_FUNCTION,
- "Cannot patch non-function with function patch "
- "'#{functionName}'."),
-
- MessageKind.INJECTED_PUBLIC_MEMBER:
- const MessageTemplate(MessageKind.INJECTED_PUBLIC_MEMBER,
- "Non-patch members in patch libraries must be private."),
-
- MessageKind.EXTERNAL_WITH_BODY:
- const MessageTemplate(MessageKind.EXTERNAL_WITH_BODY,
- "External function '#{functionName}' cannot have a function body.",
- options: const ["--output-type=dart"],
- howToFix:
- "Try removing the 'external' modifier or the function body.",
- examples: const ["""
-external foo() => 0;
-main() => foo();
-""", """
-external foo() {}
-main() => foo();
-"""]),
-
- //////////////////////////////////////////////////////////////////////////////
- // Patch errors end.
- //////////////////////////////////////////////////////////////////////////////
-
- MessageKind.EXPERIMENTAL_ASSERT_MESSAGE:
- const MessageTemplate(MessageKind.EXPERIMENTAL_ASSERT_MESSAGE,
- "Experimental language feature 'assertion with message'"
- " is not supported.",
- howToFix:
- "Use option '--assert-message' to use assertions with messages.",
- examples: const [r'''
-main() {
- int n = -7;
- assert(n > 0, 'must be positive: $n');
-}
-''']),
-
- MessageKind.IMPORT_EXPERIMENTAL_MIRRORS:
- const MessageTemplate(MessageKind.IMPORT_EXPERIMENTAL_MIRRORS, r'''
-
-****************************************************************
-* WARNING: dart:mirrors support in dart2js is experimental,
-* and not recommended.
-* This implementation of mirrors is incomplete,
-* and often greatly increases the size of the generated
-* JavaScript code.
-*
-* Your app imports dart:mirrors via:''''''
-$IMPORT_EXPERIMENTAL_MIRRORS_PADDING#{importChain}
-*
-* You can disable this message by using the --enable-experimental-mirrors
-* command-line flag.
-*
-* To learn what to do next, please visit:
-* http://dartlang.org/dart2js-reflection
-****************************************************************
-'''),
-
- MessageKind.DISALLOWED_LIBRARY_IMPORT:
- const MessageTemplate(MessageKind.DISALLOWED_LIBRARY_IMPORT, '''
-Your app imports the unsupported library '#{uri}' via:
-''''''
-$DISALLOWED_LIBRARY_IMPORT_PADDING#{importChain}
-
-Use the --categories option to support import of '#{uri}'.
-'''),
-
- MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND:
- const MessageTemplate(
- MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND,
- """
-dart:mirrors library is not supported when using this backend.
-
-Your app imports dart:mirrors via:""""""
-$MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING#{importChain}"""),
-
- MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS:
- const MessageTemplate(MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS,
- "Non-supported 'call' member on a native class, or a "
- "subclass of a native class."),
-
- MessageKind.DIRECTLY_THROWING_NSM:
- const MessageTemplate(MessageKind.DIRECTLY_THROWING_NSM,
- "This 'noSuchMethod' implementation is guaranteed to throw an "
- "exception. The generated code will be smaller if it is "
- "rewritten.",
- howToFix: "Rewrite to "
- "'noSuchMethod(Invocation i) => super.noSuchMethod(i);'."),
-
- MessageKind.COMPLEX_THROWING_NSM:
- const MessageTemplate(MessageKind.COMPLEX_THROWING_NSM,
- "This 'noSuchMethod' implementation is guaranteed to throw an "
- "exception. The generated code will be smaller and the compiler "
- "will be able to perform more optimizations if it is rewritten.",
- howToFix: "Rewrite to "
- "'noSuchMethod(Invocation i) => super.noSuchMethod(i);'."),
-
- MessageKind.COMPLEX_RETURNING_NSM:
- const MessageTemplate(MessageKind.COMPLEX_RETURNING_NSM,
- "Overriding 'noSuchMethod' causes the compiler to generate "
- "more code and prevents the compiler from doing some optimizations.",
- howToFix: "Consider removing this 'noSuchMethod' implementation."),
-
- MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP:
- const MessageTemplate(MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP,
- "Unsupported version of package:lookup_map.",
- howToFix: DONT_KNOW_HOW_TO_FIX),
-
- }; // End of TEMPLATES.
-
- /// Padding used before and between import chains in the message for
- /// [MessageKind.IMPORT_EXPERIMENTAL_MIRRORS].
- static const String IMPORT_EXPERIMENTAL_MIRRORS_PADDING = '\n* ';
-
- /// Padding used before and between import chains in the message for
- /// [MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND].
- static const String MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING = '\n ';
-
- /// Padding used before and between import chains in the message for
- /// [MessageKind.DISALLOWED_LIBRARY_IMPORT].
- static const String DISALLOWED_LIBRARY_IMPORT_PADDING = '\n ';
+ const MessageTemplate(this.kind, this.id, this.template, this.howToFix,
+ this.examples, this.options);
toString() => template;
@@ -3577,7 +898,42 @@
return new Message(this, arguments, terse);
}
- bool get hasHowToFix => howToFix != null && howToFix != DONT_KNOW_HOW_TO_FIX;
+ bool get hasHowToFix =>
+ howToFix != null && howToFix != dart2js_messages.DONT_KNOW_HOW_TO_FIX;
+
+ static final Map<MessageKind, MessageTemplate> TEMPLATES =
+ _constructMessageTemplates();
+
+ static String get IMPORT_EXPERIMENTAL_MIRRORS_PADDING =>
+ dart2js_messages.IMPORT_EXPERIMENTAL_MIRRORS_PADDING;
+
+ static String get MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING =>
+ dart2js_messages.MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING;
+
+ static String get DISALLOWED_LIBRARY_IMPORT_PADDING =>
+ dart2js_messages.DISALLOWED_LIBRARY_IMPORT_PADDING;
+
+ static Map<MessageKind, MessageTemplate> _constructMessageTemplates() {
+ Map<MessageKind, MessageTemplate> result = <MessageKind, MessageTemplate>{};
+ for (MessageKind kind in MessageKind.values) {
+ String name = _KIND_TO_STRING_MAP[kind];
+ if (name == null) {
+ throw new ArgumentError("No mapping for $kind in _KIND_TO_STRING_MAP");
+ }
+ Map data =
+ shared_messages.MESSAGES[name] ?? dart2js_messages.MESSAGES[name];
+ if (data == null) throw new ArgumentError.value(name);
+
+ String id = data['id'];
+ String template = data['template'];
+ String howToFix = data['howToFix'];
+ List examples = data['examples'];
+ List<String> options = data['options'] ?? const <String>[];
+ result[kind] =
+ new MessageTemplate(kind, id, template, howToFix, examples, options);
+ }
+ return result;
+ }
}
class Message {
@@ -3587,7 +943,10 @@
String message;
Message(this.template, this.arguments, this.terse) {
- assert(() { computeMessage(); return true; });
+ assert(() {
+ computeMessage();
+ return true;
+ });
}
MessageKind get kind => template.kind;
@@ -3601,7 +960,7 @@
assert(invariant(
CURRENT_ELEMENT_SPANNABLE,
kind == MessageKind.GENERIC ||
- !message.contains(new RegExp(r'#\{.+\}')),
+ !message.contains(new RegExp(r'#\{.+\}')),
message: 'Missing arguments in error message: "$message"'));
if (!terse && template.hasHowToFix) {
String howToFix = template.howToFix;
@@ -3618,8 +977,8 @@
return computeMessage();
}
- bool operator==(other) {
- if (other is !Message) return false;
+ bool operator ==(other) {
+ if (other is! Message) return false;
return (template == other.template) && (toString() == other.toString());
}
diff --git a/pkg/compiler/lib/src/diagnostics/shared_messages.dart b/pkg/compiler/lib/src/diagnostics/shared_messages.dart
new file mode 100644
index 0000000..0a4d2ab
--- /dev/null
+++ b/pkg/compiler/lib/src/diagnostics/shared_messages.dart
@@ -0,0 +1,61 @@
+// 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.
+
+// This file is parsed by JavaScript and must not use fancy Dart constructs.
+// It can contain JSON like constructs and "//" comments (but not "/*" "*/").
+// It must have one assignment (`final MESSAGES =`).
+// All strings must be raw strings.
+
+// The messages in this file should meet the following guide lines:
+//
+// 1. The message should be a complete sentence starting with an uppercase
+// letter, and ending with a period.
+//
+// 2. Reserved words and embedded identifiers should be in single quotes, so
+// prefer double quotes for the complete message. For example, "The
+// class '#{className}' can't use 'super'." Notice that the word 'class' in the
+// preceding message is not quoted as it refers to the concept 'class', not the
+// reserved word. On the other hand, 'super' refers to the reserved word. Do
+// not quote 'null' and numeric literals.
+//
+// 3. Do not try to compose messages, as it can make translating them hard.
+//
+// 4. Try to keep the error messages short, but informative.
+//
+// 5. Use simple words and terminology, assume the reader of the message
+// doesn't have an advanced degree in math, and that English is not the
+// reader's native language. Do not assume any formal computer science
+// training. For example, do not use Latin abbreviations (prefer "that is" over
+// "i.e.", and "for example" over "e.g."). Also avoid phrases such as "if and
+// only if" and "iff", that level of precision is unnecessary.
+//
+// 6. Prefer contractions when they are in common use, for example, prefer
+// "can't" over "cannot". Using "cannot", "must not", "shall not", etc. is
+// off-putting to people new to programming.
+//
+// 7. Use common terminology, preferably from the Dart Language
+// Specification. This increases the user's chance of finding a good
+// explanation on the web.
+//
+// 8. Do not try to be cute or funny. It is extremely frustrating to work on a
+// product that crashes with a "tongue-in-cheek" message, especially if you did
+// not want to use this product to begin with.
+//
+// 9. Do not lie, that is, do not write error messages containing phrases like
+// "can't happen". If the user ever saw this message, it would be a
+// lie. Prefer messages like: "Internal error: This function should not be
+// called when 'x' is null.".
+//
+// 10. Prefer to not use imperative tone. That is, the message should not sound
+// accusing or like it is ordering the user around. The computer should
+// describe the problem, not criticize for violating the specification.
+//
+// Other things to keep in mind:
+//
+// Generally, we want to provide messages that consists of three sentences:
+// 1. what is wrong, 2. why is it wrong, 3. how do I fix it. However, we
+// combine the first two in [template] and the last in [howToFix].
+
+final MESSAGES = {
+};
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index 95b2b2a..5549f45 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -785,9 +785,9 @@
void setPartOf(PartOf tag, DiagnosticReporter reporter) {
LibraryElementX library = enclosingElement;
if (library.entryCompilationUnit == this) {
+ // This compilation unit is loaded as a library. The error is reported by
+ // the library loader.
partTag = tag;
- reporter.reportErrorMessage(
- tag, MessageKind.IMPORT_PART_OF);
return;
}
if (!localMembers.isEmpty) {
diff --git a/pkg/compiler/lib/src/js/placeholder_safety.dart b/pkg/compiler/lib/src/js/placeholder_safety.dart
new file mode 100644
index 0000000..67ff563
--- /dev/null
+++ b/pkg/compiler/lib/src/js/placeholder_safety.dart
@@ -0,0 +1,327 @@
+// 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 js.safety;
+
+import "js.dart" as js;
+
+typedef bool PositionPredicate(int position);
+
+/// PlaceholderSafetyAnalysis determines which placeholders in a JavaScript
+/// template may be replaced with an arbitrary expression. Placeholders may be
+/// replaced with an arbitrary expression providied the template ensures the
+/// placeholders are evaluated in the same left-to-right order with no
+/// additional effects interleaved.
+///
+/// The result is semi-conservative, giving reasonable results for many simple
+/// JS fragments. The non-conservative part is the assumption that arithmetic
+/// operators are used on 'good' operands that do not force arbitrary code to be
+/// executed via conversions (valueOf() and toString() methods).
+class PlaceholderSafetyAnalysis extends js.BaseVisitor<int> {
+ final PositionPredicate isNullableInput;
+ int nextPosition = 0;
+ int maxSafePosition = -1;
+ bool safe = true;
+
+ // We do a crude abstract interpretation to find operations that might throw
+ // exceptions. The possible values of expressions are represented by
+ // integers. Small non-negative integers 0, 1, 2, ... represent the values of
+ // the placeholders. Other values are:
+ static const int NONNULL_VALUE = -1; // Unknown but not null.
+ static const int UNKNOWN_VALUE = -2; // Unknown and might be null.
+
+ PlaceholderSafetyAnalysis._(this.isNullableInput);
+
+ /// Returns the number of placeholders that can be substituted into the
+ /// template AST [node] without changing the order of observable effects.
+ /// [isNullableInput] is a function that takes the 0-based index of a
+ /// placeholder and returns `true` if expression at run time may be null, and
+ /// `false` if the value is never null.
+ static int analyze(js.Node node, PositionPredicate isNullableInput) {
+ PlaceholderSafetyAnalysis analysis =
+ new PlaceholderSafetyAnalysis._(isNullableInput);
+ analysis.visit(node);
+ return analysis.maxSafePosition + 1;
+ }
+
+ bool canBeNull(int value) {
+ if (value == NONNULL_VALUE) return false;
+ if (value == UNKNOWN_VALUE) return true;
+ return isNullableInput(value);
+ }
+
+ int unsafe(int value) {
+ safe = false;
+ return value;
+ }
+
+ int visit(js.Node node) {
+ return node.accept(this);
+ }
+
+ int visitNode(js.Node node) {
+ safe = false;
+ super.visitNode(node);
+ return UNKNOWN_VALUE;
+ }
+
+ int visitLiteralNull(js.LiteralNull node) {
+ return UNKNOWN_VALUE;
+ }
+
+ int visitLiteral(js.Literal node) {
+ return NONNULL_VALUE;
+ }
+
+ int handleInterpolatedNode(js.InterpolatedNode node) {
+ assert(node.isPositional);
+ int position = nextPosition++;
+ if (safe) maxSafePosition = position;
+ return position;
+ }
+
+ int visitInterpolatedExpression(js.InterpolatedExpression node) {
+ return handleInterpolatedNode(node);
+ }
+
+ int visitInterpolatedLiteral(js.InterpolatedLiteral node) {
+ return handleInterpolatedNode(node);
+ }
+
+ int visitInterpolatedSelector(js.InterpolatedSelector node) {
+ return handleInterpolatedNode(node);
+ }
+
+ int visitInterpolatedStatement(js.InterpolatedStatement node) {
+ return handleInterpolatedNode(node);
+ }
+
+ int visitInterpolatedDeclaration(js.InterpolatedDeclaration node) {
+ return handleInterpolatedNode(node);
+ }
+
+ int visitObjectInitializer(js.ObjectInitializer node) {
+ for (js.Property property in node.properties) {
+ visit(property);
+ }
+ return NONNULL_VALUE;
+ }
+
+ int visitProperty(js.Property node) {
+ visit(node.name);
+ visit(node.value);
+ return UNKNOWN_VALUE;
+ }
+
+ int visitArrayInitializer(js.ArrayInitializer node) {
+ node.elements.forEach(visit);
+ return NONNULL_VALUE;
+ }
+
+ int visitArrayHole(js.ArrayHole node) {
+ return UNKNOWN_VALUE;
+ }
+
+ int visitAccess(js.PropertyAccess node) {
+ int first = visit(node.receiver);
+ int second = visit(node.selector);
+ // TODO(sra): If the JS is annotated as never throwing, we can avoid this.
+ if (canBeNull(first)) safe = false;
+ return UNKNOWN_VALUE;
+ }
+
+ int visitAssignment(js.Assignment node) {
+ js.Expression left = node.leftHandSide;
+ js.Expression right = node.value;
+
+ int leftToRight() {
+ visit(left);
+ visit(right);
+ return UNKNOWN_VALUE;
+ }
+
+ if (left is js.InterpolatedNode) {
+ // A bare interpolated expression should not be the LHS of an assignment.
+ safe = false;
+ return leftToRight();
+ }
+
+ // Assignment operators dereference the LHS before evaluating the RHS.
+ if (node.op != null) return leftToRight();
+
+ // Assignment (1) evaluates the LHS as a Reference `lval`, (2) evaluates the
+ // RHS as a value, (3) dereferences the `lval` in PutValue.
+ if (left is js.VariableReference) {
+ int value = visit(right);
+ // Assignment could change an observed global or cause a ReferenceError.
+ safe = false;
+ return value;
+ }
+ if (left is js.PropertyAccess) {
+ // "a.b.x = c.y" gives a TypeError for null values in this order: `a`,
+ // `c`, `a.b`.
+ int receiver = visit(left.receiver);
+ int selector = visit(left.selector);
+ int value = visit(right);
+ if (canBeNull(receiver)) safe = false;
+ return value;
+ }
+ // Be conserative with unrecognized LHS expressions.
+ safe = false;
+ return leftToRight();
+ }
+
+ int visitCall(js.Call node) {
+ // TODO(sra): Recognize JavaScript built-ins like
+ // 'Object.prototype.hasOwnProperty.call'.
+ visit(node.target);
+ node.arguments.forEach(visit);
+ return unsafe(UNKNOWN_VALUE);
+ }
+
+ int visitNew(js.New node) {
+ visit(node.target);
+ node.arguments.forEach(visit);
+ return unsafe(NONNULL_VALUE);
+ }
+
+ int visitBinary(js.Binary node) {
+ switch (node.op) {
+ // We make the non-conservative assumption that these operations are not
+ // used in ways that force calling arbitrary code via valueOf() or
+ // toString().
+ case "*":
+ case "/":
+ case "%":
+ case "+":
+ case "-":
+ case "<<":
+ case ">>":
+ case ">>>":
+ case "<":
+ case ">":
+ case "<=":
+ case ">=":
+ case "==":
+ case "===":
+ case "!=":
+ case "!==":
+ case "&":
+ case "^":
+ case "|":
+ int left = visit(node.left);
+ int right = visit(node.right);
+ return NONNULL_VALUE; // Number, String, Boolean.
+
+ case ',':
+ int left = visit(node.left);
+ int right = visit(node.right);
+ return right;
+
+ case "&&":
+ case "||":
+ int left = visit(node.left);
+ // TODO(sra): Might be safe, e.g. "x || 0".
+ safe = false;
+ int right = visit(node.right);
+ return UNKNOWN_VALUE;
+
+ case "instanceof":
+ case "in":
+ int left = visit(node.left);
+ int right = visit(node.right);
+ return UNKNOWN_VALUE;
+
+ default:
+ return unsafe(UNKNOWN_VALUE);
+ }
+ }
+
+ int visitConditional(js.Conditional node) {
+ int cond = visit(node.condition);
+ // TODO(sra): Might be safe, e.g. "# ? 1 : 2".
+ safe = false;
+ int thenValue = visit(node.then);
+ int elseValue = visit(node.otherwise);
+ return UNKNOWN_VALUE;
+ }
+
+ int visitThrow(js.Throw node) {
+ visit(node.expression);
+ return unsafe(UNKNOWN_VALUE);
+ }
+
+ int visitPrefix(js.Prefix node) {
+ if (node.op == 'typeof') {
+ // "typeof a" first evaluates to a Reference. If the Reference is to a
+ // variable that is not present, "undefined" is returned without
+ // dereferencing.
+ if (node.argument is js.VariableUse) return NONNULL_VALUE; // A string.
+ }
+
+ visit(node.argument);
+
+ switch (node.op) {
+ case '+':
+ case '-':
+ case '!':
+ case '~':
+ // Non-conservative assumption that these operators are used on values
+ // that do not call arbitrary code via valueOf() or toString().
+ return NONNULL_VALUE;
+
+ case 'typeof':
+ return NONNULL_VALUE; // Always a string.
+
+ case 'void':
+ return UNKNOWN_VALUE;
+
+ case '--':
+ case '++':
+ return NONNULL_VALUE; // Always a number.
+
+ default:
+ safe = false;
+ return UNKNOWN_VALUE;
+ }
+ }
+
+ int visitPostfix(js.Postfix node) {
+ assert(node.op == '--' || node.op == '++');
+ visit(node.argument);
+ return NONNULL_VALUE; // Always a number, even for "(a=null, a++)".
+ }
+
+ int visitVariableUse(js.VariableUse node) {
+ // We could get a ReferenceError unless the variable is in scope. For JS
+ // fragments, the only use of VariableUse outside a `function(){...}` should
+ // be for global references. Certain global names are almost certainly not
+ // reference errors, e.g 'Array'.
+ switch (node.name) {
+ case 'Array':
+ case 'Date':
+ case 'Function':
+ case 'Number':
+ case 'Object':
+ case 'RegExp':
+ case 'String':
+ case 'self':
+ case 'window':
+ return NONNULL_VALUE;
+ default:
+ return unsafe(UNKNOWN_VALUE);
+ }
+ }
+
+ int visitFun(js.Fun node) {
+ bool oldSafe = safe;
+ int oldNextPosition = nextPosition;
+ visit(node.body);
+ // Creating a function has no effect on order unless there are embedded
+ // placeholders.
+ safe = (nextPosition == oldNextPosition) && oldSafe;
+ return NONNULL_VALUE;
+ }
+}
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 768a072..4cd691e 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -1888,6 +1888,8 @@
@override
int visitDeferred(DeferredConstantValue constant, [_]) {
+ // TODO(sra): Investigate that the use of hashCode here is probably a source
+ // of instability.
int hash = constant.prefix.hashCode;
return _combine(hash, _visit(constant.referenced));
}
diff --git a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
new file mode 100644
index 0000000..8e574c8
--- /dev/null
+++ b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
@@ -0,0 +1,213 @@
+// 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.
+
+library dart2js.js_emitter.constant_ordering;
+
+import '../constants/values.dart';
+
+import '../common.dart';
+//import '../core_types.dart';
+import '../dart_types.dart';
+import '../elements/elements.dart'
+ show Element,
+ Elements,
+ FieldElement;
+import '../tree/tree.dart' show DartString;
+import '../js_backend/js_backend.dart' show SyntheticConstantKind;
+
+/// A canonical but arbrary ordering of constants. The ordering is 'stable'
+/// under perturbation of the source.
+int deepCompareConstants(ConstantValue a, ConstantValue b) {
+ return _CompareVisitor.compareValues(a, b);
+}
+
+class _CompareVisitor implements ConstantValueVisitor<int, ConstantValue> {
+ const _CompareVisitor();
+
+ static int compareValues(ConstantValue a, ConstantValue b) {
+ if (identical(a, b)) return 0;
+ int r = _KindVisitor.kind(a).compareTo(_KindVisitor.kind(b));
+ if (r != 0) return r;
+ r = a.accept(const _CompareVisitor(), b);
+ return r;
+ }
+
+ static int compareNullable(int compare(a, b), a, b) {
+ if (a == null && b == null) return 0;
+ if (a == null) return -1;
+ if (b == null) return 1;
+ return compare(a, b);
+ }
+
+ static int compareLists(int compare(a, b), List a, List b) {
+ int r = a.length.compareTo(b.length);
+ if (r != 0) return r;
+ for (int i = 0; i < a.length; i++) {
+ r = compare(a[i], b[i]);
+ if (r != 0) return r;
+ }
+ return 0;
+ }
+
+ static int compareElements(Element a, Element b) {
+ int r = a.name.compareTo(b.name);
+ if (r != 0) return r;
+ return Elements.compareByPosition(a, b);
+ }
+
+ static int compareDartTypes(DartType a, DartType b) {
+ if (a == b) return 0;
+ int r = a.kind.index.compareTo(b.kind.index);
+ if (r != 0) return r;
+ r = compareNullable(compareElements, a.element, b.element);
+ if (r != 0) return r;
+
+ if (a is GenericType) {
+ GenericType aGeneric = a;
+ GenericType bGeneric = b;
+ r = compareLists(compareDartTypes,
+ aGeneric.typeArguments, bGeneric.typeArguments);
+ if (r != 0) return r;
+ }
+ throw 'unexpected compareDartTypes $a $b';
+ }
+
+ int visitFunction(FunctionConstantValue a, FunctionConstantValue b) {
+ return compareElements(a.element, b.element);
+ }
+
+ int visitNull(NullConstantValue a, NullConstantValue b) {
+ return 0;
+ }
+
+ int visitInt(IntConstantValue a, IntConstantValue b) {
+ return a.primitiveValue.compareTo(b.primitiveValue);
+ }
+
+ int visitDouble(DoubleConstantValue a, DoubleConstantValue b) {
+ return a.primitiveValue.compareTo(b.primitiveValue);
+ }
+
+ int visitBool(BoolConstantValue a, BoolConstantValue b) {
+ int aInt = a.primitiveValue ? 1 : 0;
+ int bInt = b.primitiveValue ? 1 : 0;
+ return aInt.compareTo(bInt);
+ }
+
+ int visitString(StringConstantValue a, StringConstantValue b) {
+ DartString aString = a.primitiveValue;
+ DartString bString = b.primitiveValue;
+ int r = aString.length.compareTo(bString.length);
+ if (r != 0) return r;
+ return aString.slowToString().compareTo(bString.slowToString());
+ }
+
+ int visitList(ListConstantValue a, ListConstantValue b) {
+ int r = compareLists(compareValues, a.entries, b.entries);
+ if (r != 0) return r;
+ return compareDartTypes(a.type, b.type);
+ }
+
+ int visitMap(MapConstantValue a, MapConstantValue b) {
+ int r = compareLists(compareValues, a.keys, b.keys);
+ if (r != 0) return r;
+ r = compareLists(compareValues, a.values, b.values);
+ if (r != 0) return r;
+ return compareDartTypes(a.type, b.type);
+ }
+
+ int visitConstructed(ConstructedConstantValue a, ConstructedConstantValue b) {
+ int r = compareDartTypes(a.type, b.type);
+ if (r != 0) return r;
+
+ List<FieldElement> aFields = a.fields.keys.toList()..sort(compareElements);
+ List<FieldElement> bFields = b.fields.keys.toList()..sort(compareElements);
+
+ r = compareLists(compareElements, aFields, bFields);
+ if (r != 0) return r;
+
+ return compareLists(compareValues,
+ aFields.map((field) => a.fields[field]).toList(),
+ aFields.map((field) => b.fields[field]).toList());
+ }
+
+ int visitType(TypeConstantValue a, TypeConstantValue b) {
+ int r = compareDartTypes(a.representedType, b.representedType);
+ if (r != 0) return r;
+ return compareDartTypes(a.type, b.type);
+ }
+
+ int visitInterceptor(InterceptorConstantValue a, InterceptorConstantValue b) {
+ return compareDartTypes(a.dispatchedType, b.dispatchedType);
+ }
+
+ int visitSynthetic(SyntheticConstantValue a, SyntheticConstantValue b) {
+ // [SyntheticConstantValue]s have abstract fields that are set only by
+ // convention. Lucky for us, they do not occur as top level constant, only
+ // as elements of a few constants. If this becomes a source of instability,
+ // we will need to add a total ordering on JavaScript ASTs including
+ // deferred elements.
+ SyntheticConstantKind aKind = a.kind;
+ SyntheticConstantKind bKind = b.kind;
+ int r = aKind.index - bKind.index;
+ if (r != 0) return r;
+ switch (a.kind) {
+ case SyntheticConstantKind.DUMMY_INTERCEPTOR:
+ case SyntheticConstantKind.EMPTY_VALUE:
+ // Never emitted.
+ return 0;
+
+ case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
+ // An opaque deferred JS AST reference to a type in reflection data.
+ return 0;
+ case SyntheticConstantKind.NAME:
+ // An opaque deferred JS AST reference to a name.
+ return 0;
+ default:
+ // Should not happen.
+ throw 'unexpected SyntheticConstantKind $aKind';
+ }
+ }
+
+ int visitDeferred(DeferredConstantValue a, DeferredConstantValue b) {
+ int r = compareValues(a.referenced, b.referenced);
+ if (r != 0) return r;
+ return compareElements(a.prefix, b.prefix);
+ }
+}
+
+class _KindVisitor implements ConstantValueVisitor<int, Null> {
+ const _KindVisitor();
+
+ static const int FUNCTION = 1;
+ static const int NULL = 2;
+ static const int INT = 3;
+ static const int DOUBLE = 4;
+ static const int BOOL = 5;
+ static const int STRING = 6;
+ static const int LIST = 7;
+ static const int MAP = 8;
+ static const int CONSTRUCTED = 9;
+ static const int TYPE = 10;
+ static const int INTERCEPTOR = 11;
+ static const int SYNTHETIC = 12;
+ static const int DEFERRED = 13;
+
+ static int kind(ConstantValue constant) =>
+ constant.accept(const _KindVisitor(), null);
+
+ int visitFunction(FunctionConstantValue a, _) => FUNCTION;
+ int visitNull(NullConstantValue a, _) => NULL;
+ int visitInt(IntConstantValue a, _) => INT;
+ int visitDouble(DoubleConstantValue a, _) => DOUBLE;
+ int visitBool(BoolConstantValue a, _) => BOOL;
+ int visitString(StringConstantValue a, _) => STRING;
+ int visitList(ListConstantValue a, _) => LIST;
+ int visitMap(MapConstantValue a, _) => MAP;
+ int visitConstructed(ConstructedConstantValue a, _) => CONSTRUCTED;
+ int visitType(TypeConstantValue a, _) => TYPE;
+ int visitInterceptor(InterceptorConstantValue a, _) => INTERCEPTOR;
+ int visitSynthetic(SyntheticConstantValue a, _) => SYNTHETIC;
+ int visitDeferred(DeferredConstantValue a, _) => DEFERRED;
+}
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
index 07ba88b..b16379f 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -17,6 +17,7 @@
import '../js_emitter.dart' as js_emitter show Emitter;
import '../model.dart';
import '../program_builder/program_builder.dart';
+import '../constant_ordering.dart' show deepCompareConstants;
import '../../common.dart';
import '../../common/names.dart' show
@@ -252,11 +253,9 @@
// which compresses a tiny bit better.
int r = namer.constantLongName(a).compareTo(namer.constantLongName(b));
if (r != 0) return r;
- // Resolve collisions in the long name by using the constant name (i.e. JS
- // name) which is unique.
- // TODO(herhut): Find a better way to resolve collisions.
- return namer.constantName(a).hashCode.compareTo(
- namer.constantName(b).hashCode);
+
+ // Resolve collisions in the long name by using a structural order.
+ return deepCompareConstants(a, b);
}
@override
@@ -1371,6 +1370,16 @@
assembleTypedefs(program);
}
+ jsAst.Statement buildDeferredHeader() {
+ /// For deferred loading we communicate the initializers via this global
+ /// variable. The deferred hunks will add their initialization to this.
+ /// The semicolon is important in minified mode, without it the
+ /// following parenthesis looks like a call to the object literal.
+ return js.statement('self.#deferredInitializers = '
+ 'self.#deferredInitializers || Object.create(null);',
+ {'deferredInitializers': deferredInitializers});
+ }
+
jsAst.Program buildOutputAstForMain(Program program,
Map<OutputUnit, _DeferredOutputUnitHash> deferredLoadHashes) {
MainFragment mainFragment = program.mainFragment;
@@ -1383,14 +1392,7 @@
..add(js.comment(HOOKS_API_USAGE));
if (isProgramSplit) {
- /// For deferred loading we communicate the initializers via this global
- /// variable. The deferred hunks will add their initialization to this.
- /// The semicolon is important in minified mode, without it the
- /// following parenthesis looks like a call to the object literal.
- statements.add(
- js.statement('self.#deferredInitializers = '
- 'self.#deferredInitializers || Object.create(null);',
- {'deferredInitializers': deferredInitializers}));
+ statements.add(buildDeferredHeader());
}
// Collect the AST for the decriptors
@@ -1999,6 +2001,7 @@
statements
..add(buildGeneratedBy())
+ ..add(buildDeferredHeader())
..add(js.statement('${deferredInitializers}.current = '
"""function (#, ${namer.staticStateHolder}) {
#
diff --git a/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
index 485195e..96838ac 100644
--- a/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
@@ -21,6 +21,7 @@
ConstantEmitter;
import '../js_emitter.dart' show NativeEmitter;
+import '../constant_ordering.dart' show deepCompareConstants;
import 'package:js_runtime/shared/embedded_names.dart' show
CREATE_NEW_ISOLATE,
@@ -108,9 +109,9 @@
// which compresses a tiny bit better.
int r = namer.constantLongName(a).compareTo(namer.constantLongName(b));
if (r != 0) return r;
- // Resolve collisions in the long name by using the constant name (i.e. JS
- // name) which is unique.
- return namer.constantName(a).compareTo(namer.constantName(b));
+
+ // Resolve collisions in the long name by using a structural order.
+ return deepCompareConstants(a, b);
}
js.Expression generateStaticClosureAccess(FunctionElement 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 7fbd768..14dea34 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
@@ -55,11 +55,6 @@
// names we want. Furthermore, the pretty-printer minifies local variables, thus
// reducing their size.
const String mainBoilerplate = '''
-{
-// Declare deferred-initializer global, which is used to keep track of the
-// loaded fragments.
-#deferredInitializer;
-
(function() {
// Copies the own properties from [from] to [to].
function copyProperties(from, to) {
@@ -355,8 +350,8 @@
// Invokes main (making sure that it records the 'current-script' value).
#invokeMain;
-})();
-}''';
+})()
+''';
/// Deferred fragments (aka 'hunks') are built similarly to the main fragment.
///
@@ -441,8 +436,7 @@
.where((Holder holder) => !holder.isStaticStateHolder);
return js.js.statement(mainBoilerplate,
- {'deferredInitializer': emitDeferredInitializerGlobal(program.loadMap),
- 'typeNameProperty': js.string(ModelEmitter.typeNameProperty),
+ {'typeNameProperty': js.string(ModelEmitter.typeNameProperty),
'cyclicThrow': backend.emitter.staticFunctionAccess(
backend.helpers.cyclicThrowHelper),
'operatorIsPrefix': js.string(namer.operatorIsPrefix),
@@ -516,15 +510,6 @@
});
}
- js.Statement emitDeferredInitializerGlobal(Map loadMap) {
- if (loadMap.isEmpty) return new js.Block.empty();
-
- String global = ModelEmitter.deferredInitializersGlobal;
- return js.js.statement(
- "if (typeof($global) === 'undefined') var # = Object.create(null);",
- new js.VariableDeclaration(global, allowRename: false));
- }
-
/// Emits all holders, except for the static-state holder.
///
/// The emitted holders contain classes (only the constructors) and all
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 739fe77..9e81bca 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
@@ -56,6 +56,7 @@
import '../../util/uri_extras.dart' show
relativize;
+import '../constant_ordering.dart' show deepCompareConstants;
import '../headers.dart';
import '../js_emitter.dart' show
NativeEmitter;
@@ -140,9 +141,9 @@
// which compresses a tiny bit better.
int r = namer.constantLongName(a).compareTo(namer.constantLongName(b));
if (r != 0) return r;
- // Resolve collisions in the long name by using the constant name (i.e. JS
- // name) which is unique.
- return namer.constantName(a).compareTo(namer.constantName(b));
+
+ // Resolve collisions in the long name by using a structural order.
+ return deepCompareConstants(a, b);
}
js.Expression generateStaticClosureAccess(FunctionElement element) {
@@ -208,7 +209,8 @@
token.setHash(hunkHashes[key]);
});
- writeMainFragment(mainFragment, mainCode);
+ writeMainFragment(mainFragment, mainCode,
+ isSplit: program.deferredFragments.isNotEmpty);
if (backend.requiresPreamble &&
!backend.htmlLibraryIsLoaded) {
@@ -249,10 +251,18 @@
return hunkHashes;
}
+ js.Statement buildDeferredInitializerGlobal() {
+ String global = deferredInitializersGlobal;
+ return js.js.statement(
+ "if (typeof($global) === 'undefined') var # = Object.create(null);",
+ new js.VariableDeclaration(global, allowRename: false));
+ }
+
// Writes the given [fragment]'s [code] into a file.
//
// Updates the shared [outputBuffers] field with the output.
- void writeMainFragment(MainFragment fragment, js.Statement code) {
+ void writeMainFragment(MainFragment fragment, js.Statement code,
+ {bool isSplit}) {
LineColumnCollector lineColumnCollector;
List<CodeOutputListener> codeOutputListeners;
if (shouldGenerateSourceMap) {
@@ -268,6 +278,7 @@
js.Program program = new js.Program([
buildGeneratedBy(),
new js.Comment(HOOKS_API_USAGE),
+ isSplit ? buildDeferredInitializerGlobal() : new js.Block.empty(),
code]);
mainOutput.addBuffer(js.prettyPrint(program, compiler,
@@ -321,6 +332,7 @@
js.Program program = new js.Program([
buildGeneratedBy(),
+ buildDeferredInitializerGlobal(),
js.js.statement('$deferredInitializersGlobal.current = #', code)]);
output.addBuffer(js.prettyPrint(program, compiler,
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index 71bfd9f..6006bc9 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -384,7 +384,21 @@
return reporter.withCurrentElement(library, () {
Uri computeUri(LibraryDependency node) {
- String tagUriString = node.uri.dartString.slowToString();
+ StringNode uriNode = node.uri;
+ if (node.conditionalUris != null) {
+ for (ConditionalUri conditionalUri in node.conditionalUris) {
+ String key = conditionalUri.key.slowNameString;
+ String value = conditionalUri.value == null
+ ? "true"
+ : conditionalUri.value.dartString.slowToString();
+ String actual = compiler.fromEnvironment(key);
+ if (value == actual) {
+ uriNode = conditionalUri.uri;
+ break;
+ }
+ }
+ }
+ String tagUriString = uriNode.dartString.slowToString();
try {
return Uri.parse(tagUriString);
} on FormatException {
@@ -610,6 +624,19 @@
if (script == null) return null;
LibraryElement element =
createLibrarySync(handler, script, resolvedUri);
+ CompilationUnitElementX compilationUnit = element.entryCompilationUnit;
+ if (compilationUnit.partTag != null) {
+ DiagnosticMessage error = reporter.withCurrentElement(
+ compilationUnit,
+ () => reporter.createMessage(
+ compilationUnit.partTag, MessageKind.IMPORT_PART_OF));
+ DiagnosticMessage info = reporter.withCurrentElement(
+ importingLibrary,
+ () => reporter.createMessage(
+ node,
+ MessageKind.IMPORT_PART_OF_HERE));
+ reporter.reportError(error, <DiagnosticMessage>[info]);
+ }
return processLibraryTags(handler, element).then((_) {
reporter.withCurrentElement(element, () {
handler.registerLibraryExports(element);
diff --git a/pkg/compiler/lib/src/parser/class_element_parser.dart b/pkg/compiler/lib/src/parser/class_element_parser.dart
index 745665d..319cba5 100644
--- a/pkg/compiler/lib/src/parser/class_element_parser.dart
+++ b/pkg/compiler/lib/src/parser/class_element_parser.dart
@@ -13,7 +13,8 @@
PartialParser;
class ClassElementParser extends PartialParser {
- ClassElementParser(Listener listener) : super(listener);
+ ClassElementParser(Listener listener)
+ : super(listener, enableConditionalDirectives: false);
Token parseClassBody(Token token) => fullParseClassBody(token);
}
diff --git a/pkg/compiler/lib/src/parser/diet_parser_task.dart b/pkg/compiler/lib/src/parser/diet_parser_task.dart
index 10a0a9f..9afc8d4 100644
--- a/pkg/compiler/lib/src/parser/diet_parser_task.dart
+++ b/pkg/compiler/lib/src/parser/diet_parser_task.dart
@@ -23,7 +23,12 @@
PartialParser;
class DietParserTask extends CompilerTask {
- DietParserTask(Compiler compiler) : super(compiler);
+ final bool _enableConditionalDirectives;
+
+ DietParserTask(Compiler compiler, {bool enableConditionalDirectives})
+ : this._enableConditionalDirectives = enableConditionalDirectives,
+ super(compiler);
+
final String name = 'Diet Parser';
dietParse(CompilationUnitElement compilationUnit, Token tokens) {
@@ -34,7 +39,8 @@
compilationUnit.library));
ElementListener listener = new ElementListener(
scannerOptions, compiler.reporter, compilationUnit, idGenerator);
- PartialParser parser = new PartialParser(listener);
+ PartialParser parser = new PartialParser(
+ listener, enableConditionalDirectives: _enableConditionalDirectives);
try {
parser.parseUnit(tokens);
} on ParserError catch(_) {
diff --git a/pkg/compiler/lib/src/parser/element_listener.dart b/pkg/compiler/lib/src/parser/element_listener.dart
index 0cdf72e..fb5314e 100644
--- a/pkg/compiler/lib/src/parser/element_listener.dart
+++ b/pkg/compiler/lib/src/parser/element_listener.dart
@@ -150,12 +150,34 @@
if (asKeyword != null) {
prefix = popNode();
}
+ NodeList conditionalUris = popNode();
StringNode uri = popLiteralString();
- addLibraryTag(new Import(importKeyword, uri, prefix, combinators,
+ addLibraryTag(new Import(importKeyword, uri, conditionalUris,
+ prefix, combinators,
popMetadata(compilationUnitElement),
isDeferred: isDeferred));
}
+ void endDottedName(int count, Token token) {
+ NodeList identifiers = makeNodeList(count, null, null, '.');
+ pushNode(new DottedName(token, identifiers));
+ }
+
+ void endConditionalUris(int count) {
+ if (count == 0) {
+ pushNode(null);
+ } else {
+ pushNode(makeNodeList(count, null, null, " "));
+ }
+ }
+
+ void endConditionalUri(Token ifToken, Token equalSign) {
+ StringNode uri = popNode();
+ LiteralString conditionValue = (equalSign != null) ? popNode() : null;
+ DottedName identifier = popNode();
+ pushNode(new ConditionalUri(ifToken, identifier, conditionValue, uri));
+ }
+
void endEnum(Token enumKeyword, Token endBrace, int count) {
NodeList names = makeNodeList(count, enumKeyword.next.next, endBrace, ",");
Identifier name = popNode();
@@ -169,8 +191,9 @@
void endExport(Token exportKeyword, Token semicolon) {
NodeList combinators = popNode();
+ NodeList conditionalUris = popNode();
StringNode uri = popNode();
- addLibraryTag(new Export(exportKeyword, uri, combinators,
+ addLibraryTag(new Export(exportKeyword, uri, conditionalUris, combinators,
popMetadata(compilationUnitElement)));
}
diff --git a/pkg/compiler/lib/src/parser/listener.dart b/pkg/compiler/lib/src/parser/listener.dart
index 6511abc..618b86a 100644
--- a/pkg/compiler/lib/src/parser/listener.dart
+++ b/pkg/compiler/lib/src/parser/listener.dart
@@ -232,6 +232,24 @@
Token asKeyword, Token semicolon) {
}
+ void beginConditionalUris(Token token) {
+ }
+
+ void endConditionalUris(int count) {
+ }
+
+ void beginConditionalUri(Token ifKeyword) {
+ }
+
+ void endConditionalUri(Token ifKeyword, Token equalitySign) {
+ }
+
+ void beginDottedName(Token token) {
+ }
+
+ void endDottedName(int count, Token firstIdentifier) {
+ }
+
void beginInitializedIdentifier(Token token) {
}
diff --git a/pkg/compiler/lib/src/parser/parser.dart b/pkg/compiler/lib/src/parser/parser.dart
index 7adddb5..f2e0577 100644
--- a/pkg/compiler/lib/src/parser/parser.dart
+++ b/pkg/compiler/lib/src/parser/parser.dart
@@ -98,11 +98,12 @@
class Parser {
final Listener listener;
bool mayParseFunctionExpressions = true;
- bool yieldIsKeyword;
- bool awaitIsKeyword;
+ final bool enableConditionalDirectives;
+ bool asyncAwaitKeywordsEnabled;
Parser(this.listener,
- {this.yieldIsKeyword: false, this.awaitIsKeyword: false});
+ {this.enableConditionalDirectives: false,
+ this.asyncAwaitKeywordsEnabled: false});
Token parseUnit(Token token) {
listener.beginCompilationUnit(token);
@@ -151,12 +152,13 @@
return token;
}
- /// import uri (as identifier)? combinator* ';'
+ /// import uri (if (test) uri)* (as identifier)? combinator* ';'
Token parseImport(Token token) {
Token importKeyword = token;
listener.beginImport(importKeyword);
assert(optional('import', token));
token = parseLiteralStringOrRecoverExpression(token.next);
+ token = parseConditionalUris(token);
Token deferredKeyword;
if (optional('deferred', token)) {
deferredKeyword = token;
@@ -174,12 +176,57 @@
return token;
}
- /// export uri combinator* ';'
+ /// if (test) uri
+ Token parseConditionalUris(Token token) {
+ listener.beginConditionalUris(token);
+ int count = 0;
+ if (enableConditionalDirectives) {
+ while (optional('if', token)) {
+ count++;
+ token = parseConditionalUri(token);
+ }
+ }
+ listener.endConditionalUris(count);
+ return token;
+ }
+
+ Token parseConditionalUri(Token token) {
+ listener.beginConditionalUri(token);
+ Token ifKeyword = token;
+ token = expect('if', token);
+ token = expect('(', token);
+ token = parseDottedName(token);
+ Token equalitySign;
+ if (optional('==', token)) {
+ equalitySign = token;
+ token = parseLiteralStringOrRecoverExpression(token.next);
+ }
+ token = expect(')', token);
+ token = parseLiteralStringOrRecoverExpression(token);
+ listener.endConditionalUri(ifKeyword, equalitySign);
+ return token;
+ }
+
+ Token parseDottedName(Token token) {
+ listener.beginDottedName(token);
+ Token firstIdentifier = token;
+ token = parseIdentifier(token);
+ int count = 1;
+ while (optional('.', token)) {
+ token = parseIdentifier(token.next);
+ count++;
+ }
+ listener.endDottedName(count, firstIdentifier);
+ return token;
+ }
+
+ /// export uri conditional-uris* combinator* ';'
Token parseExport(Token token) {
Token exportKeyword = token;
listener.beginExport(exportKeyword);
assert(optional('export', token));
token = parseLiteralStringOrRecoverExpression(token.next);
+ token = parseConditionalUris(token);
token = parseCombinators(token);
Token semicolon = token;
token = expect(';', token);
@@ -660,15 +707,27 @@
/**
* Returns true if the stringValue of the [token] is either [value1],
+ * [value2], or [value3].
+ */
+ bool isOneOf3(Token token, String value1, String value2, String value3) {
+ String stringValue = token.stringValue;
+ return
+ value1 == stringValue ||
+ value2 == stringValue ||
+ value3 == stringValue;
+ }
+
+ /**
+ * Returns true if the stringValue of the [token] is either [value1],
* [value2], [value3], or [value4].
*/
bool isOneOf4(Token token,
String value1, String value2, String value3, String value4) {
String stringValue = token.stringValue;
- return identical(value1, stringValue) ||
- identical(value2, stringValue) ||
- identical(value3, stringValue) ||
- identical(value4, stringValue);
+ return value1 == stringValue ||
+ value2 == stringValue ||
+ value3 == stringValue ||
+ value4 == stringValue;
}
bool notEofOrValue(String value, Token token) {
@@ -931,6 +990,8 @@
Token name) {
Token externalModifier;
+ // TODO(johnniwinther): Move error reporting to resolution to give more
+ // specific error messages.
for (Token modifier in modifiers) {
if (externalModifier == null && optional('external', modifier)) {
externalModifier = modifier;
@@ -954,12 +1015,10 @@
Token token = parseIdentifier(name);
token = parseFormalParametersOpt(token);
- bool previousYieldIsKeyword = yieldIsKeyword;
- bool previousAwaitIsKeyword = awaitIsKeyword;
+ bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
token = parseAsyncModifier(token);
token = parseFunctionBody(token, false, externalModifier != null);
- yieldIsKeyword = previousYieldIsKeyword;
- awaitIsKeyword = previousAwaitIsKeyword;
+ asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
Token endToken = token;
token = token.next;
if (token.kind == BAD_INPUT_TOKEN) {
@@ -1306,6 +1365,8 @@
Token constModifier;
int modifierCount = 0;
int allowedModifierCount = 1;
+ // TODO(johnniwinther): Move error reporting to resolution to give more
+ // specific error messages.
for (Token modifier in modifiers) {
if (externalModifier == null && optional('external', modifier)) {
modifierCount++;
@@ -1337,6 +1398,11 @@
modifier, MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier});
}
}
+ if (getOrSet != null && constModifier != null) {
+ listener.reportError(
+ constModifier, MessageKind.EXTRANEOUS_MODIFIER,
+ {'modifier': constModifier});
+ }
parseModifierList(modifiers);
if (type == null) {
@@ -1348,7 +1414,6 @@
if (optional('operator', name)) {
token = parseOperatorName(name);
if (staticModifier != null) {
- // TODO(ahe): Consider a more specific error message.
listener.reportError(
staticModifier, MessageKind.EXTRANEOUS_MODIFIER,
{'modifier': staticModifier});
@@ -1360,8 +1425,7 @@
token = parseQualifiedRestOpt(token);
token = parseFormalParametersOpt(token);
token = parseInitializersOpt(token);
- bool previousYieldIsKeyword = yieldIsKeyword;
- bool previousAwaitIsKeyword = awaitIsKeyword;
+ bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
token = parseAsyncModifier(token);
if (optional('=', token)) {
token = parseRedirectingFactoryBody(token);
@@ -1369,8 +1433,7 @@
token = parseFunctionBody(
token, false, staticModifier == null || externalModifier != null);
}
- yieldIsKeyword = previousYieldIsKeyword;
- awaitIsKeyword = previousAwaitIsKeyword;
+ asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
listener.endMethod(getOrSet, start, token);
return token.next;
}
@@ -1448,16 +1511,14 @@
listener.endFunctionName(token);
token = parseFormalParametersOpt(token);
token = parseInitializersOpt(token);
- bool previousYieldIsKeyword = yieldIsKeyword;
- bool previousAwaitIsKeyword = awaitIsKeyword;
+ bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
token = parseAsyncModifier(token);
if (optional('=', token)) {
token = parseRedirectingFactoryBody(token);
} else {
token = parseFunctionBody(token, false, true);
}
- yieldIsKeyword = previousYieldIsKeyword;
- awaitIsKeyword = previousAwaitIsKeyword;
+ asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
listener.endFunction(getOrSet, token);
return token.next;
}
@@ -1465,13 +1526,11 @@
Token parseUnnamedFunction(Token token) {
listener.beginUnnamedFunction(token);
token = parseFormalParameters(token);
- bool previousYieldIsKeyword = yieldIsKeyword;
- bool previousAwaitIsKeyword = awaitIsKeyword;
+ bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
token = parseAsyncModifier(token);
bool isBlock = optional('{', token);
token = parseFunctionBody(token, true, false);
- yieldIsKeyword = previousYieldIsKeyword;
- awaitIsKeyword = previousAwaitIsKeyword;
+ asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
listener.endUnnamedFunction(token);
return isBlock ? token.next : token;
}
@@ -1492,13 +1551,11 @@
listener.endFunctionName(token);
token = parseFormalParameters(token);
listener.handleNoInitializers();
- bool previousYieldIsKeyword = yieldIsKeyword;
- bool previousAwaitIsKeyword = awaitIsKeyword;
+ bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
token = parseAsyncModifier(token);
bool isBlock = optional('{', token);
token = parseFunctionBody(token, true, false);
- yieldIsKeyword = previousYieldIsKeyword;
- awaitIsKeyword = previousAwaitIsKeyword;
+ asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
listener.endFunction(null, token);
return isBlock ? token.next : token;
}
@@ -1567,14 +1624,12 @@
Token parseAsyncModifier(Token token) {
Token async;
Token star;
- awaitIsKeyword = false;
- yieldIsKeyword = false;
+ asyncAwaitKeywordsEnabled = false;
if (optional('async', token)) {
- awaitIsKeyword = true;
+ asyncAwaitKeywordsEnabled = true;
async = token;
token = token.next;
if (optional('*', token)) {
- yieldIsKeyword = true;
star = token;
token = token.next;
}
@@ -1582,7 +1637,7 @@
async = token;
token = token.next;
if (optional('*', token)) {
- yieldIsKeyword = true;
+ asyncAwaitKeywordsEnabled = true;
star = token;
token = token.next;
} else {
@@ -1606,7 +1661,7 @@
return parseVariablesDeclaration(token);
} else if (identical(value, 'if')) {
return parseIfStatement(token);
- } else if (awaitIsKeyword && identical(value, 'await')) {
+ } else if (asyncAwaitKeywordsEnabled && identical(value, 'await')) {
if (identical(token.next.stringValue, 'for')) {
return parseForStatement(token, token.next);
} else {
@@ -1637,7 +1692,7 @@
return parseAssertStatement(token);
} else if (identical(value, ';')) {
return parseEmptyStatement(token);
- } else if (yieldIsKeyword && identical(value, 'yield')) {
+ } else if (asyncAwaitKeywordsEnabled && identical(value, 'yield')) {
return parseYieldStatement(token);
} else if (identical(value, 'const')) {
return parseExpressionStatementOrConstDeclaration(token);
@@ -1919,7 +1974,7 @@
Token parseUnaryExpression(Token token, bool allowCascades) {
String value = token.stringValue;
// Prefix:
- if (awaitIsKeyword && optional('await', token)) {
+ if (asyncAwaitKeywordsEnabled && optional('await', token)) {
return parseAwaitExpression(token, allowCascades);
} else if (identical(value, '+')) {
// Dart no longer allows prefix-plus.
@@ -1970,44 +2025,47 @@
Token parsePrimary(Token token) {
final kind = token.kind;
- if (identical(kind, IDENTIFIER_TOKEN)) {
+ if (kind == IDENTIFIER_TOKEN) {
return parseSendOrFunctionLiteral(token);
- } else if (identical(kind, INT_TOKEN)
- || identical(kind, HEXADECIMAL_TOKEN)) {
+ } else if (kind == INT_TOKEN
+ || kind == HEXADECIMAL_TOKEN) {
return parseLiteralInt(token);
- } else if (identical(kind, DOUBLE_TOKEN)) {
+ } else if (kind == DOUBLE_TOKEN) {
return parseLiteralDouble(token);
- } else if (identical(kind, STRING_TOKEN)) {
+ } else if (kind == STRING_TOKEN) {
return parseLiteralString(token);
- } else if (identical(kind, HASH_TOKEN)) {
+ } else if (kind == HASH_TOKEN) {
return parseLiteralSymbol(token);
- } else if (identical(kind, KEYWORD_TOKEN)) {
+ } else if (kind == KEYWORD_TOKEN) {
final value = token.stringValue;
- if ((identical(value, 'true')) || (identical(value, 'false'))) {
+ if (value == 'true' || value == 'false') {
return parseLiteralBool(token);
- } else if (identical(value, 'null')) {
+ } else if (value == 'null') {
return parseLiteralNull(token);
- } else if (identical(value, 'this')) {
+ } else if (value == 'this') {
return parseThisExpression(token);
- } else if (identical(value, 'super')) {
+ } else if (value == 'super') {
return parseSuperExpression(token);
- } else if (identical(value, 'new')) {
+ } else if (value == 'new') {
return parseNewExpression(token);
- } else if (identical(value, 'const')) {
+ } else if (value == 'const') {
return parseConstExpression(token);
- } else if (identical(value, 'void')) {
+ } else if (value == 'void') {
return parseFunctionExpression(token);
+ } else if (asyncAwaitKeywordsEnabled &&
+ (value == 'yield' || value == 'async')) {
+ return listener.expectedExpression(token);
} else if (token.isIdentifier()) {
return parseSendOrFunctionLiteral(token);
} else {
return listener.expectedExpression(token);
}
- } else if (identical(kind, OPEN_PAREN_TOKEN)) {
+ } else if (kind == OPEN_PAREN_TOKEN) {
return parseParenthesizedExpressionOrFunctionLiteral(token);
- } else if ((identical(kind, LT_TOKEN)) ||
- (identical(kind, OPEN_SQUARE_BRACKET_TOKEN)) ||
- (identical(kind, OPEN_CURLY_BRACKET_TOKEN)) ||
- identical(token.stringValue, '[]')) {
+ } else if ((kind == LT_TOKEN) ||
+ (kind == OPEN_SQUARE_BRACKET_TOKEN) ||
+ (kind == OPEN_CURLY_BRACKET_TOKEN) ||
+ token.stringValue == '[]') {
return parseLiteralListOrMap(token);
} else {
return listener.expectedExpression(token);
@@ -2427,7 +2485,7 @@
if (identical(value, ';')) {
listener.handleNoExpression(token);
return token;
- } else if ((identical(value, 'var')) || (identical(value, 'final'))) {
+ } else if (isOneOf3(token, 'var', 'final', 'const')) {
return parseVariablesDeclarationNoSemicolon(token);
}
Token identifier = peekIdentifierAfterType(token);
diff --git a/pkg/compiler/lib/src/parser/parser_task.dart b/pkg/compiler/lib/src/parser/parser_task.dart
index 5ea0247..fa715aa 100644
--- a/pkg/compiler/lib/src/parser/parser_task.dart
+++ b/pkg/compiler/lib/src/parser/parser_task.dart
@@ -26,7 +26,13 @@
Parser;
class ParserTask extends CompilerTask {
- ParserTask(Compiler compiler) : super(compiler);
+ final bool _enableConditionalDirectives;
+
+ ParserTask(Compiler compiler,
+ {bool enableConditionalDirectives: false})
+ : this._enableConditionalDirectives = enableConditionalDirectives,
+ super(compiler);
+
String get name => 'Parser';
Node parse(ElementX element) {
@@ -37,7 +43,8 @@
return measure(() {
NodeListener listener = new NodeListener(
const ScannerOptions(), reporter, null);
- Parser parser = new Parser(listener);
+ Parser parser = new Parser(
+ listener, enableConditionalDirectives: _enableConditionalDirectives);
try {
parser.parseUnit(token);
} on ParserError catch(_) {
diff --git a/pkg/compiler/lib/src/parser/partial_parser.dart b/pkg/compiler/lib/src/parser/partial_parser.dart
index 01de07c..1c7722f 100644
--- a/pkg/compiler/lib/src/parser/partial_parser.dart
+++ b/pkg/compiler/lib/src/parser/partial_parser.dart
@@ -20,7 +20,9 @@
Parser;
class PartialParser extends Parser {
- PartialParser(Listener listener) : super(listener);
+ PartialParser(Listener listener, {bool enableConditionalDirectives})
+ : super(listener,
+ enableConditionalDirectives: enableConditionalDirectives);
Token parseClassBody(Token token) => skipClassBody(token);
diff --git a/pkg/compiler/lib/src/patch_parser.dart b/pkg/compiler/lib/src/patch_parser.dart
index 4edabb3..593b08f 100644
--- a/pkg/compiler/lib/src/patch_parser.dart
+++ b/pkg/compiler/lib/src/patch_parser.dart
@@ -159,8 +159,11 @@
class PatchParserTask extends CompilerTask {
final String name = "Patching Parser";
+ final bool _enableConditionalDirectives;
- PatchParserTask(Compiler compiler): super(compiler);
+ PatchParserTask(Compiler compiler, {bool enableConditionalDirectives})
+ : this._enableConditionalDirectives = enableConditionalDirectives,
+ super(compiler);
/**
* Scans a library patch file, applies the method patches and
@@ -195,7 +198,9 @@
compilationUnit,
idGenerator);
try {
- new PartialParser(patchListener).parseUnit(tokens);
+ new PartialParser(patchListener,
+ enableConditionalDirectives: _enableConditionalDirectives)
+ .parseUnit(tokens);
} on ParserError catch (e) {
// No need to recover from a parser error in platform libraries, user
// will never see this if the libraries are tested correctly.
@@ -212,7 +217,8 @@
measure(() => reporter.withCurrentElement(cls, () {
MemberListener listener = new PatchMemberListener(compiler, cls);
- Parser parser = new PatchClassElementParser(listener);
+ Parser parser = new PatchClassElementParser(
+ listener, enableConditionalDirectives: _enableConditionalDirectives);
try {
Token token = parser.parseTopLevelDeclaration(cls.beginToken);
assert(identical(token, cls.endToken.next));
@@ -264,7 +270,9 @@
* declarations.
*/
class PatchClassElementParser extends PartialParser {
- PatchClassElementParser(Listener listener) : super(listener);
+ PatchClassElementParser(Listener listener, {bool enableConditionalDirectives})
+ : super(listener,
+ enableConditionalDirectives: enableConditionalDirectives);
Token parseClassBody(Token token) => fullParseClassBody(token);
}
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
index 26e7b48b..ce4e93c 100644
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ b/pkg/compiler/lib/src/resolution/constructors.dart
@@ -485,18 +485,19 @@
MessageKind kind,
Map arguments,
{bool isError: false,
- bool missingConstructor: false}) {
+ bool missingConstructor: false,
+ List<DiagnosticMessage> infos: const <DiagnosticMessage>[]}) {
if (missingConstructor) {
registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
} else {
registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
}
+ DiagnosticMessage message =
+ reporter.createMessage(diagnosticNode, kind, arguments);
if (isError || inConstContext) {
- reporter.reportErrorMessage(
- diagnosticNode, kind, arguments);
+ reporter.reportError(message, infos);
} else {
- reporter.reportWarningMessage(
- diagnosticNode, kind, arguments);
+ reporter.reportWarning(message, infos);
}
ErroneousElement error = new ErroneousConstructorElementX(
kind, arguments, name, enclosing);
@@ -616,8 +617,7 @@
if (send != null) {
// The type name is of the form [: prefix . identifier :].
String name = send.receiver.asIdentifier().source;
- Element element = resolver.reportLookupErrorIfAny(
- lookupInScope(reporter, send, resolver.scope, name), node, name);
+ Element element = lookupInScope(reporter, send, resolver.scope, name);
if (element != null && element.isPrefix) {
prefix = element;
}
@@ -666,10 +666,8 @@
ConstructorResult visitIdentifier(Identifier node) {
String name = node.source;
- Element element = resolver.reportLookupErrorIfAny(
- lookupInScope(reporter, node, resolver.scope, name), node, name);
+ Element element = lookupInScope(reporter, node, resolver.scope, name);
registry.useElement(node, element);
- // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1.
return constructorResultForElement(node, name, element);
}
@@ -691,6 +689,15 @@
resolver.enclosingElement, name,
MessageKind.CANNOT_RESOLVE,
{'name': name});
+ } else if (element.isAmbiguous) {
+ AmbiguousElement ambiguous = element;
+ return reportAndCreateErroneousConstructorElement(
+ node,
+ ConstructorResultKind.INVALID_TYPE, null,
+ resolver.enclosingElement, name,
+ ambiguous.messageKind,
+ ambiguous.messageArguments,
+ infos: ambiguous.computeInfos(resolver.enclosingElement, reporter));
} else if (element.isMalformed) {
return constructorResultForErroneous(node, element);
} else if (element.isClass) {
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index c41d5a1..8426021 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -126,7 +126,7 @@
/// When visiting the type declaration of the variable in a [ForIn] loop,
/// the initializer of the variable is implicit and we should not emit an
/// error when verifying that all final variables are initialized.
- bool allowFinalWithoutInitializer = false;
+ bool inLoopVariable = false;
/// The nodes for which variable access and mutation must be registered in
/// order to determine when the static type of variables types is promoted.
@@ -3687,8 +3687,14 @@
}
ResolutionResult visitYield(Yield node) {
- coreClasses.streamClass.ensureResolved(resolution);
- coreClasses.iterableClass.ensureResolved(resolution);
+ if (!currentAsyncMarker.isYielding) {
+ reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD);
+ }
+ if (currentAsyncMarker.isAsync) {
+ coreClasses.streamClass.ensureResolved(resolution);
+ } else {
+ coreClasses.iterableClass.ensureResolved(resolution);
+ }
visit(node.expression);
return const NoneResult();
}
@@ -3825,6 +3831,9 @@
}
ResolutionResult visitAwait(Await node) {
+ if (!currentAsyncMarker.isAsync) {
+ reporter.reportErrorMessage(node, MessageKind.INVALID_AWAIT);
+ }
coreClasses.futureClass.ensureResolved(resolution);
visit(node.expression);
return const NoneResult();
@@ -4350,6 +4359,10 @@
}
ResolutionResult visitAsyncForIn(AsyncForIn node) {
+ if (!currentAsyncMarker.isAsync) {
+ reporter.reportErrorMessage(
+ node.awaitToken, MessageKind.INVALID_AWAIT_FOR_IN);
+ }
registry.registerFeature(Feature.ASYNC_FOR_IN);
registry.registerDynamicUse(
new DynamicUse(Selectors.current, null));
@@ -4387,10 +4400,10 @@
Scope blockScope) {
LibraryElement library = enclosingElement.library;
- bool oldAllowFinalWithoutInitializer = allowFinalWithoutInitializer;
- allowFinalWithoutInitializer = true;
+ bool oldAllowFinalWithoutInitializer = inLoopVariable;
+ inLoopVariable = true;
visitIn(declaration, blockScope);
- allowFinalWithoutInitializer = oldAllowFinalWithoutInitializer;
+ inLoopVariable = oldAllowFinalWithoutInitializer;
Send send = declaration.asSend();
VariableDefinitions variableDefinitions =
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index 4490b88..737b5f0 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -21,6 +21,11 @@
Compiler;
import '../compile_time_constants.dart' show
ConstantCompiler;
+import '../constants/expressions.dart' show
+ ConstantExpression,
+ ConstantExpressionKind,
+ ConstructedConstantExpression,
+ ErroneousConstantExpression;
import '../constants/values.dart' show
ConstantValue;
import '../core_types.dart' show
@@ -856,7 +861,7 @@
if (lookupElement == null) {
reporter.internalError(member,
"No abstract field for accessor");
- } else if (!identical(lookupElement.kind, ElementKind.ABSTRACT_FIELD)) {
+ } else if (!lookupElement.isAbstractField) {
if (lookupElement.isMalformed || lookupElement.isAmbiguous) return;
reporter.internalError(member,
"Inaccessible abstract field for accessor");
@@ -869,14 +874,14 @@
if (setter == null) return;
int getterFlags = getter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
int setterFlags = setter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
- if (!identical(getterFlags, setterFlags)) {
+ if (getterFlags != setterFlags) {
final mismatchedFlags =
new Modifiers.withFlags(null, getterFlags ^ setterFlags);
- reporter.reportErrorMessage(
+ reporter.reportWarningMessage(
field.getter,
MessageKind.GETTER_MISMATCH,
{'modifiers': mismatchedFlags});
- reporter.reportErrorMessage(
+ reporter.reportWarningMessage(
field.setter,
MessageKind.SETTER_MISMATCH,
{'modifiers': mismatchedFlags});
@@ -1061,8 +1066,29 @@
node.accept(visitor);
// TODO(johnniwinther): Avoid passing the [TreeElements] to
// [compileMetadata].
- annotation.constant =
- constantCompiler.compileMetadata(annotation, node, registry.mapping);
+ ConstantExpression constant = constantCompiler.compileMetadata(
+ annotation, node, registry.mapping);
+ switch (constant.kind) {
+ case ConstantExpressionKind.CONSTRUCTED:
+ ConstructedConstantExpression constructedConstant = constant;
+ if (constructedConstant.type.isGeneric) {
+ // Const constructor calls cannot have type arguments.
+ // TODO(24312): Remove this.
+ reporter.reportErrorMessage(
+ node, MessageKind.INVALID_METADATA_GENERIC);
+ constant = new ErroneousConstantExpression();
+ }
+ break;
+ case ConstantExpressionKind.VARIABLE:
+ case ConstantExpressionKind.ERRONEOUS:
+ break;
+ default:
+ reporter.reportErrorMessage(node, MessageKind.INVALID_METADATA);
+ constant = new ErroneousConstantExpression();
+ break;
+ }
+ annotation.constant = constant;
+
constantCompiler.evaluate(annotation.constant);
// TODO(johnniwinther): Register the relation between the annotation
// and the annotated element instead. This will allow the backend to
diff --git a/pkg/compiler/lib/src/resolution/variables.dart b/pkg/compiler/lib/src/resolution/variables.dart
index 6f22eed..aec67f3 100644
--- a/pkg/compiler/lib/src/resolution/variables.dart
+++ b/pkg/compiler/lib/src/resolution/variables.dart
@@ -60,11 +60,16 @@
registry.registerTypeUse(
new TypeUse.instantiation(compiler.coreTypes.nullType));
if (definitions.modifiers.isConst) {
- reporter.reportErrorMessage(
- node, MessageKind.CONST_WITHOUT_INITIALIZER);
+ if (resolver.inLoopVariable) {
+ reporter.reportErrorMessage(
+ node, MessageKind.CONST_LOOP_VARIABLE);
+ } else {
+ reporter.reportErrorMessage(
+ node, MessageKind.CONST_WITHOUT_INITIALIZER);
+ }
}
if (definitions.modifiers.isFinal &&
- !resolver.allowFinalWithoutInitializer) {
+ !resolver.inLoopVariable) {
reporter.reportErrorMessage(
node, MessageKind.FINAL_WITHOUT_INITIALIZER);
}
diff --git a/pkg/compiler/lib/src/tree/nodes.dart b/pkg/compiler/lib/src/tree/nodes.dart
index 7ef28dc..04d46f5 100644
--- a/pkg/compiler/lib/src/tree/nodes.dart
+++ b/pkg/compiler/lib/src/tree/nodes.dart
@@ -22,7 +22,9 @@
R visitClassNode(ClassNode node) => visitNode(node);
R visitCombinator(Combinator node) => visitNode(node);
R visitConditional(Conditional node) => visitExpression(node);
+ R visitConditionalUri(ConditionalUri node) => visitNode(node);
R visitContinueStatement(ContinueStatement node) => visitGotoStatement(node);
+ R visitDottedName(DottedName node) => visitExpression(node);
R visitDoWhile(DoWhile node) => visitLoop(node);
R visitEmptyStatement(EmptyStatement node) => visitStatement(node);
R visitEnum(Enum node) => visitNode(node);
@@ -34,8 +36,8 @@
R visitFunctionExpression(FunctionExpression node) => visitExpression(node);
R visitGotoStatement(GotoStatement node) => visitStatement(node);
R visitIdentifier(Identifier node) => visitExpression(node);
- R visitIf(If node) => visitStatement(node);
R visitImport(Import node) => visitLibraryDependency(node);
+ R visitIf(If node) => visitStatement(node);
R visitLabel(Label node) => visitNode(node);
R visitLabeledStatement(LabeledStatement node) => visitStatement(node);
R visitLibraryDependency(LibraryDependency node) => visitLibraryTag(node);
@@ -159,7 +161,9 @@
ClassNode asClassNode() => null;
Combinator asCombinator() => null;
Conditional asConditional() => null;
+ ConditionalUri asConditionalUri() => null;
ContinueStatement asContinueStatement() => null;
+ DottedName asDottedName() => null;
DoWhile asDoWhile() => null;
EmptyStatement asEmptyStatement() => null;
Enum asEnum() => null;
@@ -1022,6 +1026,7 @@
class LiteralSymbol extends Expression {
final Token hashToken;
+ // TODO: this could be a DottedNamed.
final NodeList identifiers;
LiteralSymbol(this.hashToken, this.identifiers);
@@ -1067,6 +1072,32 @@
Token getEndToken() => token;
}
+// TODO(floitsch): a dotted identifier isn't really an expression. Should it
+// inherit from Node instead?
+class DottedName extends Expression {
+ final Token token;
+ final NodeList identifiers;
+
+ DottedName(this.token, this.identifiers);
+
+ DottedName asDottedName() => this;
+
+ void visitChildren(Visitor visitor) {
+ identifiers.accept(visitor);
+ }
+
+ accept(Visitor visitor) => visitor.visitDottedName(this);
+
+ Token getBeginToken() => token;
+ Token getEndToken() => identifiers.getEndToken();
+
+ String get slowNameString {
+ Unparser unparser = new Unparser();
+ unparser.unparseNodeListOfIdentifiers(identifiers);
+ return unparser.result;
+ }
+}
+
class Operator extends Identifier {
static const COMPLEX_OPERATORS =
const ["--", "++", '+=', "-=", "*=", "/=", "%=", "&=", "|=", "~/=", "^=",
@@ -1964,14 +1995,18 @@
*/
abstract class LibraryDependency extends LibraryTag {
final StringNode uri;
+ final NodeList conditionalUris;
final NodeList combinators;
LibraryDependency(this.uri,
+ this.conditionalUris,
this.combinators,
List<MetadataAnnotation> metadata)
: super(metadata);
LibraryDependency asLibraryDependency() => this;
+
+ bool get hasConditionalUris => conditionalUris != null;
}
/**
@@ -1986,11 +2021,11 @@
final Token importKeyword;
final bool isDeferred;
- Import(this.importKeyword, StringNode uri,
+ Import(this.importKeyword, StringNode uri, NodeList conditionalUris,
this.prefix, NodeList combinators,
List<MetadataAnnotation> metadata,
{this.isDeferred})
- : super(uri, combinators, metadata);
+ : super(uri, conditionalUris, combinators, metadata);
bool get isImport => true;
@@ -2009,11 +2044,45 @@
Token getEndToken() {
if (combinators != null) return combinators.getEndToken().next;
if (prefix != null) return prefix.getEndToken().next;
+ if (conditionalUris != null) return conditionalUris.getEndToken().next;
return uri.getEndToken().next;
}
}
/**
+ * A conditional uri inside an import or export clause.
+ *
+ * Example:
+ *
+ * import 'foo.dart'
+ * if (some.condition == "someValue") 'bar.dart'
+ * if (other.condition) 'gee.dart';
+ */
+class ConditionalUri extends Node {
+ final Token ifToken;
+ final DottedName key;
+ // Value may be null.
+ final LiteralString value;
+ final StringNode uri;
+
+ ConditionalUri(this.ifToken, this.key, this.value, this.uri);
+
+ ConditionalUri asConditionalUri() => this;
+
+ accept(Visitor visitor) => visitor.visitConditionalUri(this);
+
+ visitChildren(Visitor visitor) {
+ key.accept(visitor);
+ if (value != null) value.accept(visitor);
+ uri.accept(visitor);
+ }
+
+ Token getBeginToken() => ifToken;
+
+ Token getEndToken() => uri.getEndToken();
+}
+
+/**
* An `enum` declaration.
*
* An `enum` defines a number of named constants inside a non-extensible class
@@ -2052,9 +2121,10 @@
Export(this.exportKeyword,
StringNode uri,
+ NodeList conditionalUris,
NodeList combinators,
List<MetadataAnnotation> metadata)
- : super(uri, combinators, metadata);
+ : super(uri, conditionalUris, combinators, metadata);
bool get isExport => true;
@@ -2071,6 +2141,7 @@
Token getEndToken() {
if (combinators != null) return combinators.getEndToken().next;
+ if (conditionalUris != null) return conditionalUris.getEndToken().next;
return uri.getEndToken().next;
}
}
diff --git a/pkg/compiler/lib/src/tree/prettyprint.dart b/pkg/compiler/lib/src/tree/prettyprint.dart
index 5096e74..552747e 100644
--- a/pkg/compiler/lib/src/tree/prettyprint.dart
+++ b/pkg/compiler/lib/src/tree/prettyprint.dart
@@ -88,10 +88,20 @@
visitNodeWithChildren(node, "Conditional");
}
+ visitConditionalUri(ConditionalUri node) {
+ visitNodeWithChildren(node, "ConditionalUri");
+ }
+
visitContinueStatement(ContinueStatement node) {
visitNodeWithChildren(node, "ContinueStatement");
}
+ visitDottedName(DottedName node) {
+ openNode(node, "DottedName");
+ visitChildNode(node.identifiers, "identifiers");
+ closeNode();
+ }
+
visitDoWhile(DoWhile node) {
visitNodeWithChildren(node, "DoWhile");
}
@@ -380,6 +390,9 @@
visitExport(Export node) {
openNode(node, "Export");
visitChildNode(node.uri, "uri");
+ if (node.conditionalUris != null) {
+ visitChildNode(node.conditionalUris, "conditionalUris");
+ }
visitChildNode(node.combinators, "combinators");
closeNode();
}
@@ -388,6 +401,9 @@
openNode(node, "Import", {
"isDeferred" : "${node.isDeferred}"});
visitChildNode(node.uri, "uri");
+ if (node.conditionalUris != null) {
+ visitChildNode(node.conditionalUris, "conditionalUris");
+ }
visitChildNode(node.combinators, "combinators");
if (node.prefix != null) {
visitChildNode(node.prefix, "prefix");
diff --git a/pkg/compiler/lib/src/tree/unparser.dart b/pkg/compiler/lib/src/tree/unparser.dart
index 6f141fd..807ea05 100644
--- a/pkg/compiler/lib/src/tree/unparser.dart
+++ b/pkg/compiler/lib/src/tree/unparser.dart
@@ -782,9 +782,33 @@
newline();
}
+ visitConditionalUri(ConditionalUri node) {
+ write(node.ifToken.value);
+ space();
+ write('(');
+ visit(node.key);
+ if (node.value != null) {
+ space();
+ write("==");
+ space();
+ visit(node.value);
+ }
+ write(")");
+ space();
+ visit(node.uri);
+ }
+
+ visitDottedName(DottedName node) {
+ unparseNodeListOfIdentifiers(node.identifiers);
+ }
+
visitImport(Import node) {
addToken(node.importKeyword);
visit(node.uri);
+ if (node.hasConditionalUris) {
+ write(' ');
+ visitNodeList(node.conditionalUris);
+ }
if (node.isDeferred) {
write(' deferred');
}
@@ -803,6 +827,10 @@
visitExport(Export node) {
addToken(node.exportKeyword);
visit(node.uri);
+ if (node.hasConditionalUris) {
+ write(' ');
+ visitNodeList(node.conditionalUris);
+ }
if (node.combinators != null) {
write(' ');
visit(node.combinators);
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
index 6667ded..ecdbccb 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
@@ -8,6 +8,7 @@
import '../tree_ir_nodes.dart';
import '../../io/source_information.dart';
import '../../elements/elements.dart';
+import '../../js/placeholder_safety.dart';
/**
* Translates to direct-style.
@@ -1140,13 +1141,24 @@
}
void handleForeignCode(ForeignCode node) {
- // Arguments will get inserted in a JS code template. The arguments will
- // not always be evaluated (e.g. if the template is '# && #').
- // TODO(asgerf): We could analyze the JS AST to see if arguments are
- // definitely evaluated left-to-right.
+ // Some arguments will get inserted in a JS code template. The arguments
+ // will not always be evaluated (e.g. the second placeholder in the template
+ // '# && #').
+
+ // TODO(sra): Find out which tree_ir expressions are not nullable. It helps
+ // a lot with templates like '#.push(#)'.
+ bool isNullable(e) => true;
+
+ int safeArguments =
+ PlaceholderSafetyAnalysis.analyze(node.codeTemplate.ast, isNullable);
inEmptyEnvironment(() {
- _rewriteList(node.arguments);
+ for (int i = node.arguments.length - 1; i >= safeArguments; --i) {
+ node.arguments[i] = visitExpression(node.arguments[i]);
+ }
});
+ for (int i = safeArguments - 1; i >= 0; --i) {
+ node.arguments[i] = visitExpression(node.arguments[i]);
+ }
}
@override
diff --git a/pkg/compiler/lib/src/types/abstract_value_domain.dart b/pkg/compiler/lib/src/types/abstract_value_domain.dart
index 14c9939..6512c5a 100644
--- a/pkg/compiler/lib/src/types/abstract_value_domain.dart
+++ b/pkg/compiler/lib/src/types/abstract_value_domain.dart
@@ -161,4 +161,9 @@
/// The length property of [value], or `null` if unknown.
int getContainerLength(AbstractValue value);
-}
\ No newline at end of file
+
+ /// Returns the type of the entry of [container] at a given index.
+ /// Returns `null` if unknown.
+ AbstractValue indexWithConstant(AbstractValue container,
+ ConstantValue indexValue);
+}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 2160dd9..ff080b5 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -121,6 +121,8 @@
[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
compiler/samples/compile_loop/compile_loop: CompileTimeError # Issue 16524
+lookup_map/test/version_check_test: StaticWarning # https://github.com/dart-lang/http_parser/issues/6
+lookup_map/test/lookup_map_test: StaticWarning # https://github.com/dart-lang/http_parser/issues/6
[ $compiler == dart2js && $csp ]
# This test cannot run under CSP because it is injecting a JavaScript polyfill
diff --git a/pkg/pkg_files.gyp b/pkg/pkg_files.gyp
index 78a751f..afb09cf 100644
--- a/pkg/pkg_files.gyp
+++ b/pkg/pkg_files.gyp
@@ -4,10 +4,13 @@
{
'targets': [
- # Other targets depend on pkg files, but have to many inputs, which causes
+ # Other targets depend on pkg files, but have too many inputs, which causes
# issues on some platforms.
# This target lists all the files in pkg and third_party/pkg,
- # and creates a single pkg_files.stamp
+ # and creates the timestamp pkg_files.stamp, which depends on some
+ # intermediate helper timestamps.
+ # We split third_party/pkg up into three groups, based on the last
+ # character before .dart at the end of the filename.
{
'target_name': 'pkg_files_stamp',
'type': 'none',
@@ -17,7 +20,9 @@
'inputs': [
'../tools/create_timestamp_file.py',
'<!@(["python", "../tools/list_files.py", "\\.dart$", "."])',
- '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files.stamp',
+ '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_1.stamp',
+ '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_2.stamp',
+ '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_3.stamp',
],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/pkg_files.stamp',
@@ -28,15 +33,47 @@
],
},
{
- 'action_name': 'make_third_party_pkg_files_stamp',
+ 'action_name': 'make_third_party_pkg_files_1_stamp',
'inputs': [
'../tools/create_timestamp_file.py',
'<!@(["python", "../tools/list_files.py",'
- '"^(?!.*_test.dart).*dart$",'
+ '"^(?!.*_test\.dart).*[a-k]\.dart$",'
'"../third_party/pkg"])',
],
'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files.stamp',
+ '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_1.stamp',
+ ],
+ 'action': [
+ 'python', '../tools/create_timestamp_file.py',
+ '<@(_outputs)',
+ ],
+ },
+ {
+ 'action_name': 'make_third_party_pkg_files_2_stamp',
+ 'inputs': [
+ '../tools/create_timestamp_file.py',
+ '<!@(["python", "../tools/list_files.py",'
+ '"^(?!.*_test\.dart).*[l-r]\.dart$",'
+ '"../third_party/pkg"])',
+ ],
+ 'outputs': [
+ '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_2.stamp',
+ ],
+ 'action': [
+ 'python', '../tools/create_timestamp_file.py',
+ '<@(_outputs)',
+ ],
+ },
+ {
+ 'action_name': 'make_third_party_pkg_files_3_stamp',
+ 'inputs': [
+ '../tools/create_timestamp_file.py',
+ '<!@(["python", "../tools/list_files.py",'
+ '"^(?!.*_test\.dart).*[^a-r]\.dart$",'
+ '"../third_party/pkg"])',
+ ],
+ 'outputs': [
+ '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_3.stamp',
],
'action': [
'python', '../tools/create_timestamp_file.py',
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index 5ae31ae..7088bed 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -396,6 +396,7 @@
void _handlePackagesReply(msg) {
// Make sure to close the _packagePort before any other action.
_packagesPort.close();
+ _packagesPort = null;
if (_traceLoading) {
_log("Got packages reply: $msg");
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 29485e2..f8ef12f 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -882,15 +882,6 @@
"--version\n"
" Print the VM version.\n"
"\n"
-"--debug[:<port number>]\n"
-" enables debugging and listens on specified port for debugger connections\n"
-" (default port number is 5858)\n"
-"\n"
-"--break-at=<location>\n"
-" sets a breakpoint at specified location where <location> is one of :\n"
-" url:<line_num> e.g. test.dart:10\n"
-" [<class_name>.]<function_name> e.g. B.foo\n"
-"\n"
"--snapshot=<file_name>\n"
" loads Dart script and generates a snapshot in the specified file\n"
"\n"
diff --git a/runtime/bin/vmservice/vmservice_io.dart b/runtime/bin/vmservice/vmservice_io.dart
index 987af55..3816aa2 100644
--- a/runtime/bin/vmservice/vmservice_io.dart
+++ b/runtime/bin/vmservice/vmservice_io.dart
@@ -28,7 +28,17 @@
// HTTP server.
Server server;
Future<Server> serverFuture;
-HashMap<String, Asset> assets;
+HashMap<String, Asset> _assets;
+HashMap<String, Asset> get assets {
+ if (_assets == null) {
+ try {
+ _assets = Asset.request();
+ } catch (e) {
+ print('Could not load Observatory assets: $e');
+ }
+ }
+ return _assets;
+}
_onShutdown() {
if (server != null) {
@@ -43,11 +53,6 @@
}
_bootServer() {
- try {
- assets = Asset.request();
- } catch (e) {
- print('Could not load Observatory assets: $e');
- }
// Lazily create service.
var service = new VMService();
service.onShutdown = _onShutdown;
diff --git a/runtime/lib/date.cc b/runtime/lib/date.cc
index 67891b9..cf92809 100644
--- a/runtime/lib/date.cc
+++ b/runtime/lib/date.cc
@@ -14,7 +14,7 @@
static int32_t kMaxAllowedSeconds = 2100000000;
-DEFINE_NATIVE_ENTRY(DateNatives_timeZoneName, 1) {
+DEFINE_NATIVE_ENTRY(DateTime_timeZoneName, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(
Integer, dart_seconds, arguments->NativeArgAt(0));
int64_t seconds = dart_seconds.AsInt64Value();
@@ -26,7 +26,7 @@
}
-DEFINE_NATIVE_ENTRY(DateNatives_timeZoneOffsetInSeconds, 1) {
+DEFINE_NATIVE_ENTRY(DateTime_timeZoneOffsetInSeconds, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(
Integer, dart_seconds, arguments->NativeArgAt(0));
int64_t seconds = dart_seconds.AsInt64Value();
@@ -38,14 +38,14 @@
}
-DEFINE_NATIVE_ENTRY(DateNatives_localTimeZoneAdjustmentInSeconds, 0) {
+DEFINE_NATIVE_ENTRY(DateTime_localTimeZoneAdjustmentInSeconds, 0) {
int adjustment = OS::GetLocalTimeZoneAdjustmentInSeconds();
return Integer::New(adjustment);
}
-DEFINE_NATIVE_ENTRY(DateNatives_currentTimeMillis, 0) {
- return Integer::New(OS::GetCurrentTimeMillis());
+DEFINE_NATIVE_ENTRY(DateTime_currentTimeMicros, 0) {
+ return Integer::New(OS::GetCurrentTimeMicros());
}
} // namespace dart
diff --git a/runtime/lib/date_patch.dart b/runtime/lib/date_patch.dart
index 6c5c0c2..4697901 100644
--- a/runtime/lib/date_patch.dart
+++ b/runtime/lib/date_patch.dart
@@ -7,28 +7,39 @@
patch class DateTime {
// Natives.
// The natives have been moved up here to work around Issue 10401.
- static int _getCurrentMs() native "DateNatives_currentTimeMillis";
+ static int _getCurrentMicros() native "DateTime_currentTimeMicros";
static String _timeZoneNameForClampedSeconds(int secondsSinceEpoch)
- native "DateNatives_timeZoneName";
+ native "DateTime_timeZoneName";
static int _timeZoneOffsetInSecondsForClampedSeconds(int secondsSinceEpoch)
- native "DateNatives_timeZoneOffsetInSeconds";
+ native "DateTime_timeZoneOffsetInSeconds";
static int _localTimeZoneAdjustmentInSeconds()
- native "DateNatives_localTimeZoneAdjustmentInSeconds";
+ native "DateTime_localTimeZoneAdjustmentInSeconds";
- static const _MILLISECOND_INDEX = 0;
- static const _SECOND_INDEX = 1;
- static const _MINUTE_INDEX = 2;
- static const _HOUR_INDEX = 3;
- static const _DAY_INDEX = 4;
- static const _WEEKDAY_INDEX = 5;
- static const _MONTH_INDEX = 6;
- static const _YEAR_INDEX = 7;
+ static const _MICROSECOND_INDEX = 0;
+ static const _MILLISECOND_INDEX = 1;
+ static const _SECOND_INDEX = 2;
+ static const _MINUTE_INDEX = 3;
+ static const _HOUR_INDEX = 4;
+ static const _DAY_INDEX = 5;
+ static const _WEEKDAY_INDEX = 6;
+ static const _MONTH_INDEX = 7;
+ static const _YEAR_INDEX = 8;
List __parts;
+ /* patch */ DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
+ {bool isUtc: false})
+ : this._withValue(
+ millisecondsSinceEpoch * Duration.MICROSECONDS_PER_MILLISECOND,
+ isUtc: isUtc);
+
+ /* patch */ DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch,
+ {bool isUtc: false})
+ : this._withValue(microsecondsSinceEpoch, isUtc: isUtc);
+
/* patch */ DateTime._internal(int year,
int month,
int day,
@@ -36,27 +47,29 @@
int minute,
int second,
int millisecond,
+ int microsecond,
bool isUtc)
: this.isUtc = isUtc,
- this.millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch(
- year, month, day, hour, minute, second, millisecond, isUtc) {
- if (millisecondsSinceEpoch == null) throw new ArgumentError();
+ this._value = _brokenDownDateToValue(
+ year, month, day, hour, minute, second, millisecond, microsecond,
+ isUtc) {
+ if (_value == null) throw new ArgumentError();
if (isUtc == null) throw new ArgumentError();
}
/* patch */ DateTime._now()
: isUtc = false,
- millisecondsSinceEpoch = _getCurrentMs() {
+ _value = _getCurrentMicros() {
}
/* patch */ String get timeZoneName {
if (isUtc) return "UTC";
- return _timeZoneName(millisecondsSinceEpoch);
+ return _timeZoneName(microsecondsSinceEpoch);
}
/* patch */ Duration get timeZoneOffset {
if (isUtc) return new Duration();
- int offsetInSeconds = _timeZoneOffsetInSeconds(millisecondsSinceEpoch);
+ int offsetInSeconds = _timeZoneOffsetInSeconds(microsecondsSinceEpoch);
return new Duration(seconds: offsetInSeconds);
}
@@ -66,7 +79,7 @@
const [const [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
const [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]];
- static List _computeUpperPart(int localMs) {
+ static List _computeUpperPart(int localMicros) {
const int DAYS_IN_4_YEARS = 4 * 365 + 1;
const int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1;
const int DAYS_IN_400_YEARS = 4 * DAYS_IN_100_YEARS + 1;
@@ -80,8 +93,8 @@
int resultDay = 0;
// Always round down.
- final int daysSince1970 = _flooredDivision(localMs,
- Duration.MILLISECONDS_PER_DAY);
+ final int daysSince1970 = _flooredDivision(localMicros,
+ Duration.MICROSECONDS_PER_DAY);
int days = daysSince1970;
days += DAYS_OFFSET;
resultYear = 400 * (days ~/ DAYS_IN_400_YEARS) - YEARS_OFFSET;
@@ -110,16 +123,20 @@
}
resultDay = days - daysUntilMonth[resultMonth - 1] + 1;
- int resultMillisecond = localMs % Duration.MILLISECONDS_PER_SECOND;
+ int resultMicrosecond = localMicros % Duration.MICROSECONDS_PER_MILLISECOND;
+ int resultMillisecond =
+ _flooredDivision(localMicros, Duration.MICROSECONDS_PER_MILLISECOND) %
+ Duration.MILLISECONDS_PER_SECOND;
int resultSecond =
- _flooredDivision(localMs, Duration.MILLISECONDS_PER_SECOND) %
+ _flooredDivision(localMicros, Duration.MICROSECONDS_PER_SECOND) %
Duration.SECONDS_PER_MINUTE;
- int resultMinute = _flooredDivision(localMs,
- Duration.MILLISECONDS_PER_MINUTE);
+ int resultMinute = _flooredDivision(localMicros,
+ Duration.MICROSECONDS_PER_MINUTE);
resultMinute %= Duration.MINUTES_PER_HOUR;
- int resultHour = _flooredDivision(localMs, Duration.MILLISECONDS_PER_HOUR);
+ int resultHour =
+ _flooredDivision(localMicros, Duration.MICROSECONDS_PER_HOUR);
resultHour %= Duration.HOURS_PER_DAY;
// In accordance with ISO 8601 a week
@@ -129,6 +146,7 @@
DateTime.DAYS_PER_WEEK) + DateTime.MONDAY;
List list = new List(_YEAR_INDEX + 1);
+ list[_MICROSECOND_INDEX] = resultMicrosecond;
list[_MILLISECOND_INDEX] = resultMillisecond;
list[_SECOND_INDEX] = resultSecond;
list[_MINUTE_INDEX] = resultMinute;
@@ -142,11 +160,32 @@
get _parts {
if (__parts == null) {
- __parts = _computeUpperPart(_localDateInUtcMs);
+ __parts = _computeUpperPart(_localDateInUtcMicros);
}
return __parts;
}
+ /* patch */ DateTime add(Duration duration) {
+ return new DateTime._withValue(
+ _value + duration.inMicroseconds, isUtc: isUtc);
+ }
+
+ /* patch */ DateTime subtract(Duration duration) {
+ return new DateTime._withValue(
+ _value - duration.inMicroseconds, isUtc: isUtc);
+ }
+
+ /* patch */ Duration difference(DateTime other) {
+ return new Duration(microseconds: _value - other._value);
+ }
+
+ /* patch */ int get millisecondsSinceEpoch =>
+ _value ~/ Duration.MICROSECONDS_PER_MILLISECOND;
+
+ /* patch */ int get microsecondsSinceEpoch => _value;
+
+ /* patch */ int get microsecond => _parts[_MICROSECOND_INDEX];
+
/* patch */ int get millisecond => _parts[_MILLISECOND_INDEX];
/* patch */ int get second => _parts[_SECOND_INDEX];
@@ -164,26 +203,26 @@
/* patch */ int get year => _parts[_YEAR_INDEX];
/**
- * Returns the amount of milliseconds in UTC that represent the same values
+ * Returns the amount of microseconds in UTC that represent the same values
* as [this].
*
- * Say [:t:] is the result of this function, then
- * * [:this.year == new DateTime.fromMillisecondsSinceEpoch(t, true).year:],
- * * [:this.month == new DateTime.fromMillisecondsSinceEpoch(t, true).month:],
- * * [:this.day == new DateTime.fromMillisecondsSinceEpoch(t, true).day:],
- * * [:this.hour == new DateTime.fromMillisecondsSinceEpoch(t, true).hour:],
+ * Say `t` is the result of this function, then
+ * * `this.year == new DateTime.fromMicrosecondsSinceEpoch(t, true).year`,
+ * * `this.month == new DateTime.fromMicrosecondsSinceEpoch(t, true).month`,
+ * * `this.day == new DateTime.fromMicrosecondsSinceEpoch(t, true).day`,
+ * * `this.hour == new DateTime.fromMicrosecondsSinceEpoch(t, true).hour`,
* * ...
*
* Daylight savings is computed as if the date was computed in [1970..2037].
* If [this] lies outside this range then it is a year with similar
* properties (leap year, weekdays) is used instead.
*/
- int get _localDateInUtcMs {
- int ms = millisecondsSinceEpoch;
- if (isUtc) return ms;
+ int get _localDateInUtcMicros {
+ int micros = _value;
+ if (isUtc) return micros;
int offset =
- _timeZoneOffsetInSeconds(ms) * Duration.MILLISECONDS_PER_SECOND;
- return ms + offset;
+ _timeZoneOffsetInSeconds(micros) * Duration.MICROSECONDS_PER_SECOND;
+ return micros + offset;
}
static int _flooredDivision(int a, int b) {
@@ -204,9 +243,10 @@
return (y % 4 == 0) && ((y % 16 == 0) || (y % 100 != 0));
}
- /* patch */ static int _brokenDownDateToMillisecondsSinceEpoch(
+ /// Converts the given broken down date to microseconds.
+ /* patch */ static int _brokenDownDateToValue(
int year, int month, int day,
- int hour, int minute, int second, int millisecond,
+ int hour, int minute, int second, int millisecond, int microsecond,
bool isUtc) {
// Simplify calculations by working with zero-based month.
--month;
@@ -225,20 +265,21 @@
int days = day - 1;
days += _DAYS_UNTIL_MONTH[_isLeapYear(year) ? 1 : 0][month];
days += _dayFromYear(year);
- int millisecondsSinceEpoch =
- days * Duration.MILLISECONDS_PER_DAY +
- hour * Duration.MILLISECONDS_PER_HOUR +
- minute * Duration.MILLISECONDS_PER_MINUTE +
- second * Duration.MILLISECONDS_PER_SECOND +
- millisecond;
+ int microsecondsSinceEpoch =
+ days * Duration.MICROSECONDS_PER_DAY +
+ hour * Duration.MICROSECONDS_PER_HOUR +
+ minute * Duration.MICROSECONDS_PER_MINUTE +
+ second * Duration.MICROSECONDS_PER_SECOND +
+ millisecond * Duration.MICROSECONDS_PER_MILLISECOND +
+ microsecond;
// Since [_timeZoneOffsetInSeconds] will crash if the input is far out of
// the valid range we do a preliminary test that weeds out values that can
// not become valid even with timezone adjustments.
// The timezone adjustment is always less than a day, so adding a security
// margin of one day should be enough.
- if (millisecondsSinceEpoch.abs() >
- (_MAX_MILLISECONDS_SINCE_EPOCH + Duration.MILLISECONDS_PER_DAY)) {
+ if (microsecondsSinceEpoch.abs() >
+ _MAX_MILLISECONDS_SINCE_EPOCH * 1000 + Duration.MICROSECONDS_PER_DAY) {
return null;
}
@@ -246,15 +287,17 @@
// Note that we need to remove the local timezone adjustement before
// asking for the correct zone offset.
int adjustment = _localTimeZoneAdjustmentInSeconds() *
- Duration.MILLISECONDS_PER_SECOND;
+ Duration.MICROSECONDS_PER_SECOND;
+
int zoneOffset =
- _timeZoneOffsetInSeconds(millisecondsSinceEpoch - adjustment);
- millisecondsSinceEpoch -= zoneOffset * Duration.MILLISECONDS_PER_SECOND;
+ _timeZoneOffsetInSeconds(microsecondsSinceEpoch - adjustment);
+ microsecondsSinceEpoch -= zoneOffset * Duration.MICROSECONDS_PER_SECOND;
}
- if (millisecondsSinceEpoch.abs() > _MAX_MILLISECONDS_SINCE_EPOCH) {
+ if (microsecondsSinceEpoch.abs() >
+ _MAX_MILLISECONDS_SINCE_EPOCH * Duration.MICROSECONDS_PER_MILLISECOND) {
return null;
}
- return millisecondsSinceEpoch;
+ return microsecondsSinceEpoch;
}
static int _weekDay(y) {
@@ -304,25 +347,25 @@
// According to V8 this fast case works for dates from 1970 to 2099.
return 1970 + (4 * days + 2) ~/ DAYS_IN_4_YEARS;
}
- int ms = secondsSinceEpoch * Duration.MILLISECONDS_PER_SECOND;
- return _computeUpperPart(ms)[_YEAR_INDEX];
+ int micros = secondsSinceEpoch * Duration.MICROSECONDS_PER_SECOND;
+ return _computeUpperPart(micros)[_YEAR_INDEX];
}
/**
* Returns a date in seconds that is equivalent to the current date. An
- * equivalent date has the same fields ([:month:], [:day:], etc.) as the
- * [this], but the [:year:] is in the range [1970..2037].
+ * equivalent date has the same fields (`month`, `day`, etc.) as the
+ * [this], but the `year` is in the range [1970..2037].
*
* * The time since the beginning of the year is the same.
* * If [this] is in a leap year then the returned seconds are in a leap
* year, too.
* * The week day of [this] is the same as the one for the returned date.
*/
- static int _equivalentSeconds(int millisecondsSinceEpoch) {
+ static int _equivalentSeconds(int microsecondsSinceEpoch) {
const int CUT_OFF_SECONDS = 2100000000;
- int secondsSinceEpoch = _flooredDivision(millisecondsSinceEpoch,
- Duration.MILLISECONDS_PER_SECOND);
+ int secondsSinceEpoch = _flooredDivision(microsecondsSinceEpoch,
+ Duration.MICROSECONDS_PER_SECOND);
if (secondsSinceEpoch < 0 || secondsSinceEpoch >= CUT_OFF_SECONDS) {
int year = _yearsFromSecondsSinceEpoch(secondsSinceEpoch);
@@ -335,13 +378,13 @@
return secondsSinceEpoch;
}
- static int _timeZoneOffsetInSeconds(int millisecondsSinceEpoch) {
- int equivalentSeconds = _equivalentSeconds(millisecondsSinceEpoch);
+ static int _timeZoneOffsetInSeconds(int microsecondsSinceEpoch) {
+ int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch);
return _timeZoneOffsetInSecondsForClampedSeconds(equivalentSeconds);
}
- static String _timeZoneName(int millisecondsSinceEpoch) {
- int equivalentSeconds = _equivalentSeconds(millisecondsSinceEpoch);
+ static String _timeZoneName(int microsecondsSinceEpoch) {
+ int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch);
return _timeZoneNameForClampedSeconds(equivalentSeconds);
}
}
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 53af2c4..24e6d71 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -1206,6 +1206,11 @@
DEFINE_NATIVE_ENTRY(ClassMirror_type_variables, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
const Class& klass = Class::Handle(ref.GetClassReferent());
+ const Error& error = Error::Handle(zone, klass.EnsureIsFinalized(thread));
+ if (!error.IsNull()) {
+ Exceptions::PropagateError(error);
+ UNREACHABLE();
+ }
return CreateTypeVariableList(klass);
}
diff --git a/runtime/lib/stopwatch.cc b/runtime/lib/stopwatch.cc
index 7d8464a..ce8951de 100644
--- a/runtime/lib/stopwatch.cc
+++ b/runtime/lib/stopwatch.cc
@@ -11,7 +11,7 @@
DEFINE_NATIVE_ENTRY(Stopwatch_now, 0) {
// TODO(iposva): investigate other hi-res time sources such as cycle count.
- return Integer::New(OS::GetCurrentTimeMicros());
+ return Integer::New(OS::GetCurrentMonotonicMicros());
}
diff --git a/runtime/lib/timeline.cc b/runtime/lib/timeline.cc
index 39fa28b..f0e5982 100644
--- a/runtime/lib/timeline.cc
+++ b/runtime/lib/timeline.cc
@@ -32,7 +32,7 @@
DEFINE_NATIVE_ENTRY(Timeline_getTraceClock, 0) {
- return Integer::New(OS::GetCurrentTraceMicros(), Heap::kNew, true);
+ return Integer::New(OS::GetCurrentMonotonicMicros(), Heap::kNew, true);
}
diff --git a/runtime/tools/create_archive.py b/runtime/tools/create_archive.py
index 0a3d756..f2fe6c1 100644
--- a/runtime/tools/create_archive.py
+++ b/runtime/tools/create_archive.py
@@ -19,6 +19,8 @@
for input_file_name in files:
# Chop off client_root.
archive_file_name = input_file_name[ len(client_root) : ]
+ # Replace back slash with forward slash. So we do not have Windows paths.
+ archive_file_name = archive_file_name.replace("\\", "/")
# Open input file and add it to the archive.
with open(input_file_name, 'rb') as input_file:
tarInfo = tarfile.TarInfo(name=archive_file_name)
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 315ce85..76413a6 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -145,10 +145,10 @@
V(Random_setupSeed, 1) \
V(Random_initialSeed, 0) \
V(SecureRandom_getBytes, 1) \
- V(DateNatives_currentTimeMillis, 0) \
- V(DateNatives_timeZoneName, 1) \
- V(DateNatives_timeZoneOffsetInSeconds, 1) \
- V(DateNatives_localTimeZoneAdjustmentInSeconds, 0) \
+ V(DateTime_currentTimeMicros, 0) \
+ V(DateTime_timeZoneName, 1) \
+ V(DateTime_timeZoneOffsetInSeconds, 1) \
+ V(DateTime_localTimeZoneAdjustmentInSeconds, 0) \
V(AssertionError_throwNew, 2) \
V(Async_rethrow, 2) \
V(StackTrace_current, 0) \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index d8434d9..9ca3731 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1269,7 +1269,8 @@
for (intptr_t i = 0; i < num_type_params; i++) {
type_param ^= type_params.TypeAt(i);
bound = type_param.bound();
- if (bound.IsFinalized() || bound.IsBeingFinalized()) {
+ // Bound may be finalized, but not canonical yet.
+ if (bound.IsCanonical() || bound.IsBeingFinalized()) {
// A bound involved in F-bounded quantification may form a cycle.
continue;
}
@@ -2231,7 +2232,10 @@
FinalizeTypeParameters(cls); // May change super type.
super_class = cls.SuperClass();
ASSERT(super_class.IsNull() || super_class.is_type_finalized());
- ResolveUpperBounds(cls);
+ // Only resolving rather than finalizing the upper bounds here would result in
+ // instantiated type parameters of the super type to temporarily have
+ // unfinalized bounds. It is more efficient to finalize them early.
+ FinalizeUpperBounds(cls);
// Finalize super type.
AbstractType& super_type = AbstractType::Handle(cls.super_type());
if (!super_type.IsNull()) {
@@ -2344,6 +2348,7 @@
void ClassFinalizer::FinalizeClass(const Class& cls) {
Thread* thread = Thread::Current();
HANDLESCOPE(thread);
+ ASSERT(cls.is_type_finalized());
if (cls.is_finalized()) {
return;
}
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index c42072f..493cc0e 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -309,6 +309,17 @@
// also allows us to reset the marked_for_parsing state in case we see an
// error.
VMTagScope tagScope(thread, VMTag::kCompileClassTagId);
+ TimelineDurationScope tds(thread,
+ thread->isolate()->GetCompilerStream(),
+ "CompileClass");
+ if (tds.enabled()) {
+ tds.SetNumArguments(1);
+ tds.CopyArgument(
+ 0,
+ "class",
+ const_cast<char*>(cls.ToCString()));
+ }
+
GrowableHandlePtrArray<const Class> parse_list(thread->zone(), 4);
GrowableHandlePtrArray<const Class> patch_list(thread->zone(), 4);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 5971023..f607b18 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -5560,7 +5560,7 @@
DART_EXPORT int64_t Dart_TimelineGetMicros() {
- return OS::GetCurrentTraceMicros();
+ return OS::GetCurrentMonotonicMicros();
}
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 5a252e5..4ae6851 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -167,15 +167,15 @@
while (!cls.IsNull()) {
function ^= cls.LookupDynamicFunction(getter_name);
if (!function.IsNull()) {
- // Getters don't have a stack overflow check, so do one in C++.
-
Isolate* isolate = Isolate::Current();
-#if defined(USING_SIMULATOR)
- uword stack_pos = Simulator::Current()->get_register(SPREG);
-#else
- uword stack_pos = Isolate::GetCurrentStackPointer();
+ uword c_stack_pos = Isolate::GetCurrentStackPointer();
+ uword c_stack_limit = OSThread::Current()->stack_base() -
+ OSThread::GetSpecifiedStackSize();
+#if !defined(USING_SIMULATOR)
+ ASSERT(c_stack_limit == isolate->saved_stack_limit());
#endif
- if (stack_pos < isolate->saved_stack_limit()) {
+
+ if (c_stack_pos < c_stack_limit) {
const Instance& exception =
Instance::Handle(isolate->object_store()->stack_overflow());
return UnhandledException::New(exception, Stacktrace::Handle());
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 134d85c..658e973 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -43,7 +43,7 @@
deopt_reason_(ICData::kDeoptUnknown),
deopt_flags_(0),
thread_(Thread::Current()),
- timeline_event_(NULL),
+ deopt_start_micros_(0),
deferred_slots_(NULL),
deferred_objects_count_(0),
deferred_objects_(NULL),
@@ -99,14 +99,7 @@
if (dest_options != kDestIsAllocated) {
// kDestIsAllocated is used by the debugger to generate a stack trace
// and does not signal a real deopt.
- Isolate* isolate = Isolate::Current();
- TimelineStream* compiler_stream = isolate->GetCompilerStream();
- ASSERT(compiler_stream != NULL);
- timeline_event_ = compiler_stream->StartEvent();
- if (timeline_event_ != NULL) {
- timeline_event_->DurationBegin("Deoptimize");
- timeline_event_->SetNumArguments(3);
- }
+ deopt_start_micros_ = OS::GetCurrentMonotonicMicros();
}
if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
@@ -143,24 +136,28 @@
delete[] deferred_objects_;
deferred_objects_ = NULL;
deferred_objects_count_ = 0;
- if (timeline_event_ != NULL) {
- const Code& code = Code::Handle(zone(), code_);
- const Function& function = Function::Handle(zone(), code.function());
- timeline_event_->CopyArgument(
- 0,
- "function",
- const_cast<char*>(function.QualifiedUserVisibleNameCString()));
- timeline_event_->CopyArgument(
- 1,
- "reason",
- const_cast<char*>(DeoptReasonToCString(deopt_reason())));
- timeline_event_->FormatArgument(
- 2,
- "deoptimizationCount",
- "%d",
- function.deoptimization_counter());
- timeline_event_->DurationEnd();
- timeline_event_->Complete();
+ if (deopt_start_micros_ != 0) {
+ Isolate* isolate = Isolate::Current();
+ TimelineStream* compiler_stream = isolate->GetCompilerStream();
+ ASSERT(compiler_stream != NULL);
+ if (compiler_stream->Enabled()) {
+ const Code& code = Code::Handle(zone(), code_);
+ const Function& function = Function::Handle(zone(), code.function());
+ const char* function_name = function.QualifiedUserVisibleNameCString();
+ const char* reason = DeoptReasonToCString(deopt_reason());
+ int counter = function.deoptimization_counter();
+ TimelineEvent* timeline_event = compiler_stream->StartEvent();
+ if (timeline_event != NULL) {
+ timeline_event->Duration("Deoptimize",
+ deopt_start_micros_,
+ OS::GetCurrentMonotonicMicros());
+ timeline_event->SetNumArguments(3);
+ timeline_event->CopyArgument(0, "function", function_name);
+ timeline_event->CopyArgument(1, "reason", reason);
+ timeline_event->FormatArgument(2, "deoptimizationCount", "%d", counter);
+ timeline_event->Complete();
+ }
+ }
}
}
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index cf357d0..79c206e 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -224,7 +224,7 @@
uint32_t deopt_flags_;
intptr_t caller_fp_;
Thread* thread_;
- TimelineEvent* timeline_event_;
+ int64_t deopt_start_micros_;
DeferredSlot* deferred_slots_;
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 878dba1..8d6e6c1 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -8,6 +8,7 @@
#include "vm/intermediate_language.h"
#include "vm/cpu.h"
+#include "vm/compiler.h"
#include "vm/dart_entry.h"
#include "vm/flow_graph.h"
#include "vm/flow_graph_compiler.h"
@@ -2379,6 +2380,7 @@
ASSERT(locs()->in(kLengthPos).reg() == kLengthReg);
if (compiler->is_optimizing() &&
+ !Compiler::always_optimize() &&
num_elements()->BindsToConstant() &&
num_elements()->BoundConstant().IsSmi()) {
const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index 7707e0b..7f85d09 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -7,6 +7,7 @@
#include "vm/intermediate_language.h"
+#include "vm/compiler.h"
#include "vm/dart_entry.h"
#include "vm/flow_graph.h"
#include "vm/flow_graph_compiler.h"
@@ -2102,6 +2103,7 @@
ASSERT(locs()->in(kLengthPos).reg() == kLengthReg);
if (compiler->is_optimizing() &&
+ !Compiler::always_optimize() &&
num_elements()->BindsToConstant() &&
num_elements()->BoundConstant().IsSmi()) {
const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index c005041..16c4367 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -7,6 +7,7 @@
#include "vm/intermediate_language.h"
+#include "vm/compiler.h"
#include "vm/dart_entry.h"
#include "vm/flow_graph.h"
#include "vm/flow_graph_compiler.h"
@@ -2233,6 +2234,7 @@
Label slow_path, done;
if (compiler->is_optimizing() &&
+ !Compiler::always_optimize() &&
num_elements()->BindsToConstant() &&
num_elements()->BoundConstant().IsSmi()) {
const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 3d30dc0..07f30fb 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -7,6 +7,7 @@
#include "vm/intermediate_language.h"
+#include "vm/compiler.h"
#include "vm/dart_entry.h"
#include "vm/flow_graph.h"
#include "vm/flow_graph_compiler.h"
@@ -2117,6 +2118,7 @@
Label slow_path, done;
if (compiler->is_optimizing() &&
+ !Compiler::always_optimize() &&
num_elements()->BindsToConstant() &&
num_elements()->BoundConstant().IsSmi()) {
const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 169b42e..2799c1b 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -3787,11 +3787,11 @@
}
// Check for reflexivity.
if (thsi.raw() == other.raw()) {
- const intptr_t num_type_args = thsi.NumTypeArguments();
- if (num_type_args == 0) {
+ const intptr_t num_type_params = thsi.NumTypeParameters();
+ if (num_type_params == 0) {
return true;
}
- const intptr_t num_type_params = thsi.NumTypeParameters();
+ const intptr_t num_type_args = thsi.NumTypeArguments();
const intptr_t from_index = num_type_args - num_type_params;
// Since we do not truncate the type argument vector of a subclass (see
// below), we only check a subvector of the proper length.
@@ -9370,9 +9370,7 @@
// Library::LoadedScripts() can find it without having to iterate
// over the members of each class.
ASSERT(i < num_classes); // We must have found a class.
- Class& pc = Class::Handle();
- pc ^= patch_classes.At(i);
- const Script& patch_script = Script::Handle(pc.script());
+ const Script& patch_script = Script::Handle(cls.script());
patch_classes.SetAt(i, patch_script);
}
@@ -9816,7 +9814,7 @@
owner_script = Class::Cast(entry).script();
} else {
ASSERT(entry.IsScript());
- owner_script ^= Script::Cast(entry).raw();
+ owner_script = Script::Cast(entry).raw();
}
AddScriptIfUnique(scripts, owner_script);
}
@@ -13379,7 +13377,7 @@
VerifiedMemory::Accept(region.start(), region.size());
CPU::FlushICache(instrs.EntryPoint(), instrs.size());
- code.set_compile_timestamp(OS::GetCurrentTraceMicros());
+ code.set_compile_timestamp(OS::GetCurrentMonotonicMicros());
CodeObservers::NotifyAll(name,
instrs.EntryPoint(),
assembler->prologue_offset(),
@@ -15630,8 +15628,8 @@
const AbstractType& other,
Error* bound_error,
Heap::Space space) const {
- ASSERT(IsResolved());
- ASSERT(other.IsResolved());
+ ASSERT(IsFinalized());
+ ASSERT(other.IsFinalized());
if (IsMalformed() || other.IsMalformed()) {
// Malformed types involved in subtype tests should be handled specially
// by the caller. Malformed types should only be encountered here in a
@@ -15685,6 +15683,15 @@
}
}
const AbstractType& bound = AbstractType::Handle(type_param.bound());
+ // We may be checking bounds at finalization time and can encounter
+ // a still unfinalized bound.
+ if (!bound.IsFinalized() && !bound.IsBeingFinalized()) {
+ ClassFinalizer::FinalizeType(
+ Class::Handle(type_param.parameterized_class()),
+ bound,
+ ClassFinalizer::kCanonicalize);
+ type_param.set_bound(bound);
+ }
if (bound.IsMoreSpecificThan(other, bound_error)) {
return true;
}
diff --git a/runtime/vm/os.h b/runtime/vm/os.h
index 5285ec8..a403df2 100644
--- a/runtime/vm/os.h
+++ b/runtime/vm/os.h
@@ -48,7 +48,7 @@
static int64_t GetCurrentTimeMicros();
// Returns the current time used by the tracing infrastructure.
- static int64_t GetCurrentTraceMicros();
+ static int64_t GetCurrentMonotonicMicros();
// Returns a cleared aligned array of type T with n entries.
// Alignment must be >= 16 and a power of two.
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 1d448d0..5c09baf 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -179,7 +179,7 @@
}
-int64_t OS::GetCurrentTraceMicros() {
+int64_t OS::GetCurrentMonotonicMicros() {
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
UNREACHABLE();
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index 25c64b7..7924be1 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -396,7 +396,7 @@
}
-int64_t OS::GetCurrentTraceMicros() {
+int64_t OS::GetCurrentMonotonicMicros() {
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
UNREACHABLE();
diff --git a/runtime/vm/os_macos.cc b/runtime/vm/os_macos.cc
index 1a338f4..d2db92d 100644
--- a/runtime/vm/os_macos.cc
+++ b/runtime/vm/os_macos.cc
@@ -90,7 +90,7 @@
}
-int64_t OS::GetCurrentTraceMicros() {
+int64_t OS::GetCurrentMonotonicMicros() {
#if TARGET_OS_IOS
// On iOS mach_absolute_time stops while the device is sleeping. Instead use
// now - KERN_BOOTTIME to get a time difference that is not impacted by clock
diff --git a/runtime/vm/os_win.cc b/runtime/vm/os_win.cc
index 5af6c71..917ee6f 100644
--- a/runtime/vm/os_win.cc
+++ b/runtime/vm/os_win.cc
@@ -123,7 +123,7 @@
static int64_t qpc_ticks_per_second = 0;
-int64_t OS::GetCurrentTraceMicros() {
+int64_t OS::GetCurrentMonotonicMicros() {
if (qpc_ticks_per_second == 0) {
// QueryPerformanceCounter not supported, fallback.
return GetCurrentTimeMicros();
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index e20ff43..89cf988 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -453,6 +453,17 @@
ASSERT(thread->long_jump_base()->IsSafeToJump());
CSTAT_TIMER_SCOPE(thread, parser_timer);
VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId);
+ TimelineDurationScope tds(thread,
+ thread->isolate()->GetCompilerStream(),
+ "CompileTopLevel");
+ if (tds.enabled()) {
+ tds.SetNumArguments(1);
+ tds.CopyArgument(
+ 0,
+ "script",
+ const_cast<char*>(String::Handle(script.url()).ToCString()));
+ }
+
Parser parser(script, library, 0);
parser.ParseTopLevel();
}
@@ -1696,6 +1707,8 @@
is_match = opening_token == Token::kLBRACK;
break;
case Token::kEOS:
+ opening_token = token_stack.RemoveLast();
+ opening_pos = token_pos_stack.RemoveLast();
unexpected_token_found = true;
break;
default:
@@ -3967,7 +3980,7 @@
if (library_.is_dart_scheme() && library_.IsPrivate(*method->name)) {
func.set_is_reflectable(false);
}
- if (method->metadata_pos > 0) {
+ if (FLAG_enable_mirrors && (method->metadata_pos > 0)) {
library_.AddFunctionMetadata(func, method->metadata_pos);
}
if (method->has_native) {
@@ -4067,7 +4080,7 @@
class_field.set_has_initializer(has_initializer);
members->AddField(class_field);
field->field_ = &class_field;
- if (field->metadata_pos >= 0) {
+ if (FLAG_enable_mirrors && (field->metadata_pos >= 0)) {
library_.AddFieldMetadata(class_field, field->metadata_pos);
}
@@ -4464,7 +4477,7 @@
library_.AddClass(cls);
cls.set_is_synthesized_class();
cls.set_is_enum_class();
- if (metadata_pos >= 0) {
+ if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
library_.AddClassMetadata(cls, tl_owner, metadata_pos);
}
cls.set_super_type(Type::Handle(Z, Type::ObjectType()));
@@ -4587,7 +4600,7 @@
if (is_abstract) {
cls.set_is_abstract();
}
- if (metadata_pos >= 0) {
+ if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
library_.AddClassMetadata(cls, tl_owner, metadata_pos);
}
@@ -5020,7 +5033,7 @@
}
ExpectSemicolon();
pending_classes.Add(mixin_application, Heap::kOld);
- if (metadata_pos >= 0) {
+ if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
library_.AddClassMetadata(mixin_application, tl_owner, metadata_pos);
}
}
@@ -5186,7 +5199,7 @@
ASSERT(!function_type_alias.IsCanonicalSignatureClass());
ASSERT(!function_type_alias.is_finalized());
pending_classes.Add(function_type_alias, Heap::kOld);
- if (metadata_pos >= 0) {
+ if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
library_.AddClassMetadata(function_type_alias,
tl_owner,
metadata_pos);
@@ -5309,7 +5322,7 @@
declaration_pos);
type_parameters_array.Add(
&AbstractType::ZoneHandle(Z, type_parameter.raw()));
- if (metadata_pos >= 0) {
+ if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
library_.AddTypeParameterMetadata(type_parameter, metadata_pos);
}
index++;
@@ -5468,7 +5481,7 @@
field.SetStaticValue(Object::null_instance(), true);
top_level->AddField(field);
library_.AddObject(field, var_name);
- if (metadata_pos >= 0) {
+ if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
library_.AddFieldMetadata(field, metadata_pos);
}
if (CurrentToken() == Token::kASSIGN) {
@@ -5659,7 +5672,7 @@
toplevel_cls.RemoveFunction(replaced_func);
library_.ReplaceObject(func, func_name);
}
- if (metadata_pos >= 0) {
+ if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
library_.AddFunctionMetadata(func, metadata_pos);
}
}
@@ -5824,7 +5837,7 @@
toplevel_cls.RemoveFunction(replaced_func);
library_.ReplaceObject(func, accessor_name);
}
- if (metadata_pos >= 0) {
+ if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
library_.AddFunctionMetadata(func, metadata_pos);
}
}
@@ -5986,7 +5999,7 @@
Namespace& ns = Namespace::Handle(Z,
Namespace::New(library, show_names, hide_names));
- if (metadata_pos >= 0) {
+ if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
ns.AddMetadata(tl_owner, metadata_pos);
}
@@ -6072,7 +6085,7 @@
ReportError("patch cannot override library name");
}
ParseLibraryName();
- if (metadata_pos >= 0) {
+ if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
library_.AddLibraryMetadata(tl_owner, metadata_pos);
}
rewind_pos = TokenPos();
@@ -7661,7 +7674,7 @@
innermost_function(),
function_pos);
function.set_result_type(result_type);
- if (metadata_pos >= 0) {
+ if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
library_.AddFunctionMetadata(function, metadata_pos);
}
}
@@ -8655,7 +8668,7 @@
// Parse stream expression.
ExpectToken(Token::kIN);
- const intptr_t stream_pos = TokenPos();
+ const intptr_t stream_expr_pos = TokenPos();
AstNode* stream_expr =
ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
ExpectToken(Token::kRPAREN);
@@ -8674,19 +8687,19 @@
Function::ZoneHandle(Z, stream_iterator_cls.LookupFunction(
Symbols::StreamIteratorConstructor()));
ASSERT(!iterator_ctor.IsNull());
- ArgumentListNode* ctor_args = new (Z) ArgumentListNode(Scanner::kNoSourcePos);
+ ArgumentListNode* ctor_args = new (Z) ArgumentListNode(stream_expr_pos);
ctor_args->Add(stream_expr);
ConstructorCallNode* ctor_call =
- new (Z) ConstructorCallNode(Scanner::kNoSourcePos,
+ new (Z) ConstructorCallNode(stream_expr_pos,
TypeArguments::ZoneHandle(Z),
iterator_ctor,
ctor_args);
const AbstractType& iterator_type = Type::ZoneHandle(Z, Type::DynamicType());
LocalVariable* iterator_var = new(Z) LocalVariable(
- stream_pos, Symbols::ForInIter(), iterator_type);
+ stream_expr_pos, Symbols::ForInIter(), iterator_type);
current_block_->scope->AddVariable(iterator_var);
AstNode* iterator_init =
- new(Z) StoreLocalNode(stream_pos, iterator_var, ctor_call);
+ new(Z) StoreLocalNode(stream_expr_pos, iterator_var, ctor_call);
current_block_->statements->Add(iterator_init);
// We need to ensure that the stream is cancelled after the loop.
@@ -8724,15 +8737,15 @@
&async_saved_try_ctx,
&outer_saved_try_ctx,
&outer_async_saved_try_ctx);
- ArgumentListNode* no_args = new(Z) ArgumentListNode(stream_pos);
+ ArgumentListNode* no_args = new(Z) ArgumentListNode(stream_expr_pos);
AstNode* iterator_moveNext = new(Z) InstanceCallNode(
- stream_pos,
- new(Z) LoadLocalNode(stream_pos, iterator_var),
+ stream_expr_pos,
+ new(Z) LoadLocalNode(stream_expr_pos, iterator_var),
Symbols::MoveNext(),
no_args);
OpenBlock();
AstNode* await_moveNext =
- new(Z) AwaitNode(stream_pos,
+ new(Z) AwaitNode(stream_expr_pos,
iterator_moveNext,
saved_try_ctx,
async_saved_try_ctx,
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index af80f9f..9f820b0 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -820,7 +820,7 @@
Isolate* isolate = thread->isolate();
ASSERT(sample_buffer != NULL);
Sample* sample = sample_buffer->ReserveSample();
- sample->Init(isolate, OS::GetCurrentTraceMicros(), tid);
+ sample->Init(isolate, OS::GetCurrentMonotonicMicros(), tid);
uword vm_tag = thread->vm_tag();
#if defined(USING_SIMULATOR)
// When running in the simulator, the runtime entry function address
@@ -898,7 +898,7 @@
return;
}
- Sample* sample = SetupSample(thread, sample_buffer, os_thread->id());
+ Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
sample->SetAllocationCid(cid);
ProfilerNativeStackWalker native_stack_walker(isolate,
sample,
@@ -910,7 +910,7 @@
sp);
native_stack_walker.walk();
} else if (exited_dart_code) {
- Sample* sample = SetupSample(thread, sample_buffer, os_thread->id());
+ Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
sample->SetAllocationCid(cid);
ProfilerDartExitStackWalker dart_exit_stack_walker(thread,
isolate,
@@ -920,7 +920,7 @@
} else {
// Fall back.
uintptr_t pc = GetProgramCounter();
- Sample* sample = SetupSample(thread, sample_buffer, os_thread->id());
+ Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
sample->SetAllocationCid(cid);
sample->SetAt(0, pc);
}
@@ -1000,7 +1000,7 @@
}
// Setup sample.
- Sample* sample = SetupSample(thread, sample_buffer, os_thread->id());
+ Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
// Increment counter for vm tag.
VMTagCounters* counters = isolate->vm_tag_counters();
ASSERT(counters != NULL);
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 331fb52..60cde39 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -189,44 +189,45 @@
void TimelineEvent::AsyncBegin(const char* label, int64_t async_id) {
Init(kAsyncBegin, label);
- timestamp0_ = OS::GetCurrentTraceMicros();
+ set_timestamp0(OS::GetCurrentMonotonicMicros());
// Overload timestamp1_ with the async_id.
- timestamp1_ = async_id;
+ set_timestamp1(async_id);
}
void TimelineEvent::AsyncInstant(const char* label,
int64_t async_id) {
Init(kAsyncInstant, label);
- timestamp0_ = OS::GetCurrentTraceMicros();
+ set_timestamp0(OS::GetCurrentMonotonicMicros());
// Overload timestamp1_ with the async_id.
- timestamp1_ = async_id;
+ set_timestamp1(async_id);
}
void TimelineEvent::AsyncEnd(const char* label,
int64_t async_id) {
Init(kAsyncEnd, label);
- timestamp0_ = OS::GetCurrentTraceMicros();
+ set_timestamp0(OS::GetCurrentMonotonicMicros());
// Overload timestamp1_ with the async_id.
- timestamp1_ = async_id;
+ set_timestamp1(async_id);
}
void TimelineEvent::DurationBegin(const char* label) {
Init(kDuration, label);
- timestamp0_ = OS::GetCurrentTraceMicros();
+ set_timestamp0(OS::GetCurrentMonotonicMicros());
}
void TimelineEvent::DurationEnd() {
- timestamp1_ = OS::GetCurrentTraceMicros();
+ ASSERT(timestamp1_ == 0);
+ set_timestamp1(OS::GetCurrentMonotonicMicros());
}
void TimelineEvent::Instant(const char* label) {
Init(kInstant, label);
- timestamp0_ = OS::GetCurrentTraceMicros();
+ set_timestamp0(OS::GetCurrentMonotonicMicros());
}
@@ -234,22 +235,22 @@
int64_t start_micros,
int64_t end_micros) {
Init(kDuration, label);
- timestamp0_ = start_micros;
- timestamp1_ = end_micros;
+ set_timestamp0(start_micros);
+ set_timestamp1(end_micros);
}
void TimelineEvent::Begin(const char* label,
int64_t micros) {
Init(kBegin, label);
- timestamp0_ = micros;
+ set_timestamp0(micros);
}
void TimelineEvent::End(const char* label,
int64_t micros) {
Init(kEnd, label);
- timestamp0_ = micros;
+ set_timestamp0(micros);
}
@@ -453,7 +454,7 @@
int64_t TimelineEvent::TimeDuration() const {
if (timestamp1_ == 0) {
// This duration is still open, use current time as end.
- return OS::GetCurrentTraceMicros() - timestamp0_;
+ return OS::GetCurrentMonotonicMicros() - timestamp0_;
}
return timestamp1_ - timestamp0_;
}
@@ -529,7 +530,7 @@
return;
}
ASSERT(event != NULL);
- event->Duration(label_, timestamp_, OS::GetCurrentTraceMicros());
+ event->Duration(label_, timestamp_, OS::GetCurrentMonotonicMicros());
event->StealArguments(arguments_length_, arguments_);
event->Complete();
arguments_length_ = 0;
@@ -545,7 +546,7 @@
// Stream is not enabled, do nothing.
return;
}
- timestamp_ = OS::GetCurrentTraceMicros();
+ timestamp_ = OS::GetCurrentMonotonicMicros();
enabled_ = true;
}
@@ -675,6 +676,12 @@
// We are accessing the thread's timeline block- so take the lock here.
// This lock will be held until the call to |CompleteEvent| is made.
thread_block_lock->Lock();
+#if defined(DEBUG)
+ Thread* T = Thread::Current();
+ if (T != NULL) {
+ T->IncrementNoSafepointScopeDepth();
+ }
+#endif // defined(DEBUG)
TimelineEventBlock* thread_block = thread->timeline_block();
@@ -699,6 +706,11 @@
return event;
}
// Drop lock here as no event is being handed out.
+#if defined(DEBUG)
+ if (T != NULL) {
+ T->DecrementNoSafepointScopeDepth();
+ }
+#endif // defined(DEBUG)
thread_block_lock->Unlock();
return NULL;
}
@@ -714,6 +726,12 @@
// Unlock the thread's block lock.
Mutex* thread_block_lock = thread->timeline_block_lock();
ASSERT(thread_block_lock != NULL);
+#if defined(DEBUG)
+ Thread* T = Thread::Current();
+ if (T != NULL) {
+ T->DecrementNoSafepointScopeDepth();
+ }
+#endif // defined(DEBUG)
thread_block_lock->Unlock();
}
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 1c61814..fa55f75 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -129,10 +129,10 @@
int64_t end_micros);
void Begin(const char* label,
- int64_t micros = OS::GetCurrentTraceMicros());
+ int64_t micros = OS::GetCurrentMonotonicMicros());
void End(const char* label,
- int64_t micros = OS::GetCurrentTraceMicros());
+ int64_t micros = OS::GetCurrentMonotonicMicros());
void SerializedJSON(const char* json);
@@ -236,16 +236,6 @@
const char* GetSerializedJSON() const;
private:
- int64_t timestamp0_;
- int64_t timestamp1_;
- TimelineEventArgument* arguments_;
- intptr_t arguments_length_;
- uword state_;
- const char* label_;
- const char* category_;
- ThreadId thread_;
- Dart_Port isolate_id_;
-
void FreeArguments();
void StreamInit(TimelineStream* stream);
@@ -257,6 +247,15 @@
state_ = EventTypeField::update(event_type, state_);
}
+ void set_timestamp0(int64_t value) {
+ ASSERT(timestamp0_ == 0);
+ timestamp0_ = value;
+ }
+ void set_timestamp1(int64_t value) {
+ ASSERT(timestamp1_ == 0);
+ timestamp1_ = value;
+ }
+
enum StateBits {
kEventTypeBit = 0, // reserve 4 bits for type.
kNextBit = 4,
@@ -264,6 +263,16 @@
class EventTypeField : public BitField<EventType, kEventTypeBit, 4> {};
+ int64_t timestamp0_;
+ int64_t timestamp1_;
+ TimelineEventArgument* arguments_;
+ intptr_t arguments_length_;
+ uword state_;
+ const char* label_;
+ const char* category_;
+ ThreadId thread_;
+ Dart_Port isolate_id_;
+
friend class TimelineEventRecorder;
friend class TimelineEventEndlessRecorder;
friend class TimelineEventRingRecorder;
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 9dd31a4..dfed0df 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -186,6 +186,18 @@
@patch
class DateTime {
@patch
+ DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
+ {bool isUtc: false})
+ : this._withValue(millisecondsSinceEpoch, isUtc: isUtc);
+
+ @patch
+ DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch,
+ {bool isUtc: false})
+ : this._withValue(
+ _microsecondInRoundedMilliseconds(microsecondsSinceEpoch),
+ isUtc: isUtc);
+
+ @patch
DateTime._internal(int year,
int month,
int day,
@@ -193,26 +205,38 @@
int minute,
int second,
int millisecond,
+ int microsecond,
bool isUtc)
// checkBool is manually inlined here because dart2js doesn't inline it
// and [isUtc] is usually a constant.
: this.isUtc = isUtc is bool
? isUtc
: throw new ArgumentError.value(isUtc, 'isUtc'),
- millisecondsSinceEpoch = checkInt(Primitives.valueFromDecomposedDate(
- year, month, day, hour, minute, second, millisecond, isUtc));
+ _value = checkInt(Primitives.valueFromDecomposedDate(
+ year, month, day, hour, minute, second,
+ millisecond + _microsecondInRoundedMilliseconds(microsecond),
+ isUtc));
@patch
DateTime._now()
: isUtc = false,
- millisecondsSinceEpoch = Primitives.dateNow();
+ _value = Primitives.dateNow();
+
+ /// Rounds the given [microsecond] to the nearest milliseconds value.
+ ///
+ /// For example, invoked with argument `2600` returns `3`.
+ static int _microsecondInRoundedMilliseconds(int microsecond) {
+ return (microsecond / 1000).round();
+ }
@patch
- static int _brokenDownDateToMillisecondsSinceEpoch(
+ static int _brokenDownDateToValue(
int year, int month, int day, int hour, int minute, int second,
- int millisecond, bool isUtc) {
+ int millisecond, int microsecond, bool isUtc) {
return Primitives.valueFromDecomposedDate(
- year, month, day, hour, minute, second, millisecond, isUtc);
+ year, month, day, hour, minute, second,
+ millisecond + _microsecondInRoundedMilliseconds(microsecond),
+ isUtc);
}
@patch
@@ -228,6 +252,29 @@
}
@patch
+ DateTime add(Duration duration) {
+ return new DateTime._withValue(
+ _value + duration.inMilliseconds, isUtc: isUtc);
+ }
+
+ @patch
+ DateTime subtract(Duration duration) {
+ return new DateTime._withValue(
+ _value - duration.inMilliseconds, isUtc: isUtc);
+ }
+
+ @patch
+ Duration difference(DateTime other) {
+ return new Duration(milliseconds: _value - other._value);
+ }
+
+ @patch
+ int get millisecondsSinceEpoch => _value;
+
+ @patch
+ int get microsecondsSinceEpoch => _value * 1000;
+
+ @patch
int get year => Primitives.getYear(this);
@patch
@@ -249,6 +296,9 @@
int get millisecond => Primitives.getMilliseconds(this);
@patch
+ int get microsecond => 0;
+
+ @patch
int get weekday => Primitives.getWeekday(this);
}
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index fdc1ee2..d6dd538 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -891,9 +891,9 @@
// an identifier, we use that instead of the very generic 'Object'.
var objectConstructor = JS('', '#.constructor', object);
if (JS('bool', 'typeof # == "function"', objectConstructor)) {
- var decompiledName =
- JS('var', r'#.match(/^\s*function\s*([\w$]*)\s*\(/)[1]',
- JS('var', r'String(#)', objectConstructor));
+ var match = JS('var', r'#.match(/^\s*function\s*([\w$]*)\s*\(/)',
+ JS('var', r'String(#)', objectConstructor));
+ var decompiledName = match == null ? null : JS('var', r'#[1]', match);
if (decompiledName is String &&
JS('bool', r'/^\w+$/.test(#)', decompiledName)) {
name = decompiledName;
@@ -2898,10 +2898,9 @@
bool operator==(other) {
if (identical(this, other)) return true;
if (other is! BoundClosure) return false;
- return JS('bool', '# === # && # === # && # === #',
- _self, other._self,
- _target, other._target,
- _receiver, other._receiver);
+ return JS('bool', '# === #', _self, other._self) &&
+ JS('bool', '# === #', _target, other._target) &&
+ JS('bool', '# === #', _receiver, other._receiver);
}
int get hashCode {
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index 35dfd119..f27b34d 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -187,20 +187,16 @@
_asyncCompleteError(error, stackTrace);
}
- bool get _mayComplete => _state == _INCOMPLETE;
- bool get _isChained => _state == _CHAINED;
- bool get _isComplete => _state >= _VALUE;
- bool get _hasValue => _state == _VALUE;
- bool get _hasError => _state == _ERROR;
+ bool get _mayComplete => _state == _INCOMPLETE;
+ bool get _isPendingComplete => _state == _PENDING_COMPLETE;
+ bool get _isChained => _state == _CHAINED;
+ bool get _isComplete => _state >= _VALUE;
+ bool get _hasValue => _state == _VALUE;
+ bool get _hasError => _state == _ERROR;
- set _isChained(bool value) {
- if (value) {
- assert(!_isComplete);
- _state = _CHAINED;
- } else {
- assert(_isChained);
- _state = _INCOMPLETE;
- }
+ void _setChained() {
+ assert(!_isComplete);
+ _state = _CHAINED;
}
Future then(f(T value), { Function onError }) {
@@ -304,14 +300,15 @@
}
// Take the value (when completed) of source and complete target with that
- // value (or error). This function can chain all Futures, but is slower
- // for _Future than _chainCoreFuture - Use _chainCoreFuture in that case.
+ // value (or error). This function could chain all Futures, but is slower
+ // for _Future than _chainCoreFuture, so you must use _chainCoreFuture
+ // in that case.
static void _chainForeignFuture(Future source, _Future target) {
assert(!target._isComplete);
assert(source is! _Future);
// Mark the target as chained (and as such half-completed).
- target._isChained = true;
+ target._setChained();
try {
source.then((value) {
assert(target._isChained);
@@ -343,7 +340,7 @@
assert(source is _Future);
// Mark the target as chained (and as such half-completed).
- target._isChained = true;
+ target._setChained();
_FutureListener listener = new _FutureListener.chain(target);
if (source._isComplete) {
_propagateToListeners(source, listener);
@@ -404,7 +401,7 @@
Future<T> typedFuture = value;
if (typedFuture is _Future) {
_Future<T> coreFuture = typedFuture;
- if (coreFuture._isComplete && coreFuture._hasError) {
+ if (coreFuture._hasError) {
// Case 1 from above. Delay completion to enable the user to register
// callbacks.
_markPendingCompletion();
@@ -467,21 +464,16 @@
}
_FutureListener listener = listeners;
// Do the actual propagation.
- // Set initial state of listenerHasValue and listenerValueOrError. These
- // variables are updated, with the outcome of potential callbacks.
- bool listenerHasValue = true;
- final sourceValue = hasError ? null : source._value;
- var listenerValueOrError = sourceValue;
- // Set to true if a whenComplete needs to wait for a future.
- // The whenComplete action will resume the propagation by itself.
- bool isPropagationAborted = false;
- // TODO(floitsch): mark the listener as pending completion. Currently
- // we can't do this, since the markPendingCompletion verifies that
- // the future is not already marked (or chained).
+ // Set initial state of listenerHasError and listenerValueOrError. These
+ // variables are updated with the outcome of potential callbacks.
+ bool listenerHasError = hasError;
+ final sourceResult = source._resultOrListeners;
+ var listenerValueOrError = sourceResult;
+
// Only if we either have an error or callbacks, go into this, somewhat
// expensive, branch. Here we'll enter/leave the zone. Many futures
- // doesn't have callbacks, so this is a significant optimization.
- if (hasError || (listener.handlesValue || listener.handlesComplete)) {
+ // don't have callbacks, so this is a significant optimization.
+ if (hasError || listener.handlesValue || listener.handlesComplete) {
Zone zone = listener._zone;
if (hasError && !source._zone.inSameErrorZone(zone)) {
// Don't cross zone boundaries with errors.
@@ -497,14 +489,15 @@
oldZone = Zone._enter(zone);
}
- bool handleValueCallback() {
+ void handleValueCallback() {
+ assert(!hasError);
try {
listenerValueOrError = zone.runUnary(listener._onValue,
- sourceValue);
- return true;
+ sourceResult);
+ listenerHasError = false;
} catch (e, s) {
listenerValueOrError = new AsyncError(e, s);
- return false;
+ listenerHasError = true;
}
}
@@ -516,9 +509,10 @@
try {
matchesTest = zone.runUnary(test, asyncError.error);
} catch (e, s) {
- listenerValueOrError = identical(asyncError.error, e) ?
- asyncError : new AsyncError(e, s);
- listenerHasValue = false;
+ listenerValueOrError = identical(asyncError.error, e)
+ ? asyncError
+ : new AsyncError(e, s);
+ listenerHasError = true;
return;
}
}
@@ -533,21 +527,18 @@
listenerValueOrError = zone.runUnary(errorCallback,
asyncError.error);
}
+ listenerHasError = false;
} catch (e, s) {
- listenerValueOrError = identical(asyncError.error, e) ?
- asyncError : new AsyncError(e, s);
- listenerHasValue = false;
- return;
+ listenerValueOrError = identical(asyncError.error, e)
+ ? asyncError
+ : new AsyncError(e, s);
+ listenerHasError = true;
}
- listenerHasValue = true;
- } else {
- // Copy over the error from the source.
- listenerValueOrError = asyncError;
- listenerHasValue = false;
}
}
void handleWhenCompleteCallback() {
+ assert(!listener.handlesError);
var completeResult;
try {
completeResult = zone.run(listener._whenCompleteAction);
@@ -557,49 +548,50 @@
} else {
listenerValueOrError = new AsyncError(e, s);
}
- listenerHasValue = false;
+ listenerHasError = true;
return;
}
if (completeResult is Future) {
- _Future result = listener.result;
- result._isChained = true;
- isPropagationAborted = true;
- completeResult.then((ignored) {
- _propagateToListeners(source, new _FutureListener.chain(result));
- }, onError: (error, [stackTrace]) {
- // When there is an error, we have to make the error the new
- // result of the current listener.
- if (completeResult is! _Future) {
- // This should be a rare case.
- completeResult = new _Future();
- completeResult._setError(error, stackTrace);
+ if (completeResult is _Future && completeResult._isComplete) {
+ if (completeResult._hasError) {
+ listenerValueOrError = completeResult._error;
+ listenerHasError = true;
}
- _propagateToListeners(completeResult,
- new _FutureListener.chain(result));
- });
+ // Otherwise use the existing result of source.
+ return;
+ }
+ // We have to wait for the completeResult future to complete
+ // before knowing if it's an error or we should use the result
+ // of source.
+ var originalSource = source;
+ listenerValueOrError = completeResult.then((_) => originalSource);
+ listenerHasError = false;
}
}
- if (!hasError) {
+ if (listener.handlesComplete) {
+ // The whenComplete-handler is not combined with normal value/error
+ // handling. This means at most one handleX method is called per
+ // listener.
+ assert(!listener.handlesValue);
+ assert(!listener.handlesError);
+ handleWhenCompleteCallback();
+ } else if (!hasError) {
if (listener.handlesValue) {
- listenerHasValue = handleValueCallback();
+ handleValueCallback();
}
} else {
- handleError();
+ if (listener.handlesError) {
+ handleError();
+ }
}
- if (listener.handlesComplete) {
- handleWhenCompleteCallback();
- }
+
// If we changed zone, oldZone will not be null.
if (oldZone != null) Zone._leave(oldZone);
- if (isPropagationAborted) return;
// If the listener's value is a future we need to chain it. Note that
- // this can only happen if there is a callback. Since 'is' checks
- // can be expensive, we're trying to avoid it.
- if (listenerHasValue &&
- !identical(sourceValue, listenerValueOrError) &&
- listenerValueOrError is Future) {
+ // this can only happen if there is a callback.
+ if (listenerValueOrError is Future) {
Future chainSource = listenerValueOrError;
// Shortcut if the chain-source is already completed. Just continue
// the loop.
@@ -607,7 +599,7 @@
if (chainSource is _Future) {
if (chainSource._isComplete) {
// propagate the value (simulating a tail call).
- result._isChained = true;
+ result._setChained();
source = chainSource;
listeners = new _FutureListener.chain(result);
continue;
@@ -622,7 +614,7 @@
}
_Future result = listener.result;
listeners = result._removeListeners();
- if (listenerHasValue) {
+ if (!listenerHasError) {
result._setValue(listenerValueOrError);
} else {
AsyncError asyncError = listenerValueOrError;
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index ae003e3..dff5b18 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -906,7 +906,7 @@
* Skips data events if they are equal to the previous data event.
*
* The returned stream provides the same events as this stream, except
- * that it never provides two consequtive data events that are equal.
+ * that it never provides two consecutive data events that are equal.
*
* Equality is determined by the provided [equals] method. If that is
* omitted, the '==' operator on the last provided data element is used.
@@ -1459,7 +1459,7 @@
/**
* Abstract interface for a "sink" accepting multiple entire streams.
*
- * A consumer can accept a number of consequtive streams using [addStream],
+ * A consumer can accept a number of consecutive streams using [addStream],
* and when no further data need to be added, the [close] method tells the
* consumer to complete its work and shut down.
*
@@ -1493,7 +1493,7 @@
Future addStream(Stream<S> stream);
/**
- * Tells the consumer that no futher streams will be added.
+ * Tells the consumer that no further streams will be added.
*
* This allows the consumer to complete any remaining work and release
* resources that are no longer needed
@@ -1527,7 +1527,7 @@
*/
abstract class StreamSink<S> implements EventSink<S>, StreamConsumer<S> {
/**
- * Tells the stream sink that no futher streams will be added.
+ * Tells the stream sink that no further streams will be added.
*
* This allows the stream sink to complete any remaining work and release
* resources that are no longer needed
diff --git a/sdk/lib/collection/collections.dart b/sdk/lib/collection/collections.dart
index fb9a94b..5756544 100644
--- a/sdk/lib/collection/collections.dart
+++ b/sdk/lib/collection/collections.dart
@@ -12,7 +12,13 @@
*/
class UnmodifiableListView<E> extends UnmodifiableListBase<E> {
final Iterable<E> _source;
- /** Create an unmodifiable list backed by [source]. */
+
+ /**
+ * Creates an unmodifiable list backed by [source].
+ *
+ * The [source] of the elements may be a [List] or any [Iterable] with
+ * efficient [Iterable.length] and [Iterable.elementAt].
+ */
UnmodifiableListView(Iterable<E> source) : _source = source;
int get length => _source.length;
E operator[](int index) => _source.elementAt(index);
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index 1e89080..28ece3f 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -129,17 +129,13 @@
static const int MONTHS_PER_YEAR = 12;
/**
- * The number of milliseconds since
- * the "Unix epoch" 1970-01-01T00:00:00Z (UTC).
+ * The value of this DateTime.
*
- * This value is independent of the time zone.
- *
- * This value is at most
- * 8,640,000,000,000,000ms (100,000,000 days) from the Unix epoch.
- * In other words: [:millisecondsSinceEpoch.abs() <= 8640000000000000:].
- *
+ * The content of this field is implementation dependent. On JavaScript it is
+ * equal to [millisecondsSinceEpoch]. On the VM it is equal to
+ * [microsecondsSinceEpoch].
*/
- final int millisecondsSinceEpoch;
+ final int _value;
/**
* True if this [DateTime] is set to UTC time.
@@ -164,9 +160,11 @@
int hour = 0,
int minute = 0,
int second = 0,
- int millisecond = 0])
+ int millisecond = 0,
+ int microsecond = 0])
: this._internal(
- year, month, day, hour, minute, second, millisecond, false);
+ year, month, day, hour, minute, second, millisecond, microsecond,
+ false);
/**
* Constructs a [DateTime] instance specified in the UTC time zone.
@@ -179,9 +177,11 @@
int hour = 0,
int minute = 0,
int second = 0,
- int millisecond = 0])
+ int millisecond = 0,
+ int microsecond = 0])
: this._internal(
- year, month, day, hour, minute, second, millisecond, true);
+ year, month, day, hour, minute, second, millisecond, microsecond,
+ true);
/**
* Constructs a [DateTime] instance with current date and time in the
@@ -256,7 +256,7 @@
* time_opt ::= <empty> | (' ' | 'T') hour minutes_opt
* minutes_opt ::= <empty> | colon_opt digit{2} seconds_opt
* seconds_opt ::= <empty> | colon_opt digit{2} millis_opt
- * millis_opt ::= <empty> | '.' digit{1,6}
+ * micros_opt ::= <empty> | '.' digit{1,6}
* timezone_opt ::= <empty> | space_opt timezone
* space_opt :: ' ' | <empty>
* timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt
@@ -274,35 +274,20 @@
return int.parse(matched);
}
- // Parses fractional second digits of '.(\d{1,6})' into milliseconds.
- // Uses first three digits (assumed to be zero if not there), and
- // rounds up if fourth digit is 5 or greater.
- // Should be equivalent to `(double.parse(".$matchd")*1000).round()`.
- int parseMilliseconds(String matched) {
+ // Parses fractional second digits of '.(\d{1,6})' into the combined
+ // microseconds.
+ int parseMilliAndMicroseconds(String matched) {
if (matched == null) return 0;
int length = matched.length;
assert(length >= 1);
assert(length <= 6);
- int result = (matched.codeUnitAt(0) ^ 0x30);
- if (length <= 3) {
- int i = 1;
- while (i < length) {
- result *= 10;
+ int result = 0;
+ for (int i = 0; i < 6; i++) {
+ result *= 10;
+ if (i < matched.length) {
result += matched.codeUnitAt(i) ^ 0x30;
- i++;
}
- while (i < 3) {
- result *= 10;
- i++;
- }
- return result;
- }
- // Parse the prefix from 0..3 without creating a new substring.
- result = result * 10 + (matched.codeUnitAt(1) ^ 0x30);
- result = result * 10 + (matched.codeUnitAt(2) ^ 0x30);
- if (matched.codeUnitAt(3) >= 0x35) {
- result += 1;
}
return result;
}
@@ -314,11 +299,11 @@
int minute = parseIntOrZero(match[5]);
int second = parseIntOrZero(match[6]);
bool addOneMillisecond = false;
- int millisecond = parseMilliseconds(match[7]);
- if (millisecond == 1000) {
- addOneMillisecond = true;
- millisecond = 999;
- }
+ int milliAndMicroseconds = parseMilliAndMicroseconds(match[7]);
+ int millisecond =
+ milliAndMicroseconds ~/ Duration.MICROSECONDS_PER_MILLISECOND;
+ int microsecond =
+ milliAndMicroseconds.remainder(Duration.MICROSECONDS_PER_MILLISECOND);
bool isUtc = false;
if (match[8] != null) { // timezone part
isUtc = true;
@@ -331,14 +316,13 @@
minute -= sign * minuteDifference;
}
}
- int millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch(
- years, month, day, hour, minute, second, millisecond, isUtc);
- if (millisecondsSinceEpoch == null) {
+ int value = _brokenDownDateToValue(
+ years, month, day, hour, minute, second, millisecond, microsecond,
+ isUtc);
+ if (value == null) {
throw new FormatException("Time out of range", formattedString);
}
- if (addOneMillisecond) millisecondsSinceEpoch++;
- return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
- isUtc: isUtc);
+ return new DateTime._withValue(value, isUtc: isUtc);
} else {
throw new FormatException("Invalid date format", formattedString);
}
@@ -356,11 +340,31 @@
* 1970-01-01T00:00:00Z + [millisecondsSinceEpoch] ms in the given
* time zone (local or UTC).
*/
- DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
- {bool isUtc: false})
- : this.millisecondsSinceEpoch = millisecondsSinceEpoch,
- this.isUtc = isUtc {
- if (millisecondsSinceEpoch.abs() > _MAX_MILLISECONDS_SINCE_EPOCH) {
+ external DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
+ {bool isUtc: false});
+
+ /**
+ * Constructs a new [DateTime] instance
+ * with the given [microsecondsSinceEpoch].
+ *
+ * If [isUtc] is false then the date is in the local time zone.
+ *
+ * The constructed [DateTime] represents
+ * 1970-01-01T00:00:00Z + [microsecondsSinceEpoch] us in the given
+ * time zone (local or UTC).
+ */
+ external DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch,
+ {bool isUtc: false});
+
+ /**
+ * Constructs a new [DateTime] instance with the given value.
+ *
+ * If [isUtc] is false then the date is in the local time zone.
+ */
+ DateTime._withValue(this._value, {this.isUtc}) {
+ if (millisecondsSinceEpoch.abs() > _MAX_MILLISECONDS_SINCE_EPOCH ||
+ (millisecondsSinceEpoch.abs() == _MAX_MILLISECONDS_SINCE_EPOCH &&
+ microsecond != 0)) {
throw new ArgumentError(millisecondsSinceEpoch);
}
if (isUtc == null) throw new ArgumentError(isUtc);
@@ -379,8 +383,7 @@
*/
bool operator ==(other) {
if (!(other is DateTime)) return false;
- return (millisecondsSinceEpoch == other.millisecondsSinceEpoch &&
- isUtc == other.isUtc);
+ return (_value == other._value && isUtc == other.isUtc);
}
/**
@@ -396,7 +399,7 @@
*
*/
bool isBefore(DateTime other) {
- return millisecondsSinceEpoch < other.millisecondsSinceEpoch;
+ return _value < other._value;
}
/**
@@ -412,7 +415,7 @@
*
*/
bool isAfter(DateTime other) {
- return millisecondsSinceEpoch > other.millisecondsSinceEpoch;
+ return _value > other._value;
}
/**
@@ -427,7 +430,7 @@
* assert(berlinWallFell.isAtSameMomentAs(moonLanding) == false);
*/
bool isAtSameMomentAs(DateTime other) {
- return millisecondsSinceEpoch == other.millisecondsSinceEpoch;
+ return _value == other._value;
}
/**
@@ -438,10 +441,9 @@
* if this DateTime is smaller (earlier) than [other],
* or a positive integer if it is greater (later).
*/
- int compareTo(DateTime other)
- => millisecondsSinceEpoch.compareTo(other.millisecondsSinceEpoch);
+ int compareTo(DateTime other) => _value.compareTo(other._value);
- int get hashCode => millisecondsSinceEpoch;
+ int get hashCode => (_value ^ (_value >> 30)) & 0x3FFFFFFF;
/**
* Returns this DateTime value in the local time zone.
@@ -449,13 +451,12 @@
* Returns [this] if it is already in the local time zone.
* Otherwise this method is equivalent to:
*
- * new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
+ * new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch,
* isUtc: false)
*/
DateTime toLocal() {
if (isUtc) {
- return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
- isUtc: false);
+ return new DateTime._withValue(_value, isUtc: false);
}
return this;
}
@@ -466,13 +467,12 @@
* Returns [this] if it is already in UTC.
* Otherwise this method is equivalent to:
*
- * new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
+ * new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch,
* isUtc: true)
*/
DateTime toUtc() {
if (isUtc) return this;
- return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
- isUtc: true);
+ return new DateTime._withValue(_value, isUtc: true);
}
static String _fourDigits(int n) {
@@ -522,18 +522,19 @@
String min = _twoDigits(minute);
String sec = _twoDigits(second);
String ms = _threeDigits(millisecond);
+ String us = microsecond == 0 ? "" : _threeDigits(microsecond);
if (isUtc) {
- return "$y-$m-$d $h:$min:$sec.${ms}Z";
+ return "$y-$m-$d $h:$min:$sec.$ms${us}Z";
} else {
- return "$y-$m-$d $h:$min:$sec.$ms";
+ return "$y-$m-$d $h:$min:$sec.$ms$us";
}
}
/**
* Returns an ISO-8601 full-precision extended format representation.
*
- * The format is `yyyy-MM-ddTHH:mm:ss.sssZ` for UTC time, and
- * `yyyy-MM-ddTHH:mm:ss.sss` (no trailing "Z") for local/non-UTC time,
+ * The format is `yyyy-MM-ddTHH:mm:ss.mmmuuuZ` for UTC time, and
+ * `yyyy-MM-ddTHH:mm:ss.mmmuuu` (no trailing "Z") for local/non-UTC time,
* where:
*
* * `yyyy` is a, possibly negative, four digit representation of the year,
@@ -543,8 +544,10 @@
* * `dd` is the day of the month in the range 01 to 31,
* * `HH` are hours in the range 00 to 23,
* * `mm` are minutes in the range 00 to 59,
- * * `ss` are seconds in the range 00 to 59 (no leap seconds), and
- * * `sss` are milliseconds in the range 000 to 999.
+ * * `ss` are seconds in the range 00 to 59 (no leap seconds),
+ * * `mmm` are microseconds in the range 000 to 999, and
+ * * `uuu` are microseconds in the range 001 to 999. If [microsecond] equals
+ * 0, then this part is omitted.
*
* The resulting string can be parsed back using [parse].
*/
@@ -557,10 +560,11 @@
String min = _twoDigits(minute);
String sec = _twoDigits(second);
String ms = _threeDigits(millisecond);
+ String us = microsecond == 0 ? "" : _threeDigits(microsecond);
if (isUtc) {
- return "$y-$m-${d}T$h:$min:$sec.${ms}Z";
+ return "$y-$m-${d}T$h:$min:$sec.$ms${us}Z";
} else {
- return "$y-$m-${d}T$h:$min:$sec.$ms";
+ return "$y-$m-${d}T$h:$min:$sec.$ms$us";
}
}
@@ -570,39 +574,49 @@
* DateTime today = new DateTime.now();
* DateTime sixtyDaysFromNow = today.add(new Duration(days: 60));
*/
- DateTime add(Duration duration) {
- int ms = millisecondsSinceEpoch;
- return new DateTime.fromMillisecondsSinceEpoch(
- ms + duration.inMilliseconds, isUtc: isUtc);
- }
+ external DateTime add(Duration duration);
/**
* Returns a new [DateTime] instance with [duration] subtracted from [this].
*
* DateTime today = new DateTime.now();
- * DateTime sixtyDaysAgo = today.subtract(new Duration(days: 60));
+ * DateTime sixtyDaysAgo = today.subtract(new Duration(days: 30));
+ *
+ * Notice that duration being subtracted is actually 30 * 24 * 60 * 60 seconds
+ * and if that crosses a daylight saving time change, the resulting `DateTime`
+ * won't have the same time of day as `today`, and may not actually hit the
+ * calendar date 30 days earlier. Be careful when working with dates in local
+ * time.
*/
- DateTime subtract(Duration duration) {
- int ms = millisecondsSinceEpoch;
- return new DateTime.fromMillisecondsSinceEpoch(
- ms - duration.inMilliseconds, isUtc: isUtc);
- }
+ external DateTime subtract(Duration duration);
/**
* Returns a [Duration] with the difference between [this] and [other].
*
- * DateTime berlinWallFell = new DateTime(1989, DateTime.NOVEMBER, 9);
- * DateTime dDay = new DateTime(1944, DateTime.JUNE, 6);
+ * DateTime berlinWallFell = new DateTime.utc(1989, DateTime.NOVEMBER, 9);
+ * DateTime dDay = new DateTime.utc(1944, DateTime.JUNE, 6);
*
* Duration difference = berlinWallFell.difference(dDay);
* assert(difference.inDays == 16592);
+ *
+ * The difference is measured in seconds and fractions of seconds.
+ * The difference above counts the number of fractional seconds between
+ * midnight at the beginning of those dates.
+ * If the dates above had been in local time, not UTC, then the difference
+ * between two midnights may not be a multiple of 24 hours due to daylight
+ * saving differences.
+ *
+ * For example, in Australia, similar code using local time instead of UTC:
+ *
+ * DateTime berlinWallFell = new DateTime(1989, DateTime.NOVEMBER, 9);
+ * DateTime dDay = new DateTime(1944, DateTime.JUNE, 6);
+ * Duration difference = berlinWallFell.difference(dDay);
+ * assert(difference.inDays == 16592);
+ *
+ * will fail because the difference is actually 16591 days and 23 hours, and
+ * [Duration.inDays] only returns the number of whole days.
*/
-
- Duration difference(DateTime other) {
- int ms = millisecondsSinceEpoch;
- int otherMs = other.millisecondsSinceEpoch;
- return new Duration(milliseconds: ms - otherMs);
- }
+ external Duration difference(DateTime other);
external DateTime._internal(int year,
int month,
@@ -611,13 +625,43 @@
int minute,
int second,
int millisecond,
+ int microsecond,
bool isUtc);
+
external DateTime._now();
- /// Returns the time as milliseconds since epoch, or null if the
- /// values are out of range.
- external static int _brokenDownDateToMillisecondsSinceEpoch(
+
+ /// Returns the time as value (millisecond or microsecond since epoch), or
+ /// null if the values are out of range.
+ external static int _brokenDownDateToValue(
int year, int month, int day, int hour, int minute, int second,
- int millisecond, bool isUtc);
+ int millisecond, int microsecond, bool isUtc);
+
+ /**
+ * The number of milliseconds since
+ * the "Unix epoch" 1970-01-01T00:00:00Z (UTC).
+ *
+ * This value is independent of the time zone.
+ *
+ * This value is at most
+ * 8,640,000,000,000,000ms (100,000,000 days) from the Unix epoch.
+ * In other words: `millisecondsSinceEpoch.abs() <= 8640000000000000`.
+ */
+ external int get millisecondsSinceEpoch;
+
+ /**
+ * The number of microseconds since
+ * the "Unix epoch" 1970-01-01T00:00:00Z (UTC).
+ *
+ * This value is independent of the time zone.
+ *
+ * This value is at most
+ * 8,640,000,000,000,000,000us (100,000,000 days) from the Unix epoch.
+ * In other words: `microsecondsSinceEpoch.abs() <= 8640000000000000000`.
+ *
+ * Note that this value does not fit into 53 bits (the size of a IEEE double).
+ * A JavaScript number is not able to hold this value.
+ */
+ external int get microsecondsSinceEpoch;
/**
* The abbreviated time zone name—for example,
@@ -695,6 +739,14 @@
external int get millisecond;
/**
+ * The microsecond [0...999].
+ *
+ * DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
+ * assert(moonLanding.microsecond == 0);
+ */
+ external int get microsecond;
+
+ /**
* The day of the week [MONDAY]..[SUNDAY].
*
* In accordance with ISO 8601
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index 98f7da8..fdc7727 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -170,7 +170,7 @@
* non-negative number (i.e. unsigned representation). The returned value has
* zeros in all bit positions higher than [width].
*
- * (-1).toUnsigned(5) == 32 // 11111111 -> 00011111
+ * (-1).toUnsigned(5) == 31 // 11111111 -> 00011111
*
* This operation can be used to simulate arithmetic from low level languages.
* For example, to increment an 8 bit quantity:
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 7f4ab18..9d25927 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -192,17 +192,26 @@
*
* The [compare] function must act as a [Comparator].
*
- * List<String> numbers = ['one', 'two', 'three', 'four'];
+ * List<String> numbers = ['two', 'three', 'four'];
* // Sort from shortest to longest.
- * numbers.sort((x, y) => x.length.compareTo(y.length));
- * numbers.join(', '); // 'one, two, four, three'
+ * numbers.sort((a, b) => a.length.compareTo(b.length));
+ * print(numbers); // [two, four, three]
*
* The default List implementations use [Comparable.compare] if
* [compare] is omitted.
*
* List<int> nums = [13, 2, -11];
* nums.sort();
- * nums.join(', '); // '-11, 2, 13'
+ * print(nums); // [-11, 2, 13]
+ *
+ * A [Comparator] may compare objects as equal (return zero), even if they
+ * are distinct objects.
+ * The sort function is not guaranteed to be stable, so distinct objects
+ * that compare as equal may occur in any order in the result:
+ *
+ * List<String> numbers = ['one', 'two', 'three', 'four'];
+ * numbers.sort((a, b) => a.length.compareTo(b.length));
+ * print(numbers); // [one, two, four, three] OR [two, one, four, three]
*/
void sort([int compare(E a, E b)]);
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 56ccac3..f17ea2f 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -104,8 +104,6 @@
Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t01: CompileTimeError # Please triage this failure
Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t02: CompileTimeError # Please triage this failure
Language/Libraries_and_Scripts/Imports/namespace_changes_t10: CompileTimeError # Please triage this failure
-Language/Libraries_and_Scripts/Imports/same_name_t08: fail # Issue 21171
-Language/Libraries_and_Scripts/Imports/same_name_t18: fail # Issue 21171
Language/Libraries_and_Scripts/URIs/syntax_t04: CompileTimeError # Please triage this failure
Language/Libraries_and_Scripts/URIs/syntax_t05: CompileTimeError # Please triage this failure
Language/Libraries_and_Scripts/URIs/syntax_t09: CompileTimeError # Please triage this failure
@@ -119,7 +117,6 @@
Language/Metadata/before_type_param_t01: CompileTimeError # Please triage this failure
Language/Metadata/before_typedef_t01: RuntimeError # Please triage this failure
Language/Metadata/before_variable_t01: RuntimeError # Please triage this failure
-Language/Metadata/compilation_t10: MissingCompileTimeError # Please triage this failure
Language/Mixins/Mixin_Application/error_t01: MissingCompileTimeError # Please triage this failure
Language/Mixins/Mixin_Application/error_t02: MissingCompileTimeError # Please triage this failure
Language/Mixins/Mixin_Application/wrong_mixin_type_t01: MissingCompileTimeError # Please triage this failure
@@ -631,6 +628,7 @@
LayoutTests/fast/backgrounds/background-shorthand-with-backgroundSize-style_t01: RuntimeError # co19 issue 14
LayoutTests/fast/backgrounds/multiple-backgrounds-computed-style_t01: RuntimeError # co19 issue 14
LayoutTests/fast/borders/border-radius-child_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/borders/border-width-percent_t01: RuntimeError # Issue 25155
LayoutTests/fast/canvas/2d.fillText.gradient_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.gradient_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.negative_t01: RuntimeError # Please triage this failure
@@ -750,6 +748,7 @@
LayoutTests/fast/css/auto-min-size_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/background-position-serialize_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/background-serialize_t01: RuntimeError # https://github.com/dart-lang/co19/issues/14
+LayoutTests/fast/css/css-selector-text_t01: RuntimeError # co19 Issue 15
LayoutTests/fast/css/css-escaped-identifier_t01: RuntimeError # co19 issue 14
LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: RuntimeError # Please triage this failure
@@ -842,6 +841,7 @@
LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css3-text/css3-text-justify/getComputedStyle/getComputedStyle-text-justify_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/52776_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/click-method-on-html-element_t01: RuntimeError # Issue 25155
LayoutTests/fast/dom/DOMException/XPathException_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Document/CaretRangeFromPoint/basic_t01: RuntimeError # Please triage this failure
@@ -879,8 +879,10 @@
LayoutTests/fast/dom/HTMLLinkElement/link-beforeload-recursive_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/dom/HTMLLinkElement/resolve-url-on-insertion_t01: RuntimeError # Issue 18010
LayoutTests/fast/dom/HTMLObjectElement/beforeload-set-text-crash_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/dom/HTMLObjectElement/set-type-to-null-crash_t01: RuntimeError # Issue 25155
LayoutTests/fast/dom/HTMLOptionElement/collection-setter-getter_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLOutputElement/dom-settable-token-list_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/HTMLObjectElement/form/test1_t01: RuntimeError # Issue 25155
LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLScriptElement/async-inline-script_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLScriptElement/async-onbeforeload_t01: RuntimeError # Please triage this failure
@@ -934,6 +936,7 @@
LayoutTests/fast/dom/fragment-activation-focuses-target_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/dom/getElementsByClassName/011_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/dom/getElementsByClassName/dumpNodeList_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/getelementsbyname-invalidation-cache_t01: RuntimeError # Issue 25155
LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # Please triage this failure
@@ -941,6 +944,7 @@
LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: Skip # API not supported.
LayoutTests/fast/dom/navigatorcontentutils/register-protocol-handler_t01: Skip # API not supported.
LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: Skip # API not supported.
+LayoutTests/fast/dom/object-plugin-hides-properties_t01: RuntimeError # Issue 25155
LayoutTests/fast/dom/option-properties_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/set-innerHTML_t01: RuntimeError # Please triage this failure
@@ -954,6 +958,7 @@
LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-option_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/shadow-content-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/shadow-disable_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/dom/shadow/shadow-element-inactive_t01: RuntimeError # Issue 25155
LayoutTests/fast/dom/shadow/shadow-removechild-and-blur-event_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/shadow-root-js-api_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/shadowhost-keyframes_t01: Pass, RuntimeError # Please triage this failure
@@ -963,6 +968,7 @@
LayoutTests/fast/dynamic/crash-generated-quote_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dynamic/crash-generated-text_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dynamic/insertAdjacentElement_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dynamic/insertAdjacentHTML-allowed-parents_t01: RuntimeError # Issue 25155
LayoutTests/fast/dynamic/recursive-layout_t01: RuntimeError # Please triage this failure
LayoutTests/fast/encoding/css-charset-dom_t01: RuntimeError # Please triage this failure
LayoutTests/fast/events/add-event-without-document_t01: RuntimeError # Please triage this failure
@@ -1010,13 +1016,16 @@
LayoutTests/fast/forms/autofocus-readonly-attribute_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/forms/button-baseline-and-collapsing_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/forms/button/button-disabled-blur_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/forms/checkValidity-001_t01: RuntimeError # Issue 25155
LayoutTests/fast/forms/clone-input-with-dirty-value_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-onblur-setvalue-onfocusremoved_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/forms/date/input-valueasdate-date_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/datetimelocal/input-valueasdate-datetimelocal_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/fieldset/fieldset-elements_t01: RuntimeError # Issue 25155
LayoutTests/fast/forms/file/file-input-capture_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/focus-style-pending_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/forms/focus_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/forms/form-attribute_t01: RuntimeError # Issue 25155
LayoutTests/fast/forms/input-appearance-elementFromPoint_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/input-hit-test-border_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/forms/input-inputmode_t01: RuntimeError # Please triage this failure
@@ -1036,11 +1045,14 @@
LayoutTests/fast/forms/select-clientheight-with-multiple-attr_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/forms/select-list-box-mouse-focus_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/forms/select-max-length_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/setCustomValidity-existence_t01: RuntimeError # Issue 25155
LayoutTests/fast/forms/setrangetext_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/submit-form-attributes_t01: RuntimeError # co19 issue 14
LayoutTests/fast/forms/textarea-paste-newline_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/textfield-focus-out_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/forms/validationMessage_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/validity-property_t01: RuntimeError # Issue 25155
+LayoutTests/fast/forms/willvalidate_t01: RuntimeError # Issue 25155
LayoutTests/fast/html/hidden-attr_t01: RuntimeError # Please triage this failure
LayoutTests/fast/html/imports/import-element-removed-flag_t01: RuntimeError # Please triage this failure
LayoutTests/fast/html/imports/import-events_t01: RuntimeError # Please triage this failure
@@ -1063,6 +1075,7 @@
LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: RuntimeError # Please triage this failure
LayoutTests/fast/loader/stateobjects/replacestate-in-onunload_t01: RuntimeError # Please triage this failure
LayoutTests/fast/innerHTML/innerHTML-uri-resolution_t01: RuntimeError # co19 issue 14
+LayoutTests/fast/masking/parsing-clip-path-iri_t01: RuntimeError # co19 issue 14
LayoutTests/fast/masking/parsing-clip-path-shape_t01: RuntimeError # Please triage this failure
LayoutTests/fast/masking/parsing-mask-source-type_t01: RuntimeError # Please triage this failure
LayoutTests/fast/masking/parsing-mask_t01: RuntimeError # Please triage this failure
@@ -1104,6 +1117,7 @@
LayoutTests/fast/replaced/table-percent-width_t01: RuntimeError # Please triage this failure
LayoutTests/fast/ruby/ruby-line-height_t01: RuntimeError # Please triage this failure
LayoutTests/fast/shapes/parsing/parsing-shape-lengths_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/shapes/parsing/parsing-shape-outside_t01: RuntimeError # co19 issue 14
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-big-box-border-radius_t01: RuntimeError # Please triage this failure
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-diamond-margin-polygon_t01: RuntimeError # Please triage this failure
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left_t01: RuntimeError # Please triage this failure
@@ -1236,6 +1250,7 @@
LibTest/html/Element/getNamespacedAttributes_A01_t01: RuntimeError # Issue 16395
LibTest/html/Element/isContentEditable_A01_t01: RuntimeError # Please triage this failure
LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # Please triage this failure
+LibTest/html/Element/isTagSupported_A01_t01: RuntimeError # Issue 25155
LibTest/html/Element/marginEdge_A01_t01: RuntimeError # Issue 16574
LibTest/html/Element/mouseWheelEvent_A01_t01: Skip # Times out. Please triage this failure
LibTest/html/Element/onMouseWheel_A01_t01: Skip # Times out. Please triage this failure
@@ -1243,6 +1258,7 @@
LibTest/html/Element/paddingEdge_A01_t01: RuntimeError # Issue 16574
LibTest/html/Element/querySelectorAll_A01_t02: RuntimeError # Please triage this failure
LibTest/html/Element/replaceWith_A01_t02: RuntimeError # Please triage this failure
+LibTest/html/Element/tagName_A01_t01: RuntimeError # Issue 25155
LibTest/html/Element/transitionEndEvent_A01_t01: RuntimeError # Please triage this failure
LibTest/html/HttpRequest/getAllResponseHeaders_A01_t01: RuntimeError # Please triage this failure
LibTest/html/HttpRequest/getResponseHeader_A01_t01: RuntimeError # Please triage this failure
@@ -1313,6 +1329,12 @@
WebPlatformTest/custom-elements/concepts/type_A03_t01: RuntimeError # Please triage this failure
WebPlatformTest/custom-elements/concepts/type_A05_t01: RuntimeError # Please triage this failure
WebPlatformTest/custom-elements/concepts/type_A06_t01: RuntimeError # Please triage this failure
+WebPlatformTest/custom-elements/instantiating/createElement_A02_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/createElement_A03_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/createElementNS_A02_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/createElementNS_A03_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t02: RuntimeError # Issue 25155
WebPlatformTest/dom/EventTarget/dispatchEvent_A02_t01: RuntimeError # Please triage this failure
WebPlatformTest/dom/EventTarget/dispatchEvent_A03_t01: Skip # Times out. Please triage this failure
WebPlatformTest/dom/events/type_A01_t01: RuntimeError # Please triage this failure
@@ -1360,7 +1382,6 @@
WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Skip # Times out. Please triage this failure
WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: RuntimeError # Please triage this failure
-WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formaction_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setRangeText_t01: RuntimeError # Please triage this failure
@@ -1453,6 +1474,8 @@
WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-002_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-002_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-009_t01: RuntimeError # Please triage this failure
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-005_t01: RuntimeError # Issue 25155
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-007_t01: RuntimeError # Issue 25155
WebPlatformTest/webstorage/event_constructor_t01: RuntimeError # Please triage this failure
WebPlatformTest/webstorage/event_constructor_t02: RuntimeError # Please triage this failure
@@ -1625,25 +1648,6 @@
LayoutTests/fast/text/regional-indicator-symobls_t01: RuntimeError # Please triage this failure
LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError # Please triage this failure
-[ $compiler == dart2js && $runtime == chrome && $system == windows ]
-LayoutTests/fast/canvas/canvas-blending-color-over-gradient_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-color-over-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-color-over-pattern_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-fill-style_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-global-alpha_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-gradient-over-color_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-gradient-over-gradient_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-gradient-over-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-image-over-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-pattern-over-color_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-pattern-over-gradient_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-pattern-over-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-pattern-over-pattern_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-shadow_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-transforms_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-composite-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-composite-stroke-alpha_t01: RuntimeError # Please triage this failure
-
[ $compiler == dart2js && $runtime == chrome && $system != linux ]
LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Issue 24398
@@ -3167,6 +3171,9 @@
LayoutTests/fast/xpath/4XPath/Core/test_parser_t01: RuntimeError # Dartium JSInterop failure
LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Dartium JSInterop failure
+[ $compiler == dart2js && $runtime == ff && $system == linux]
+LayoutTests/fast/canvas/canvas-composite-text-alpha_t01: RuntimeError # co19 issue 16
+
[ $compiler == dart2js && $runtime == safari ]
LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
@@ -9615,10 +9622,6 @@
WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out. Please triage this failure
[ $compiler == dart2js && $cps_ir ]
-Language/Expressions/Instance_Creation/New/evaluation_t12: RuntimeError # Please triage this failure.
-Language/Expressions/Method_Invocation/Super_Invocation/syntax_t01: RuntimeError # Cannot read property 'call' of undefined
-Language/Expressions/Identifier_Reference/evaluation_variable_or_parameter_t03.dart: Crash # (i=0): For-loop variable captured in loop header
-Language/Statements/For/syntax_t07: Crash # unsupported operation on erroneous element
Language/Statements/Labels/scope_t04: Crash # (switch (i){L:case 0:flag=true;break;case 2:continue L;}): continue to a labeled switch case
Language/Statements/Continue/label_t12: Crash # (switch (2){L:case 1:flag=true;break;case 2:continue L;}): continue to a labeled switch case
Language/Statements/Continue/label_t13: Crash # (switch (2){case 2:continue L;L:case 1:flag=true;}): continue to a labeled switch case
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index b9f872a..c5bfba7 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -23,6 +23,7 @@
LibTest/core/DateTime/parse_A03_t01: fail # Issue 12514
+LibTest/core/DateTime/parse_A01_t02: Fail # co19 issue 17.
LibTest/core/DateTime/DateTime.now_A01_t02: Pass, Fail # co19 issue 709
diff --git a/tests/compiler/dart2js/async_await_syntax_test.dart b/tests/compiler/dart2js/async_await_syntax_test.dart
index fd21a0d..af4ae5a 100644
--- a/tests/compiler/dart2js/async_await_syntax_test.dart
+++ b/tests/compiler/dart2js/async_await_syntax_test.dart
@@ -14,9 +14,9 @@
/// includes the multitest in 'language/async_await_syntax_test.dart' but
/// expects the subtests 'a03b' and 'a04c' to fail.
const Map<String, List<String>> TESTS = const <String, List<String>>{
- 'language/async_await_syntax_test.dart': const ['a05h', 'c11a', 'c11b'],
+ 'language/async_await_syntax_test.dart': const [],
};
void main(List<String> arguments) {
- check(TESTS, arguments: arguments, options: ['--enable-async']);
+ check(TESTS, arguments: arguments, options: []);
}
diff --git a/tests/compiler/dart2js/js_safety_test.dart b/tests/compiler/dart2js/js_safety_test.dart
new file mode 100644
index 0000000..140f4b6
--- /dev/null
+++ b/tests/compiler/dart2js/js_safety_test.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:compiler/src/js/js.dart' as js;
+import 'package:compiler/src/js/placeholder_safety.dart';
+
+void test(String source, int expected, {List notNull: const[]}) {
+ var predicate = (int pos) => ! notNull.contains(pos);
+ js.Template template = js.js.parseForeignJS(source);
+ int actual = PlaceholderSafetyAnalysis.analyze(template.ast, predicate);
+ Expect.equals(expected, actual, 'source: "$source", notNull: $notNull');
+}
+
+
+void main() {
+ test('0', 0);
+
+ test('#.x', 1);
+ test('!!#.x', 1);
+ test('#.x + 1', 1);
+ test('1 + #.x', 1);
+ test('#[#] + 2', 2);
+ test('2 + #[#]', 2);
+ test('(# & #) >>> 0', 2);
+
+ test('#.a + #.b + #.c', 1);
+ test('#.b + #.b + #.c', 2, notNull: [0]);
+ test('#.c + #.b + #.c', 3, notNull: [0, 1]);
+ test('#.d + #.b + #.c', 1, notNull: [1]);
+
+ test('typeof(#) == "string"', 1);
+ test('"object" === typeof #', 1);
+
+ test('# == 1 || # == 2 || # == 3', 1);
+ test('# != 1 && # != 2 && # != 3', 1);
+
+ test('#.x == 1 || # == 1', 1);
+ test('# == 1 || #.x == 1', 1);
+
+ test('(# || 1, #)', 1); // Could also be 2.
+
+ test('(#, null.a, #)', 1);
+ test('(#, undefined.a, #)', 1);
+ test('(#, (void 0).a, #)', 1);
+ test('(#, "a".a, #)', 2);
+ test('((#, "a").a, #)', 2);
+
+ test('#[#][#][#][#]', 2);
+ test('#[#][#][#][#]', 3, notNull: [0]);
+ test('#[#][#][#][#]', 3, notNull: [0, 1, 2, 3]);
+
+ test('#.a = #', 2);
+ test('#.a.b = #', 1);
+ test('#[1] = #', 2);
+ test('#[1][1] = #', 1);
+
+ test('#.a = #.a + #.a + #.a', 2);
+ test('#.a = #.a + #.a + #.a', 2, notNull: [0]);
+ test('#.a = #.a + #.a + #.a', 3, notNull: [1]);
+ test('#.a = #.a + #.a + #.a', 4, notNull: [1, 2]);
+
+ test('#()', 1);
+ test('#(#, #)', 3);
+ test('#.f(#, #)', 1);
+ test('#.f(#, #)', 3, notNull: [0]);
+
+ test('(#.a+=1, #)', 1);
+ test('(#.a++, #)', 1);
+ test('(++#.a, #)', 1);
+
+ test('new Array(#)', 1);
+ test('new Date(#)', 1);
+ test('new Function(#)', 1);
+ test('new RegExp(#)', 1);
+ test('new xxx(#)', 0);
+ test('String(#)', 1);
+ test('# in #', 2);
+
+ test('Object.keys(#)', 1);
+
+ test('typeof #', 1);
+ test('typeof #.foo', 1);
+ test('typeof foo.#', 0);
+ test('typeof Array.#', 1);
+
+ test('throw #', 1);
+ test('throw #.x', 1);
+
+ test('(function(){})()', 0);
+ test('(function(a,b){#})(#, #)', 0);
+ // Placeholders in an immediate call are ok.
+ test('(function(a,b){a++;b++;return a+b})(#, #)', 2);
+
+ test('# ? # : #', 1);
+ test('(# ? 1 : #, #)', 1);
+ test('(# ? # : 2, #)', 1);
+ test('(# ? 1 : 2, #)', 1); // Could also be 4.
+
+ test('{A:#, B:#, C:#}', 3);
+ test('[#,#,#,#]', 4);
+ test('[,,,,#,#,,,]', 2);
+}
diff --git a/tests/compiler/dart2js/mirrors_helper.dart b/tests/compiler/dart2js/mirrors_helper.dart
index 30910d5..7ffae11 100644
--- a/tests/compiler/dart2js/mirrors_helper.dart
+++ b/tests/compiler/dart2js/mirrors_helper.dart
@@ -15,10 +15,9 @@
}
/// Singleline doc comment.
-@Metadata // This is intentionally the type literal.
+@Metadata(null)
// Singleline comment 1.
// Singleline comment 2.
-@Metadata(null)
@Metadata(true)
@Metadata(false)
@Metadata(0)
diff --git a/tests/compiler/dart2js/mirrors_test.dart b/tests/compiler/dart2js/mirrors_test.dart
index 7d3c48c..ef815e9 100644
--- a/tests/compiler/dart2js/mirrors_test.dart
+++ b/tests/compiler/dart2js/mirrors_test.dart
@@ -169,7 +169,7 @@
var metadataList = fooClass.metadata;
Expect.isNotNull(metadataList);
- Expect.equals(16, metadataList.length);
+ Expect.equals(14, metadataList.length);
var metadataListIndex = 0;
var metadata;
@@ -192,28 +192,17 @@
Expect.stringEquals(
"Singleline doc comment.", metadata.trimmedText);
- // @Metadata
+ // @Metadata(null)
metadata = metadataList[metadataListIndex++];
+ var metadataType = metadata.type;
Expect.isTrue(metadata is InstanceMirror);
Expect.isFalse(metadata.hasReflectee);
Expect.throws(() => metadata.reflectee, (_) => true);
- Expect.isTrue(metadata is TypeInstanceMirror);
- var metadataType = metadata.representedType;
- Expect.isNotNull(metadataType);
- Expect.equals(#Metadata, metadataType.simpleName);
-
- // // This is intentionally the type literal.
- metadata = metadataList[metadataListIndex++];
- Expect.isTrue(metadata is InstanceMirror);
- Expect.isFalse(metadata.hasReflectee);
- Expect.throws(() => metadata.reflectee, (_) => true);
- Expect.isTrue(metadata is CommentInstanceMirror);
- Expect.equals(commentType.originalDeclaration, metadata.type);
- Expect.isFalse(metadata.isDocComment);
- Expect.stringEquals(
- "// This is intentionally the type literal.", metadata.text);
- Expect.stringEquals(
- "This is intentionally the type literal.", metadata.trimmedText);
+ Expect.isTrue(metadataType.isOriginalDeclaration);
+ InstanceMirror data = metadata.getField(#data);
+ Expect.isNotNull(data);
+ Expect.isTrue(data.hasReflectee);
+ Expect.isNull(data.reflectee);
// Singleline comment 1.
metadata = metadataList[metadataListIndex++];
@@ -241,17 +230,6 @@
Expect.stringEquals(
"Singleline comment 2.", metadata.trimmedText);
- // @Metadata(null)
- metadata = metadataList[metadataListIndex++];
- Expect.isTrue(metadata is InstanceMirror);
- Expect.isFalse(metadata.hasReflectee);
- Expect.throws(() => metadata.reflectee, (_) => true);
- Expect.equals(metadataType.originalDeclaration, metadata.type);
- InstanceMirror data = metadata.getField(#data);
- Expect.isNotNull(data);
- Expect.isTrue(data.hasReflectee);
- Expect.isNull(data.reflectee);
-
// @Metadata(true)
metadata = metadataList[metadataListIndex++];
Expect.isTrue(metadata is InstanceMirror);
@@ -398,7 +376,7 @@
// leading comment.
Expect.equals(376, fooClassLocation.offset, "Unexpected offset");
// Expect the location to end with the class body.
- Expect.equals(351, fooClassLocation.length, "Unexpected length");
+ Expect.equals(298, fooClassLocation.length, "Unexpected length");
Expect.equals(18, fooClassLocation.line, "Unexpected line");
Expect.equals(1, fooClassLocation.column, "Unexpected column");
diff --git a/tests/compiler/dart2js/parser_helper.dart b/tests/compiler/dart2js/parser_helper.dart
index eeba1f9..202e6f2 100644
--- a/tests/compiler/dart2js/parser_helper.dart
+++ b/tests/compiler/dart2js/parser_helper.dart
@@ -102,7 +102,7 @@
NodeListener listener = new NodeListener(
new ScannerOptions(canUseNative: true),
reporter, library.entryCompilationUnit);
- Parser parser = new Parser(listener);
+ Parser parser = new Parser(listener, enableConditionalDirectives: true);
Token endToken = parseMethod(parser, tokens);
assert(endToken.kind == EOF_TOKEN);
Node node = listener.popNode();
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index d0e7db5..9406ea9 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -2600,8 +2600,7 @@
NodeListener listener = new NodeListener(
const ScannerOptions(), compiler.reporter, null);
Parser parser = new Parser(listener,
- yieldIsKeyword: element.asyncMarker.isYielding,
- awaitIsKeyword: element.asyncMarker.isAsync);
+ asyncAwaitKeywordsEnabled: element.asyncMarker != AsyncMarker.SYNC);
parser.parseStatement(tokens);
Node node = listener.popNode();
TreeElements elements = compiler.resolveNodeStatement(node, element);
diff --git a/tests/compiler/dart2js/unparser_test.dart b/tests/compiler/dart2js/unparser_test.dart
index 4b9a815..e19ed0d 100644
--- a/tests/compiler/dart2js/unparser_test.dart
+++ b/tests/compiler/dart2js/unparser_test.dart
@@ -98,6 +98,57 @@
testUnparseTopLevelWithMetadata('export "søhest";');
}
+testConditionalImport() {
+ testUnparseTopLevelWithMetadata(
+ 'import "søhest" if(some.dotted.id)"other";');
+ testUnparseTopLevelWithMetadata(
+ 'import "søhest" if(id=="some str")"other";');
+ testUnparseTopLevelWithMetadata(
+ 'import "søhest"'
+ ' if(id=="some str")"other"'
+ ' if(id)"other2";');
+ testUnparseTopLevelWithMetadata(
+ 'import "søhest" if(some.dotted.id)"other" as fiskehest;');
+ testUnparseTopLevelWithMetadata(
+ 'import "søhest" if(id=="some str")"other" as fiskehest;');
+ testUnparseTopLevelWithMetadata(
+ 'import "søhest"'
+ ' if(id=="some str")"other"'
+ ' if(id)"other2"'
+ ' as fiskehest;');
+ testUnparseTopLevelWithMetadata(
+ 'import "søhest" if(some.dotted.id)"other" deferred as fiskehest;');
+ testUnparseTopLevelWithMetadata(
+ 'import "søhest" if(id=="some str")"other" deferred as fiskehest;');
+ testUnparseTopLevelWithMetadata(
+ 'import "søhest"'
+ ' if(id=="some str")"other"'
+ ' if(id)"other2"'
+ ' deferred as fiskehest;');
+ testUnparseTopLevelWithMetadata(
+ 'import "søhest"'
+ ' if(id=="some str")"other"'
+ ' if(id)"other2"'
+ ' deferred as fiskehest'
+ ' show foo,bar;');
+}
+
+testConditionalExport() {
+ testUnparseTopLevelWithMetadata(
+ 'export "søhest" if(some.dotted.id)"other";');
+ testUnparseTopLevelWithMetadata(
+ 'export "søhest" if(id=="some str")"other";');
+ testUnparseTopLevelWithMetadata(
+ 'export "søhest"'
+ ' if(id=="some str")"other"'
+ ' if(id)"other2";');
+ testUnparseTopLevelWithMetadata(
+ 'export "søhest"'
+ ' if(id=="some str")"other"'
+ ' if(id)"other2"'
+ ' show foo,bar;');
+}
+
testPart() {
testUnparseTopLevelWithMetadata('part "søhest";');
}
@@ -383,6 +434,8 @@
testLibraryName();
testImport();
testExport();
+ testConditionalImport();
+ testConditionalExport();
testPart();
testPartOf();
testCombinators();
diff --git a/tests/compiler/dart2js_extra/23828_test.dart b/tests/compiler/dart2js_extra/23828_test.dart
index b6312a3..53c2221 100644
--- a/tests/compiler/dart2js_extra/23828_test.dart
+++ b/tests/compiler/dart2js_extra/23828_test.dart
@@ -6,7 +6,9 @@
// Used to fail when methods contain a name starting with `get`
import 'package:expect/expect.dart';
-confuse(x) { return x; return x; }
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
class MA {
noSuchMethod(i) => Expect.equals(i.positionalArguments.length, 1);
diff --git a/tests/compiler/dart2js_extra/consistent_add_error_test.dart b/tests/compiler/dart2js_extra/consistent_add_error_test.dart
new file mode 100644
index 0000000..22927e2
--- /dev/null
+++ b/tests/compiler/dart2js_extra/consistent_add_error_test.dart
@@ -0,0 +1,187 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that optimized '+' and slow path '+' produce the same error.
+
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
+
+void check2(String name, name1, f1, name2, f2) {
+ Error trap(part, f) {
+ try {
+ f();
+ } catch (e) {
+ return e;
+ }
+ Expect.fail('should throw: $name.$part');
+ }
+ var e1 = trap(name1, f1);
+ var e2 = trap(name2, f2);
+ var s1 = '$e1';
+ var s2 = '$e2';
+ Expect.equals(s1, s2, '\n $name.$name1: "$s1"\n $name.$name2: "$s2"\n');
+}
+
+void check(String name, f1, f2, [f3, f4, f5, f6, f7]) {
+ check2(name, 'f1', f1, 'f2', f2);
+ if (f3 != null) check2(name, 'f1', f1, 'f3', f3);
+ if (f4 != null) check2(name, 'f1', f1, 'f4', f4);
+ if (f5 != null) check2(name, 'f1', f1, 'f5', f5);
+ if (f6 != null) check2(name, 'f1', f1, 'f6', f6);
+ if (f7 != null) check2(name, 'f1', f1, 'f7', f7);
+}
+
+class IntPlusNull {
+ static f1() {
+ return confuse(1) + confuse(null);
+ }
+
+ static f2() {
+ return confuse(1) + null;
+ }
+
+ static f3() {
+ return (confuse(1) as int) + confuse(null);
+ }
+
+ static f4() {
+ return (confuse(1) as int) + null;
+ }
+
+ static f5() {
+ var a = confuse(true) ? 1 : 2; // Small int with unknown value.
+ return a + confuse(null);
+ }
+
+ static f6() {
+ var a = confuse(true) ? 1 : 2; // Small int with unknown value.
+ return a + null;
+ }
+
+ static f7() {
+ return 1 + null;
+ }
+
+ static test() {
+ check('IntPlusNull', f1, f2, f3, f4, f5, f6, f7);
+ }
+}
+
+class StringPlusNull {
+ static f1() {
+ return confuse('a') + confuse(null);
+ }
+
+ static f2() {
+ return confuse('a') + null;
+ }
+
+ static f3() {
+ return (confuse('a') as String) + confuse(null);
+ }
+
+ static f4() {
+ return (confuse('a') as String) + null;
+ }
+
+ static f5() {
+ var a = confuse(true) ? 'a' : 'bc';
+ return a + confuse(null);
+ }
+
+ static f6() {
+ var a = confuse(true) ? 'a' : 'bc';
+ return a + null;
+ }
+
+ static f7() {
+ return 'a' + null;
+ }
+
+ static test() {
+ check('StringPlusNull', f1, f2, f3, f4, f5, f6, f7);
+ }
+}
+
+class IntPlusString {
+ static f1() {
+ return confuse(1) + confuse('a');
+ }
+
+ static f2() {
+ return confuse(1) + 'a';
+ }
+
+ static f3() {
+ var a = confuse(true) ? 1 : 2; // Small int with unknown value.
+ return a + confuse('a');
+ }
+
+ static f4() {
+ return (confuse(1) as int) + confuse('a');
+ }
+
+ static f5() {
+ return (confuse(1) as int) + 'a';
+ }
+
+ static f6() {
+ var a = confuse(true) ? 1 : 2; // Small int with unknown value.
+ return a + 'a';
+ }
+
+ static f7() {
+ return 1 + 'a';
+ }
+
+ static test() {
+ check('IntPlusString', f1, f2, f3, f4, f5, f6, f7);
+ }
+}
+
+class StringPlusInt {
+ static f1() {
+ return confuse('a') + confuse(1);
+ }
+
+ static f2() {
+ return confuse('a') + 1;
+ }
+
+ static f3() {
+ return (confuse('a') as String) + confuse(1);
+ }
+
+ static f4() {
+ return (confuse('a') as String) + 1;
+ }
+
+ static f5() {
+ var a = confuse(true) ? 'a' : 'bc';
+ return a + confuse(1);
+ }
+
+ static f6() {
+ var a = confuse(true) ? 'a' : 'bc';
+ return a + 1;
+ }
+
+ static f7() {
+ return 'a' + 1;
+ }
+
+ static test() {
+ check('StringPlusInt', f1, f2, f3, f4, f5, f6, f7);
+ }
+}
+
+main() {
+ IntPlusNull.test();
+ StringPlusNull.test();
+ IntPlusString.test();
+ StringPlusInt.test();
+}
diff --git a/tests/compiler/dart2js_extra/consistent_null_add_error_test.dart b/tests/compiler/dart2js_extra/consistent_null_add_error_test.dart
new file mode 100644
index 0000000..2c47018
--- /dev/null
+++ b/tests/compiler/dart2js_extra/consistent_null_add_error_test.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that optimized 'null + x' and slow path '+' produce the same error.
+//
+// They don't, sometimes we generate null.$add, sometimes JSNull_methods.$add.
+
+
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
+
+void check2(String name, name1, f1, name2, f2) {
+ Error trap(part, f) {
+ try {
+ f();
+ } catch (e) {
+ return e;
+ }
+ Expect.fail('should throw: $name.$part');
+ }
+ var e1 = trap(name1, f1);
+ var e2 = trap(name2, f2);
+ var s1 = '$e1';
+ var s2 = '$e2';
+ Expect.equals(s1, s2, '\n $name.$name1: "$s1"\n $name.$name2: "$s2"\n');
+}
+
+void check(String name, f1, f2, [f3, f4, f5, f6]) {
+ check2(name, 'f1', f1, 'f2', f2);
+ if (f3 != null) check2(name, 'f1', f1, 'f3', f3);
+ if (f4 != null) check2(name, 'f1', f1, 'f4', f4);
+ if (f5 != null) check2(name, 'f1', f1, 'f5', f5);
+ if (f6 != null) check2(name, 'f1', f1, 'f6', f6);
+}
+
+
+class NullPlusInt {
+ static f1() {
+ return confuse(null) + confuse(1);
+ }
+
+ static f2() {
+ return confuse(null) + 1;
+ }
+
+ static f3() {
+ return (confuse(null) as int) + confuse(1);
+ }
+
+ static f4() {
+ return (confuse(null) as int) + 1;
+ }
+
+ static f5() {
+ var a = null;
+ return a + confuse(1);
+ }
+
+ static f6() {
+ var a = null;
+ return a + 1;
+ }
+
+ static test() {
+ // Sometimes we generate null.$add, sometimes JSNull_methods.$add. The best
+ // we can do is check there is an error.
+ check('NullPlusInt', f1, f1);
+ check('NullPlusInt', f2, f2);
+ check('NullPlusInt', f3, f3);
+ check('NullPlusInt', f4, f4);
+ check('NullPlusInt', f5, f5);
+ check('NullPlusInt', f6, f6);
+ }
+}
+
+main() {
+ NullPlusInt.test();
+}
diff --git a/tests/compiler/dart2js_extra/consistent_subtract_error_test.dart b/tests/compiler/dart2js_extra/consistent_subtract_error_test.dart
new file mode 100644
index 0000000..757c37d
--- /dev/null
+++ b/tests/compiler/dart2js_extra/consistent_subtract_error_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that optimized '-' and slow path '-' produce the same error.
+
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
+
+void check2(String name, name1, f1, name2, f2) {
+ Error trap(part, f) {
+ try {
+ f();
+ } catch (e) {
+ return e;
+ }
+ Expect.fail('should throw: $name.$part');
+ }
+ var e1 = trap(name1, f1);
+ var e2 = trap(name2, f2);
+ var s1 = '$e1';
+ var s2 = '$e2';
+ Expect.equals(s1, s2, '\n $name.$name1: "$s1"\n $name.$name2: "$s2"\n');
+}
+
+void check(String name, f1, f2, [f3, f4, f5, f6, f7]) {
+ check2(name, 'f1', f1, 'f2', f2);
+ if (f3 != null) check2(name, 'f1', f1, 'f3', f3);
+ if (f4 != null) check2(name, 'f1', f1, 'f4', f4);
+ if (f5 != null) check2(name, 'f1', f1, 'f5', f5);
+ if (f6 != null) check2(name, 'f1', f1, 'f6', f6);
+ if (f7 != null) check2(name, 'f1', f1, 'f7', f7);
+}
+
+class IntMinusNull {
+ static f1() {
+ return confuse(1) - confuse(null);
+ }
+
+ static f2() {
+ return confuse(1) - null;
+ }
+
+ static f3() {
+ return (confuse(1) as int) - confuse(null);
+ }
+
+ static f4() {
+ return (confuse(1) as int) - null;
+ }
+
+ static f5() {
+ var a = confuse(true) ? 1 : 2; // Small int with unknown value.
+ return a - confuse(null);
+ }
+
+ static f6() {
+ var a = confuse(true) ? 1 : 2; // Small int with unknown value.
+ return a - null;
+ }
+
+ static f7() {
+ return 1 - null;
+ }
+
+ static test() {
+ check('IntMinusNull', f1, f2, f3, f4, f5, f6, f7);
+ }
+}
+
+class IntMinusString {
+ static f1() {
+ return confuse(1) - confuse('a');
+ }
+
+ static f2() {
+ return confuse(1) - 'a';
+ }
+
+ static f3() {
+ var a = confuse(true) ? 1 : 2; // Small int with unknown value.
+ return a - confuse('a');
+ }
+
+ static f4() {
+ return (confuse(1) as int) - confuse('a');
+ }
+
+ static f5() {
+ return (confuse(1) as int) - 'a';
+ }
+
+ static f6() {
+ var a = confuse(true) ? 1 : 2; // Small int with unknown value.
+ return a - 'a';
+ }
+
+ static f7() {
+ return 1 - 'a';
+ }
+
+ static test() {
+ check('IntMinusString', f1, f2, f3, f4, f5, f6, f7);
+ }
+}
+
+main() {
+ IntMinusNull.test();
+ IntMinusString.test();
+}
diff --git a/tests/compiler/dart2js_extra/hash_code_test.dart b/tests/compiler/dart2js_extra/hash_code_test.dart
index 0c5c4b3..3329a38 100644
--- a/tests/compiler/dart2js_extra/hash_code_test.dart
+++ b/tests/compiler/dart2js_extra/hash_code_test.dart
@@ -7,9 +7,11 @@
// dart2js specific test to make sure hashCode on intercepted types behaves as
// intended.
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
class Hasher {
- confuse(x) => [1, 'x', true, null, x].last;
hash(x) => confuse(x).hashCode;
}
diff --git a/tests/compiler/dart2js_extra/many_constants_test.dart b/tests/compiler/dart2js_extra/many_constants_test.dart
new file mode 100644
index 0000000..5027b50
--- /dev/null
+++ b/tests/compiler/dart2js_extra/many_constants_test.dart
@@ -0,0 +1,87 @@
+// 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.
+
+// This program has many similar constants that should all have distinct
+// identities. They are sufficiently similar to have name collisions and need
+// ordering by constant value.
+
+import "package:expect/expect.dart";
+
+enum E { A, B, C, D }
+
+class Z {
+ final a, b, c, d, e, f;
+ const Z({this.a: 1, this.b: 1, this.c: 1, this.d: 1, this.e: 1, this.f: 1});
+}
+
+const c1 = const {};
+const c2 = const <int, int>{};
+const c3 = const <dynamic, int>{};
+const c4 = const <int, dynamic>{};
+const l1 = const [];
+const l2 = const <int>[];
+const l3 = const <String>[];
+const l4 = const <num>[];
+
+const ll1 = const [1, 2, 3, 4, 5, 6, 7];
+const ll2 = const [1, 8, 3, 4, 5, 6, 7];
+const ll3 = const [1, 2, 8, 4, 5, 6, 7];
+const ll4 = const [1, 2, 3, 4, 8, 6, 7];
+
+const m1 = const {1: 1, 2: 2};
+const m2 = const {1: 2, 2: 1};
+const m3 = const {1: 1, 2: 1};
+const m4 = const {1: 2, 2: 2};
+const m5 = const {2: 1, 1: 2};
+const m6 = const {2: 2, 1: 1};
+const m7 = const {2: 1, 1: 1};
+const m8 = const {2: 2, 1: 2};
+const m9 = const <int,int>{1: 1, 2: 2};
+const mA = const <int,int>{1: 2, 2: 1};
+const mB = const <int,int>{1: 1, 2: 1};
+const mC = const <int,int>{1: 2, 2: 2};
+
+const mE1 = const {E.A: E.B};
+const mE2 = const {E.A: E.C};
+const mE3 = const {E.A: 0, E.B: 0};
+const mE4 = const {E.A: 0, E.C: 0};
+const mE5 = const {E.A: 0, E.B: 0, E.C: 4};
+const mE6 = const {E.A: 0, E.B: 0, E.C: 2};
+const mE7 = const {E.A: 0, E.B: 0, E.C: 3};
+const mE8 = const {E.A: 0, E.B: 0, E.C: 1};
+
+const z1 = const Z(f: 3);
+const z2 = const Z(f: 2);
+const z3 = const Z(f: 1);
+const z4 = const Z(e: 2);
+const z5 = const Z(d: 3);
+const z6 = const Z(d: 2);
+
+makeAll() => {
+ 'E.A': E.A, 'E.B': E.B, 'E.C': E.C, 'E.D': E.D,
+ 'c1': c1, 'c2': c2, 'c3': c3, 'c4': c4,
+ 'l1': l1, 'l2': l2, 'l3': l3, 'l4': l4,
+ 'll1': ll1, 'll2': ll2, 'll3': ll3, 'l4': ll4,
+ 'm1': m1, 'm2': m2, 'm3': m3, 'm4': m4,
+ 'm5': m5, 'm6': m6, 'm7': m7, 'm8': m8,
+ 'm9': m9, 'mA': mA, 'mB': mB, 'mC': mC,
+ 'mE1': mE1, 'mE2': mE2, 'mE3': mE3, 'mE4': mE4,
+ 'mE5': mE5, 'mE6': mE6, 'mE7': mE7, 'mE8': mE8,
+ 'z1': z1, 'z2': z2, 'z3': z3, 'z4': z4, 'z5': z5, 'z6': z6,
+};
+
+main() {
+ var all1 = makeAll();
+ var all2 = makeAll();
+
+ for (var name1 in all1.keys) {
+ var e1 = all1[name1];
+ for (var name2 in all2.keys) {
+ if (name1 == name2) continue;
+ var e2 = all2[name2];
+ Expect.isFalse(identical(e1, e2),
+ 'Different instances $name1: $e1 $name2: $e2');
+ }
+ }
+}
diff --git a/tests/compiler/dart2js_extra/mirror_invalid_invoke2_test.dart b/tests/compiler/dart2js_extra/mirror_invalid_invoke2_test.dart
index 9b6d8d2..49b74cf 100644
--- a/tests/compiler/dart2js_extra/mirror_invalid_invoke2_test.dart
+++ b/tests/compiler/dart2js_extra/mirror_invalid_invoke2_test.dart
@@ -17,7 +17,7 @@
class C {
foo() => 1;
- @DontInline
+ @NoInline()
// Use a closure to prevent inlining until the annotation is implemented.
bar() => () => 2;
}
diff --git a/tests/compiler/dart2js_extra/mirror_invalid_invoke3_test.dart b/tests/compiler/dart2js_extra/mirror_invalid_invoke3_test.dart
index e142253..4236b3f 100644
--- a/tests/compiler/dart2js_extra/mirror_invalid_invoke3_test.dart
+++ b/tests/compiler/dart2js_extra/mirror_invalid_invoke3_test.dart
@@ -17,7 +17,7 @@
class C {
static foo() => 1;
- @DontInline
+ @NoInline()
// Use a closure to prevent inlining until the annotation is implemented.
static bar() => () => 2;
}
diff --git a/tests/compiler/dart2js_extra/mirror_invalid_invoke_test.dart b/tests/compiler/dart2js_extra/mirror_invalid_invoke_test.dart
index 09e8d65..35df0e0 100644
--- a/tests/compiler/dart2js_extra/mirror_invalid_invoke_test.dart
+++ b/tests/compiler/dart2js_extra/mirror_invalid_invoke_test.dart
@@ -16,7 +16,7 @@
foo() => 1;
-@DontInline
+@NoInline()
// Use a closure to prevent inlining until the annotation is implemented.
bar() => () => 2;
diff --git a/tests/compiler/dart2js_extra/mirrors_used_closure_test.dart b/tests/compiler/dart2js_extra/mirrors_used_closure_test.dart
index 28c19a8..12551cf 100644
--- a/tests/compiler/dart2js_extra/mirrors_used_closure_test.dart
+++ b/tests/compiler/dart2js_extra/mirrors_used_closure_test.dart
@@ -18,12 +18,9 @@
bar() => 33;
}
-// Uses DateTime.now to make it impossible to predict.
-// Uses recursive call to make it harder to inline.
-confuse(x) {
- if (new DateTime.now().millisecondsSinceEpoch == 42) return confuse(x + 1);
- return x;
-}
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
main() {
var f = [new A(), new B()][confuse(0)].bar;
diff --git a/tests/corelib/apply_test.dart b/tests/corelib/apply_test.dart
index e06cf6d..0ad85b1 100644
--- a/tests/corelib/apply_test.dart
+++ b/tests/corelib/apply_test.dart
@@ -25,14 +25,9 @@
int call(int x, int y) => x + y;
}
-confuse() {
- try {
- throw [Function.apply];
- } catch (e) {
- return e[0];
- }
- return null;
-}
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
main() {
testMap(res, func, map) {
@@ -62,7 +57,7 @@
testList(42, cfoo, [32]);
// Test that apply works even with a different name.
- var app = confuse();
+ var app = confuse(Function.apply);
Expect.equals(42, app(test2, [22, 20]));
// Test that apply can itself be applied.
diff --git a/tests/corelib/date_time4_test.dart b/tests/corelib/date_time4_test.dart
index 7e936ff..46c1c10 100644
--- a/tests/corelib/date_time4_test.dart
+++ b/tests/corelib/date_time4_test.dart
@@ -6,11 +6,21 @@
// Test fromString with 6 digits after the decimal point.
+bool get supportsMicroseconds =>
+ new DateTime.fromMicrosecondsSinceEpoch(1).microsecondsSinceEpoch == 1;
+
+
main() {
+ if (supportsMicroseconds) {
+ testMicrosecondPrecision();
+ } else {
+ testMillisecondPrecision();
+ }
+}
+
+void testMillisecondPrecision() {
// We only support milliseconds. If the user supplies more data (the "51"
// here), we round.
- // If (eventually) we support more than just milliseconds this test could
- // fail. Please update the test in this case.
DateTime dt1 = DateTime.parse("1999-01-02 23:59:59.999519");
Expect.equals(1999, dt1.year);
Expect.equals(1, dt1.month);
@@ -48,5 +58,48 @@
Expect.equals(13, dt1.second);
Expect.equals(752, dt1.millisecond);
Expect.equals(true, dt1.isUtc);
-
+}
+
+void testMicrosecondPrecision() {
+ DateTime dt1 = DateTime.parse("1999-01-02 23:59:59.999519");
+ Expect.equals(1999, dt1.year);
+ Expect.equals(1, dt1.month);
+ Expect.equals(2, dt1.day);
+ Expect.equals(23, dt1.hour);
+ Expect.equals(59, dt1.minute);
+ Expect.equals(59, dt1.second);
+ Expect.equals(999, dt1.millisecond);
+ Expect.equals(519, dt1.microsecond);
+ Expect.equals(false, dt1.isUtc);
+ dt1 = DateTime.parse("1999-01-02 23:58:59.999519Z");
+ Expect.equals(1999, dt1.year);
+ Expect.equals(1, dt1.month);
+ Expect.equals(2, dt1.day);
+ Expect.equals(23, dt1.hour);
+ Expect.equals(58, dt1.minute);
+ Expect.equals(59, dt1.second);
+ Expect.equals(999, dt1.millisecond);
+ Expect.equals(519, dt1.microsecond);
+ Expect.equals(true, dt1.isUtc);
+ dt1 = DateTime.parse("0009-09-09 09:09:09.009411Z");
+ Expect.equals(9, dt1.year);
+ Expect.equals(9, dt1.month);
+ Expect.equals(9, dt1.day);
+ Expect.equals(9, dt1.hour);
+ Expect.equals(9, dt1.minute);
+ Expect.equals(9, dt1.second);
+ Expect.equals(9, dt1.millisecond);
+ Expect.equals(411, dt1.microsecond);
+ Expect.equals(true, dt1.isUtc);
+ String svnDate = "2012-03-30T04:28:13.752341Z";
+ dt1 = DateTime.parse(svnDate);
+ Expect.equals(2012, dt1.year);
+ Expect.equals(3, dt1.month);
+ Expect.equals(30, dt1.day);
+ Expect.equals(4, dt1.hour);
+ Expect.equals(28, dt1.minute);
+ Expect.equals(13, dt1.second);
+ Expect.equals(752, dt1.millisecond);
+ Expect.equals(341, dt1.microsecond);
+ Expect.equals(true, dt1.isUtc);
}
diff --git a/tests/corelib/date_time_parse_test.dart b/tests/corelib/date_time_parse_test.dart
index 2f48923..85f183a 100644
--- a/tests/corelib/date_time_parse_test.dart
+++ b/tests/corelib/date_time_parse_test.dart
@@ -9,10 +9,19 @@
Expect.equals(expected, actual); // Only checks if they are at the same time.
Expect.equals(expected.isUtc, actual.isUtc);
}
+
+bool get supportsMicroseconds =>
+ new DateTime.fromMicrosecondsSinceEpoch(1).microsecondsSinceEpoch == 1;
+
main() {
check(new DateTime(2012, 02, 27, 13, 27), "2012-02-27 13:27:00");
- check(new DateTime.utc(2012, 02, 27, 13, 27, 0, 123),
- "2012-02-27 13:27:00.123456z");
+ if (supportsMicroseconds) {
+ check(new DateTime.utc(2012, 02, 27, 13, 27, 0, 123, 456),
+ "2012-02-27 13:27:00.123456z");
+ } else {
+ check(new DateTime.utc(2012, 02, 27, 13, 27, 0, 123, 456),
+ "2012-02-27 13:27:00.123z");
+ }
check(new DateTime(2012, 02, 27, 13, 27), "20120227 13:27:00");
check(new DateTime(2012, 02, 27, 13, 27), "20120227T132700");
check(new DateTime(2012, 02, 27), "20120227");
@@ -31,8 +40,15 @@
check(new DateTime.utc(2015, 02, 14, 13, 0, 0, 0),
"2015-02-15T00:00:00+11:00");
- check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 501),
- "2015-02-15T00:00:00.5005Z");
- check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 512),
- "2015-02-15T00:00:00.5115Z");
+ if (supportsMicroseconds) {
+ check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 500, 500),
+ "2015-02-15T00:00:00.500500Z");
+ check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 511, 500),
+ "2015-02-15T00:00:00.511500Z");
+ } else {
+ check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 501),
+ "2015-02-15T00:00:00.501Z");
+ check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 512),
+ "2015-02-15T00:00:00.512Z");
+ }
}
diff --git a/tests/corelib/date_time_test.dart b/tests/corelib/date_time_test.dart
index 79dcdd9..efb2206 100644
--- a/tests/corelib/date_time_test.dart
+++ b/tests/corelib/date_time_test.dart
@@ -6,6 +6,9 @@
// Dart test program for DateTime.
+bool get supportsMicroseconds =>
+ new DateTime.fromMicrosecondsSinceEpoch(1).microsecondsSinceEpoch == 1;
+
// Identical to _MAX_MILLISECONDS_SINCE_EPOCH in date_time.dart
const int _MAX_MILLISECONDS = 8640000000000000;
@@ -26,13 +29,25 @@
Expect.isFalse(t1.isUtc);
}
-void testValue() {
+void testMillisecondsSinceEpoch() {
var dt1 = new DateTime.now();
var millisecondsSinceEpoch = dt1.millisecondsSinceEpoch;
var dt2 = new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch);
Expect.equals(millisecondsSinceEpoch, dt2.millisecondsSinceEpoch);
}
+void testMicrosecondsSinceEpoch() {
+ var dt1 = new DateTime.fromMillisecondsSinceEpoch(1);
+ var microsecondsSinceEpoch = dt1.microsecondsSinceEpoch;
+ var dt2 = new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch);
+ Expect.equals(microsecondsSinceEpoch, dt2.microsecondsSinceEpoch);
+
+ dt1 = new DateTime.now();
+ microsecondsSinceEpoch = dt1.microsecondsSinceEpoch;
+ dt2 = new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch);
+ Expect.equals(microsecondsSinceEpoch, dt2.microsecondsSinceEpoch);
+}
+
void testFarAwayDates() {
DateTime dt =
new DateTime.fromMillisecondsSinceEpoch(1000000000000001, isUtc: true);
@@ -43,6 +58,7 @@
Expect.equals(46, dt.minute);
Expect.equals(40, dt.second);
Expect.equals(1, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001, isUtc: true);
Expect.equals(-29719, dt.year);
Expect.equals(4, dt.month);
@@ -51,6 +67,7 @@
Expect.equals(13, dt.minute);
Expect.equals(19, dt.second);
Expect.equals(999, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
// Same with local zone.
dt = new DateTime.fromMillisecondsSinceEpoch(1000000000000001);
Expect.equals(33658, dt.year);
@@ -62,6 +79,7 @@
Expect.equals(true, dt.minute % 15 == 46 % 15);
Expect.equals(40, dt.second);
Expect.equals(1, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001);
Expect.equals(-29719, dt.year);
Expect.equals(4, dt.month);
@@ -72,6 +90,52 @@
Expect.equals(true, dt.minute % 15 == 13);
Expect.equals(19, dt.second);
Expect.equals(999, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
+
+ if (!supportsMicroseconds) return;
+ dt =
+ new DateTime.fromMicrosecondsSinceEpoch(1000000000000000001, isUtc: true);
+ Expect.equals(33658, dt.year);
+ Expect.equals(9, dt.month);
+ Expect.equals(27, dt.day);
+ Expect.equals(1, dt.hour);
+ Expect.equals(46, dt.minute);
+ Expect.equals(40, dt.second);
+ Expect.equals(0, dt.millisecond);
+ Expect.equals(1, dt.microsecond);
+ dt = new DateTime.fromMicrosecondsSinceEpoch(
+ -1000000000000000001, isUtc: true);
+ Expect.equals(-29719, dt.year);
+ Expect.equals(4, dt.month);
+ Expect.equals(5, dt.day);
+ Expect.equals(22, dt.hour);
+ Expect.equals(13, dt.minute);
+ Expect.equals(19, dt.second);
+ Expect.equals(999, dt.millisecond);
+ Expect.equals(999, dt.microsecond);
+ // Same with local zone.
+ dt = new DateTime.fromMicrosecondsSinceEpoch(1000000000000000001);
+ Expect.equals(33658, dt.year);
+ Expect.equals(9, dt.month);
+ Expect.equals(true, dt.day == 27 || dt.day == 26);
+ // Not much we can test for local hour.
+ Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
+ // Timezones can have offsets down to 15 minute.
+ Expect.equals(true, dt.minute % 15 == 46 % 15);
+ Expect.equals(40, dt.second);
+ Expect.equals(0, dt.millisecond);
+ Expect.equals(1, dt.microsecond);
+ dt = new DateTime.fromMicrosecondsSinceEpoch(-1000000000000000001);
+ Expect.equals(-29719, dt.year);
+ Expect.equals(4, dt.month);
+ Expect.equals(true, 5 == dt.day || 6 == dt.day);
+ // Not much we can test for local hour.
+ Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
+ // Timezones can have offsets down to 15 minute.
+ Expect.equals(true, dt.minute % 15 == 13);
+ Expect.equals(19, dt.second);
+ Expect.equals(999, dt.millisecond);
+ Expect.equals(999, dt.microsecond);
}
void testEquivalentYears() {
@@ -86,6 +150,7 @@
Expect.equals(0, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
dt = new DateTime.fromMillisecondsSinceEpoch(-63108000000, isUtc: true);
Expect.equals(1968, dt.year);
Expect.equals(1, dt.month);
@@ -94,6 +159,7 @@
Expect.equals(0, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
dt = new DateTime.fromMillisecondsSinceEpoch(-94644000000, isUtc: true);
Expect.equals(1967, dt.year);
Expect.equals(1, dt.month);
@@ -102,6 +168,7 @@
Expect.equals(0, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
dt = new DateTime.fromMillisecondsSinceEpoch(-126180000000, isUtc: true);
Expect.equals(1966, dt.year);
Expect.equals(1, dt.month);
@@ -110,6 +177,7 @@
Expect.equals(0, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
dt = new DateTime.fromMillisecondsSinceEpoch(-157716000000, isUtc: true);
Expect.equals(1965, dt.year);
Expect.equals(1, dt.month);
@@ -118,6 +186,7 @@
Expect.equals(0, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
dt = new DateTime.fromMillisecondsSinceEpoch(-2177402400000, isUtc: true);
Expect.equals(1901, dt.year);
Expect.equals(1, dt.month);
@@ -126,6 +195,7 @@
Expect.equals(0, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
dt = new DateTime.fromMillisecondsSinceEpoch(-5333076000000, isUtc: true);
Expect.equals(1801, dt.year);
Expect.equals(1, dt.month);
@@ -134,6 +204,7 @@
Expect.equals(0, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
dt = new DateTime.fromMillisecondsSinceEpoch(-8520285600000, isUtc: true);
Expect.equals(1700, dt.year);
Expect.equals(1, dt.month);
@@ -142,6 +213,7 @@
Expect.equals(0, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
dt = new DateTime.fromMillisecondsSinceEpoch(-14831719200000, isUtc: true);
Expect.equals(1500, dt.year);
Expect.equals(1, dt.month);
@@ -150,6 +222,7 @@
Expect.equals(0, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
dt = new DateTime.fromMillisecondsSinceEpoch(-59011408800000, isUtc: true);
Expect.equals(100, dt.year);
Expect.equals(1, dt.month);
@@ -158,6 +231,7 @@
Expect.equals(0, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
dt = new DateTime.fromMillisecondsSinceEpoch(-62011408800000, isUtc: true);
Expect.equals(4, dt.year);
Expect.equals(12, dt.month);
@@ -166,6 +240,7 @@
Expect.equals(40, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
dt = new DateTime.fromMillisecondsSinceEpoch(-64011408800000, isUtc: true);
Expect.equals(-59, dt.year);
Expect.equals(7, dt.month);
@@ -174,6 +249,7 @@
Expect.equals(6, dt.minute);
Expect.equals(40, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
final int SECONDS_YEAR_2035 = 2051222400;
dt = new DateTime.fromMillisecondsSinceEpoch(SECONDS_YEAR_2035 * 1000 + 1,
isUtc: true);
@@ -184,6 +260,7 @@
Expect.equals(0, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(1, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
dt = new DateTime.fromMillisecondsSinceEpoch(SECONDS_YEAR_2035 * 1000 - 1,
isUtc: true);
Expect.equals(2034, dt.year);
@@ -193,6 +270,8 @@
Expect.equals(59, dt.minute);
Expect.equals(59, dt.second);
Expect.equals(999, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
+
dt = new DateTime.utc(2035, 1, 1, 0, 0, 0, 1);
Expect.equals(SECONDS_YEAR_2035 * 1000 + 1, dt.millisecondsSinceEpoch);
dt = new DateTime.utc(2034, 12, 31, 23, 59, 59, 999);
@@ -211,6 +290,8 @@
(2034 == dt.year && 12 == dt.month && 31 == dt.day));
Expect.equals(59, dt.second);
Expect.equals(999, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
+
dt2 = new DateTime(
dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
dt.millisecond);
@@ -223,6 +304,8 @@
Expect.equals(20, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
+
// Internally this will use the maximum value for the native calls.
dt = new DateTime(2036, 7, 18, 13, 20);
Expect.equals(2036, dt.year);
@@ -232,7 +315,46 @@
Expect.equals(20, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
Expect.equals("2036-07-18 13:20:00.000", dt.toString());
+
+ if (!supportsMicroseconds) return;
+
+ dt = new DateTime.utc(2035, 1, 1, 0, 0, 0, 0, 1);
+ Expect.equals(SECONDS_YEAR_2035 * 1000000 + 1, dt.microsecondsSinceEpoch);
+ dt = new DateTime.utc(2034, 12, 31, 23, 59, 59, 999, 999);
+ Expect.equals(SECONDS_YEAR_2035 * 1000000 - 1, dt.microsecondsSinceEpoch);
+ dt = new DateTime.fromMicrosecondsSinceEpoch(SECONDS_YEAR_2035 * 1000000 + 1);
+ Expect.equals(true, (2035 == dt.year && 1 == dt.month && 1 == dt.day) ||
+ (2034 == dt.year && 12 == dt.month && 31 == dt.day));
+ Expect.equals(0, dt.second);
+ Expect.equals(0, dt.millisecond);
+ Expect.equals(1, dt.microsecond);
+ dt2 = new DateTime(
+ dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
+ dt.millisecond, dt.microsecond);
+ Expect.equals(dt.microsecondsSinceEpoch, dt2.microsecondsSinceEpoch);
+ dt = new DateTime.fromMicrosecondsSinceEpoch(SECONDS_YEAR_2035 * 1000000 - 1);
+ Expect.equals(true, (2035 == dt.year && 1 == dt.month && 1 == dt.day) ||
+ (2034 == dt.year && 12 == dt.month && 31 == dt.day));
+ Expect.equals(59, dt.second);
+ Expect.equals(999, dt.millisecond);
+ Expect.equals(999, dt.microsecond);
+
+ dt2 = new DateTime(
+ dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
+ dt.millisecond, dt.microsecond);
+ Expect.equals(dt.millisecondsSinceEpoch, dt2.millisecondsSinceEpoch);
+ dt = new DateTime.fromMicrosecondsSinceEpoch(2100000000 * 1000000,
+ isUtc: true);
+ Expect.equals(2036, dt.year);
+ Expect.equals(7, dt.month);
+ Expect.equals(18, dt.day);
+ Expect.equals(13, dt.hour);
+ Expect.equals(20, dt.minute);
+ Expect.equals(0, dt.second);
+ Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
}
void testExtremes() {
@@ -245,6 +367,7 @@
Expect.equals(0, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
Expect.equals(-271821, dt.year);
Expect.equals(4, dt.month);
@@ -253,6 +376,7 @@
Expect.equals(0, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
// Make sure that we can build the extreme dates in local too.
dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
@@ -280,6 +404,35 @@
dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
Expect.throws(() => new DateTime.utc(dt.year, dt.month, dt.day,
dt.hour, dt.minute, 0, -1));
+
+ if (!supportsMicroseconds) return;
+
+ dt = new DateTime.fromMicrosecondsSinceEpoch(_MAX_MILLISECONDS * 1000);
+ dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
+ Expect.equals(_MAX_MILLISECONDS * 1000, dt.microsecondsSinceEpoch);
+ dt = new DateTime.fromMicrosecondsSinceEpoch(-_MAX_MILLISECONDS * 1000);
+ dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
+ Expect.equals(-_MAX_MILLISECONDS * 1000, dt.microsecondsSinceEpoch);
+ Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
+ _MAX_MILLISECONDS * 1000 + 1, isUtc: true));
+ Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
+ -_MAX_MILLISECONDS * 1000 - 1, isUtc: true));
+ Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
+ _MAX_MILLISECONDS * 1000 + 1));
+ Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
+ -_MAX_MILLISECONDS * 1000 - 1));
+ dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
+ Expect.throws(() => new DateTime(dt.year, dt.month, dt.day,
+ dt.hour, dt.minute, 0, 0, 1));
+ dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS, isUtc: true);
+ Expect.throws(() => new DateTime.utc(dt.year, dt.month, dt.day,
+ dt.hour, dt.minute, 0, 0, 1));
+ dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS);
+ Expect.throws(() => new DateTime(dt.year, dt.month, dt.day,
+ dt.hour, dt.minute, 0, 0, -1));
+ dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
+ Expect.throws(() => new DateTime.utc(dt.year, dt.month, dt.day,
+ dt.hour, dt.minute, 0, 0, -1));
}
void testUTCGetters() {
@@ -291,6 +444,7 @@
Expect.equals(58, dt.minute);
Expect.equals(35, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
Expect.equals(true, dt.isUtc);
Expect.equals(1305140315000, dt.millisecondsSinceEpoch);
dt = new DateTime.fromMillisecondsSinceEpoch(-9999999, isUtc: true);
@@ -301,12 +455,26 @@
Expect.equals(13, dt.minute);
Expect.equals(20, dt.second);
Expect.equals(1, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
+
+ if (!supportsMicroseconds) return;
+
+ dt = new DateTime.fromMicrosecondsSinceEpoch(-9999999999, isUtc: true);
+ Expect.equals(1969, dt.year);
+ Expect.equals(12, dt.month);
+ Expect.equals(31, dt.day);
+ Expect.equals(21, dt.hour);
+ Expect.equals(13, dt.minute);
+ Expect.equals(20, dt.second);
+ Expect.equals(0, dt.millisecond);
+ Expect.equals(1, dt.microsecond);
}
void testLocalGetters() {
var dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000);
var dt2 = new DateTime.utc(dt1.year, dt1.month, dt1.day,
- dt1.hour, dt1.minute, dt1.second, dt1.millisecond);
+ dt1.hour, dt1.minute, dt1.second, dt1.millisecond,
+ dt1.microsecond);
Duration zoneOffset = dt1.difference(dt2);
Expect.equals(true, zoneOffset.inDays == 0);
Expect.equals(true, zoneOffset.inHours.abs() <= 12);
@@ -321,34 +489,40 @@
((dt1.minute - dt2.minute).abs() == 15));
Expect.equals(dt1.second, dt2.second);
Expect.equals(dt1.millisecond, dt2.millisecond);
+ Expect.equals(dt1.microsecond, dt2.microsecond);
}
void testConstructors() {
- var dt0 = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0);
- var dt0b = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0).toLocal();
+ var dt0 = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0, 0);
+ var dt0b = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0, 0).toLocal();
Expect.equals(1305140315000, dt0.millisecondsSinceEpoch);
var dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000);
Expect.equals(dt1.millisecondsSinceEpoch, dt0.millisecondsSinceEpoch);
+ Expect.equals(dt1.microsecondsSinceEpoch, dt0.microsecondsSinceEpoch);
Expect.equals(false, dt1 == dt0);
Expect.equals(true, dt1 == dt0b);
var dt3 = new DateTime(dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
- dt1.second, dt1.millisecond);
+ dt1.second, dt1.millisecond, dt1.microsecond);
Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+ Expect.equals(dt1.microsecondsSinceEpoch, dt3.microsecondsSinceEpoch);
Expect.equals(false, dt3 == dt0);
Expect.equals(true, dt1 == dt3);
dt3 = new DateTime(
dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
- dt1.second, dt1.millisecond);
+ dt1.second, dt1.millisecond, dt1.microsecond);
Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+ Expect.equals(dt1.microsecondsSinceEpoch, dt3.microsecondsSinceEpoch);
Expect.equals(true, dt1 == dt3);
var dt2 = dt1.toLocal();
- dt3 = new DateTime(2011, 5, dt1.day, dt1.hour, dt1.minute, 35, 0);
+ dt3 = new DateTime(2011, 5, dt1.day, dt1.hour, dt1.minute, 35, 0, 0);
Expect.equals(dt2.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+ Expect.equals(dt2.microsecondsSinceEpoch, dt3.microsecondsSinceEpoch);
Expect.equals(true, dt2 == dt3);
dt1 = new DateTime.fromMillisecondsSinceEpoch(-9999999, isUtc: true);
dt3 = new DateTime.utc(dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
dt1.second, dt1.millisecond);
Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+ Expect.equals(dt1.microsecondsSinceEpoch, dt3.microsecondsSinceEpoch);
dt3 = new DateTime.utc(99, 1, 2, 10, 11, 12, 0);
Expect.equals(99, dt3.year);
Expect.equals(1, dt3.month);
@@ -357,6 +531,7 @@
Expect.equals(11, dt3.minute);
Expect.equals(12, dt3.second);
Expect.equals(0, dt3.millisecond);
+ Expect.equals(0, dt3.microsecond);
Expect.equals(true, dt3.isUtc);
var dt4 = new DateTime(99, 1, 2);
Expect.equals(99, dt4.year);
@@ -366,6 +541,7 @@
Expect.equals(0, dt4.minute);
Expect.equals(0, dt4.second);
Expect.equals(0, dt4.millisecond);
+ Expect.equals(0, dt4.microsecond);
Expect.isFalse(dt4.isUtc);
var dt5 = new DateTime.utc(99, 1, 2);
Expect.equals(99, dt5.year);
@@ -375,6 +551,7 @@
Expect.equals(0, dt5.minute);
Expect.equals(0, dt5.second);
Expect.equals(0, dt5.millisecond);
+ Expect.equals(0, dt5.microsecond);
Expect.isTrue(dt5.isUtc);
var dt6 = new DateTime(2012, 2, 27, 13, 27, 0);
Expect.equals(2012, dt6.year);
@@ -384,6 +561,7 @@
Expect.equals(27, dt6.minute);
Expect.equals(0, dt6.second);
Expect.equals(0, dt6.millisecond);
+ Expect.equals(0, dt6.microsecond);
Expect.isFalse(dt6.isUtc);
var dt7 = new DateTime.utc(2012, 2, 27, 13, 27, 0);
Expect.equals(2012, dt7.year);
@@ -393,6 +571,7 @@
Expect.equals(27, dt7.minute);
Expect.equals(0, dt7.second);
Expect.equals(0, dt7.millisecond);
+ Expect.equals(0, dt7.microsecond);
Expect.isTrue(dt7.isUtc);
}
@@ -409,6 +588,7 @@
Expect.equals(dt2.minute, dt3.minute);
Expect.equals(dt2.second, dt3.second);
Expect.equals(dt2.millisecond, dt3.millisecond);
+ Expect.equals(dt2.microsecond, dt3.microsecond);
var dt4 = dt3.toLocal();
Expect.equals(dt1.year, dt4.year);
Expect.equals(dt1.month, dt4.month);
@@ -417,6 +597,7 @@
Expect.equals(dt1.minute, dt4.minute);
Expect.equals(dt1.second, dt4.second);
Expect.equals(dt1.millisecond, dt4.millisecond);
+ Expect.equals(dt1.microsecond, dt4.microsecond);
}
void testSubAdd() {
@@ -430,19 +611,39 @@
Expect.equals(dt1.minute, dt2.minute);
Expect.equals(dt1.second + 3, dt2.second);
Expect.equals(dt1.millisecond + 5, dt2.millisecond);
+ Expect.equals(dt1.microsecond, dt2.microsecond);
var dt3 = dt2.subtract(new Duration(milliseconds:
3 * Duration.MILLISECONDS_PER_SECOND + 5));
Expect.equals(true, dt1 == dt3);
Expect.equals(false, dt1 == dt2);
+
+ if (!supportsMicroseconds) return;
+
+ dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000, isUtc: true);
+ dt2 = dt1.add(new Duration(microseconds:
+ 3 * Duration.MICROSECONDS_PER_SECOND + 5));
+ Expect.equals(dt1.year, dt2.year);
+ Expect.equals(dt1.month, dt2.month);
+ Expect.equals(dt1.day, dt2.day);
+ Expect.equals(dt1.hour, dt2.hour);
+ Expect.equals(dt1.minute, dt2.minute);
+ Expect.equals(dt1.second + 3, dt2.second);
+ Expect.equals(dt1.millisecond, dt2.millisecond);
+ Expect.equals(dt1.microsecond + 5, dt2.microsecond);
+ dt3 = dt2.subtract(new Duration(microseconds:
+ 3 * Duration.MICROSECONDS_PER_SECOND + 5));
+ Expect.equals(true, dt1 == dt3);
+ Expect.equals(false, dt1 == dt2);
}
void testUnderflowAndOverflow() {
- final dtBase = new DateTime(2012, 6, 20, 12, 30, 30, 500);
+ int microsecond = supportsMicroseconds ? 499 : 0;
+ final dtBase = new DateTime(2012, 6, 20, 12, 30, 30, 500, microsecond);
// Millisecond
print(" >>> Millisecond+");
var dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
- dtBase.minute, dtBase.second, 1000);
+ dtBase.minute, dtBase.second, 1000, dtBase.microsecond);
Expect.equals(dtBase.year, dt.year);
Expect.equals(dtBase.month, dt.month);
Expect.equals(dtBase.day, dt.day);
@@ -450,10 +651,11 @@
Expect.equals(dtBase.minute, dt.minute);
Expect.equals(dtBase.second + 1, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(dtBase.microsecond, dt.microsecond);
print(" >>> Millisecond-");
dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
- dtBase.minute, dtBase.second, -1000);
+ dtBase.minute, dtBase.second, -1000, dtBase.microsecond);
Expect.equals(dtBase.year, dt.year);
Expect.equals(dtBase.month, dt.month);
Expect.equals(dtBase.day, dt.day);
@@ -461,11 +663,12 @@
Expect.equals(dtBase.minute, dt.minute);
Expect.equals(dtBase.second - 1, dt.second);
Expect.equals(0, dt.millisecond);
+ Expect.equals(dtBase.microsecond, dt.microsecond);
// Second
print(" >>> Second+");
dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
- dtBase.minute, 60, dtBase.millisecond);
+ dtBase.minute, 60, dtBase.millisecond, dtBase.microsecond);
Expect.equals(dtBase.year, dt.year);
Expect.equals(dtBase.month, dt.month);
Expect.equals(dtBase.day, dt.day);
@@ -473,10 +676,11 @@
Expect.equals(dtBase.minute + 1, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(dtBase.millisecond, dt.millisecond);
+ Expect.equals(dtBase.microsecond, dt.microsecond);
print(" >>> Second-");
dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
- dtBase.minute, -60, dtBase.millisecond);
+ dtBase.minute, -60, dtBase.millisecond, dtBase.microsecond);
Expect.equals(dtBase.year, dt.year);
Expect.equals(dtBase.month, dt.month);
Expect.equals(dtBase.day, dt.day);
@@ -484,11 +688,12 @@
Expect.equals(dtBase.minute - 1, dt.minute);
Expect.equals(0, dt.second);
Expect.equals(dtBase.millisecond, dt.millisecond);
+ Expect.equals(dtBase.microsecond, dt.microsecond);
// Minute
print(" >>> Minute+");
dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour, 60,
- dtBase.second, dtBase.millisecond);
+ dtBase.second, dtBase.millisecond, dtBase.microsecond);
Expect.equals(dtBase.year, dt.year);
Expect.equals(dtBase.month, dt.month);
Expect.equals(dtBase.day, dt.day);
@@ -496,10 +701,11 @@
Expect.equals(0, dt.minute);
Expect.equals(dtBase.second, dt.second);
Expect.equals(dtBase.millisecond, dt.millisecond);
+ Expect.equals(dtBase.microsecond, dt.microsecond);
print(" >>> Minute-");
dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour, -60,
- dtBase.second, dtBase.millisecond);
+ dtBase.second, dtBase.millisecond, dtBase.microsecond);
Expect.equals(dtBase.year, dt.year);
Expect.equals(dtBase.month, dt.month);
Expect.equals(dtBase.day, dt.day);
@@ -507,11 +713,12 @@
Expect.equals(0, dt.minute);
Expect.equals(dtBase.second, dt.second);
Expect.equals(dtBase.millisecond, dt.millisecond);
+ Expect.equals(dtBase.microsecond, dt.microsecond);
// Hour
print(" >>> Hour+");
dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, 24, dtBase.minute,
- dtBase.second, dtBase.millisecond);
+ dtBase.second, dtBase.millisecond, dtBase.microsecond);
Expect.equals(dtBase.year, dt.year);
Expect.equals(dtBase.month, dt.month);
Expect.equals(dtBase.day + 1, dt.day);
@@ -519,10 +726,11 @@
Expect.equals(dtBase.minute, dt.minute);
Expect.equals(dtBase.second, dt.second);
Expect.equals(dtBase.millisecond, dt.millisecond);
+ Expect.equals(dtBase.microsecond, dt.microsecond);
print(" >>> Hour-");
dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, -24, dtBase.minute,
- dtBase.second, dtBase.millisecond);
+ dtBase.second, dtBase.millisecond, dtBase.microsecond);
Expect.equals(dtBase.year, dt.year);
Expect.equals(dtBase.month, dt.month);
Expect.equals(dtBase.day - 1, dt.day);
@@ -530,11 +738,12 @@
Expect.equals(dtBase.minute, dt.minute);
Expect.equals(dtBase.second, dt.second);
Expect.equals(dtBase.millisecond, dt.millisecond);
+ Expect.equals(dtBase.microsecond, dt.microsecond);
// Day
print(" >>> Day+");
dt = new DateTime(dtBase.year, dtBase.month, 31, dtBase.hour, dtBase.minute,
- dtBase.second, dtBase.millisecond);
+ dtBase.second, dtBase.millisecond, dtBase.microsecond);
Expect.equals(dtBase.year, dt.year);
Expect.equals(dtBase.month + 1, dt.month);
Expect.equals(1, dt.day);
@@ -542,10 +751,11 @@
Expect.equals(dtBase.minute, dt.minute);
Expect.equals(dtBase.second, dt.second);
Expect.equals(dtBase.millisecond, dt.millisecond);
+ Expect.equals(dtBase.microsecond, dt.microsecond);
print(" >>> Day-");
dt = new DateTime(dtBase.year, dtBase.month, -30, dtBase.hour, dtBase.minute,
- dtBase.second, dtBase.millisecond);
+ dtBase.second, dtBase.millisecond, dtBase.microsecond);
Expect.equals(dtBase.year, dt.year);
Expect.equals(dtBase.month - 1, dt.month);
Expect.equals(1, dt.day);
@@ -553,11 +763,12 @@
Expect.equals(dtBase.minute, dt.minute);
Expect.equals(dtBase.second, dt.second);
Expect.equals(dtBase.millisecond, dt.millisecond);
+ Expect.equals(dtBase.microsecond, dt.microsecond);
// Month
print(" >>> Month+");
dt = new DateTime(dtBase.year, 13, dtBase.day, dtBase.hour, dtBase.minute,
- dtBase.second, dtBase.millisecond);
+ dtBase.second, dtBase.millisecond, dtBase.microsecond);
Expect.equals(dtBase.year + 1, dt.year);
Expect.equals(1, dt.month);
Expect.equals(dtBase.day, dt.day);
@@ -565,10 +776,11 @@
Expect.equals(dtBase.minute, dt.minute);
Expect.equals(dtBase.second, dt.second);
Expect.equals(dtBase.millisecond, dt.millisecond);
+ Expect.equals(dtBase.microsecond, dt.microsecond);
print(" >>> Month-");
dt = new DateTime(dtBase.year, -11, dtBase.day, dtBase.hour, dtBase.minute,
- dtBase.second, dtBase.millisecond);
+ dtBase.second, dtBase.millisecond, dtBase.microsecond);
Expect.equals(dtBase.year - 1, dt.year);
Expect.equals(1, dt.month);
Expect.equals(dtBase.day, dt.day);
@@ -576,13 +788,14 @@
Expect.equals(dtBase.minute, dt.minute);
Expect.equals(dtBase.second, dt.second);
Expect.equals(dtBase.millisecond, dt.millisecond);
+ Expect.equals(dtBase.microsecond, dt.microsecond);
// Flowing all the way up the chain.
print(" >>> Flow+");
- var dtBase1 = new DateTime(2012, 12, 31, 23, 59, 59, 999);
+ var dtBase1 = new DateTime(2012, 12, 31, 23, 59, 59, 999, 000);
var dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day,
dtBase1.hour, dtBase1.minute, dtBase1.second,
- dtBase1.millisecond + 1);
+ dtBase1.millisecond + 1, dtBase1.microsecond);
Expect.equals(dtBase1.year + 1, dtTick.year);
Expect.equals(1, dtTick.month);
Expect.equals(1, dtTick.day);
@@ -590,11 +803,13 @@
Expect.equals(0, dtTick.minute);
Expect.equals(0, dtTick.second);
Expect.equals(0, dtTick.millisecond);
+ Expect.equals(0, dtTick.microsecond);
print(" >>> Flow-");
dtBase1 = new DateTime(2012, 1, 1, 0, 0, 0, 0);
dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day, dtBase1.hour,
- dtBase1.minute, dtBase1.second, dtBase1.millisecond - 1);
+ dtBase1.minute, dtBase1.second, dtBase1.millisecond - 1,
+ dtBase1.microsecond);
Expect.equals(dtBase1.year - 1, dtTick.year);
Expect.equals(12, dtTick.month);
Expect.equals(31, dtTick.day);
@@ -602,10 +817,12 @@
Expect.equals(59, dtTick.minute);
Expect.equals(59, dtTick.second);
Expect.equals(999, dtTick.millisecond);
+ Expect.equals(0, dtTick.microsecond);
print(" >>> extra underflow");
dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day, -17520,
- dtBase1.minute, dtBase1.second, dtBase1.millisecond);
+ dtBase1.minute, dtBase1.second, dtBase1.millisecond,
+ dtBase1.microsecond);
Expect.equals(dtBase1.year - 2, dtTick.year);
Expect.equals(dtBase1.month, dtTick.month);
Expect.equals(dtBase1.day, dtTick.day);
@@ -613,6 +830,63 @@
Expect.equals(dtBase1.minute, dtTick.minute);
Expect.equals(dtBase1.second, dtTick.second);
Expect.equals(dtBase1.millisecond, dtTick.millisecond);
+ Expect.equals(dtBase1.microsecond, dtTick.microsecond);
+
+ if (!supportsMicroseconds) return;
+
+ // Microsecond
+ print(" >>> Microsecond+");
+ dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
+ dtBase.minute, dtBase.second, dtBase.millisecond, 1000);
+ Expect.equals(dtBase.year, dt.year);
+ Expect.equals(dtBase.month, dt.month);
+ Expect.equals(dtBase.day, dt.day);
+ Expect.equals(dtBase.hour, dt.hour);
+ Expect.equals(dtBase.minute, dt.minute);
+ Expect.equals(dtBase.second, dt.second);
+ Expect.equals(dtBase.millisecond + 1, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
+
+ print(" >>> Microsecond-");
+ dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
+ dtBase.minute, dtBase.second, dtBase.millisecond, -1000);
+ Expect.equals(dtBase.year, dt.year);
+ Expect.equals(dtBase.month, dt.month);
+ Expect.equals(dtBase.day, dt.day);
+ Expect.equals(dtBase.hour, dt.hour);
+ Expect.equals(dtBase.minute, dt.minute);
+ Expect.equals(dtBase.second, dt.second);
+ Expect.equals(dtBase.millisecond - 1, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
+
+ // Flowing all the way up the chain.
+ print(" >>> Flow+ 2");
+ dtBase1 = new DateTime(2012, 12, 31, 23, 59, 59, 999, 999);
+ dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day,
+ dtBase1.hour, dtBase1.minute, dtBase1.second,
+ dtBase1.millisecond, dtBase1.microsecond + 1);
+ Expect.equals(dtBase1.year + 1, dtTick.year);
+ Expect.equals(1, dtTick.month);
+ Expect.equals(1, dtTick.day);
+ Expect.equals(0, dtTick.hour);
+ Expect.equals(0, dtTick.minute);
+ Expect.equals(0, dtTick.second);
+ Expect.equals(0, dtTick.millisecond);
+ Expect.equals(0, dtTick.microsecond);
+
+ print(" >>> Flow- 2");
+ dtBase1 = new DateTime(2012, 1, 1, 0, 0, 0, 0, 0);
+ dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day, dtBase1.hour,
+ dtBase1.minute, dtBase1.second, dtBase1.millisecond,
+ dtBase1.microsecond - 1);
+ Expect.equals(dtBase1.year - 1, dtTick.year);
+ Expect.equals(12, dtTick.month);
+ Expect.equals(31, dtTick.day);
+ Expect.equals(23, dtTick.hour);
+ Expect.equals(59, dtTick.minute);
+ Expect.equals(59, dtTick.second);
+ Expect.equals(999, dtTick.millisecond);
+ Expect.equals(999, dtTick.microsecond);
}
void testDateStrings() {
@@ -640,6 +914,7 @@
Expect.equals(0, dt4.minute);
Expect.equals(0, dt4.second);
Expect.equals(0, dt4.millisecond);
+ Expect.equals(0, dt4.microsecond);
Expect.isTrue(dt4.isUtc);
var dt5 = DateTime.parse("0099-01-02");
Expect.equals(99, dt5.year);
@@ -649,17 +924,23 @@
Expect.equals(0, dt5.minute);
Expect.equals(0, dt5.second);
Expect.equals(0, dt5.millisecond);
+ Expect.equals(0, dt5.microsecond);
Expect.isFalse(dt5.isUtc);
var dt6 = DateTime.parse("2012-01-01 00:00:10.012");
Expect.equals(12, dt6.millisecond);
+ Expect.equals(0, dt6.microsecond);
dt6 = DateTime.parse("2012-01-01 00:00:10.003");
Expect.equals(3, dt6.millisecond);
+ Expect.equals(0, dt6.microsecond);
dt6 = DateTime.parse("2012-01-01 00:00:10.5");
Expect.equals(500, dt6.millisecond);
+ Expect.equals(0, dt6.microsecond);
dt6 = DateTime.parse("2012-01-01 00:00:10.003Z");
Expect.equals(3, dt6.millisecond);
+ Expect.equals(0, dt6.microsecond);
dt6 = DateTime.parse("2012-01-01 00:00:10.5z");
Expect.equals(500, dt6.millisecond);
+ Expect.equals(0, dt6.microsecond);
var dt7 = DateTime.parse("2011-05-11T18:58:35Z");
Expect.equals(1305140315000, dt7.millisecondsSinceEpoch);
var dt8 = DateTime.parse("-1234-01-01T00:00:00Z");
@@ -670,6 +951,7 @@
Expect.equals(0, dt8.minute);
Expect.equals(0, dt8.second);
Expect.equals(0, dt8.millisecond);
+ Expect.equals(0, dt8.microsecond);
Expect.isTrue(dt8.isUtc);
var dt9 = DateTime.parse("-1234-01-01T00:00:00");
Expect.equals(-1234, dt9.year);
@@ -679,6 +961,7 @@
Expect.equals(0, dt9.minute);
Expect.equals(0, dt9.second);
Expect.equals(0, dt9.millisecond);
+ Expect.equals(0, dt9.microsecond);
Expect.isFalse(dt9.isUtc);
var dt10 = DateTime.parse("-12340101");
Expect.equals(-1234, dt10.year);
@@ -688,6 +971,7 @@
Expect.equals(0, dt10.minute);
Expect.equals(0, dt10.second);
Expect.equals(0, dt10.millisecond);
+ Expect.equals(0, dt10.microsecond);
Expect.isFalse(dt10.isUtc);
dt1 = DateTime.parse("2012-02-27 13:27:00");
Expect.equals(2012, dt1.year);
@@ -697,6 +981,7 @@
Expect.equals(27, dt1.minute);
Expect.equals(0, dt1.second);
Expect.equals(0, dt1.millisecond);
+ Expect.equals(0, dt1.microsecond);
Expect.equals(false, dt1.isUtc);
dt1 = DateTime.parse("2012-02-27 13:27:00.423z");
Expect.equals(2012, dt1.year);
@@ -706,6 +991,7 @@
Expect.equals(27, dt1.minute);
Expect.equals(0, dt1.second);
Expect.equals(423, dt1.millisecond);
+ Expect.equals(0, dt1.microsecond);
Expect.equals(true, dt1.isUtc);
dt1 = DateTime.parse("20120227 13:27:00");
Expect.equals(2012, dt1.year);
@@ -715,6 +1001,7 @@
Expect.equals(27, dt1.minute);
Expect.equals(0, dt1.second);
Expect.equals(0, dt1.millisecond);
+ Expect.equals(0, dt1.microsecond);
Expect.equals(false, dt1.isUtc);
dt1 = DateTime.parse("20120227T132700");
Expect.equals(2012, dt1.year);
@@ -724,6 +1011,7 @@
Expect.equals(27, dt1.minute);
Expect.equals(0, dt1.second);
Expect.equals(0, dt1.millisecond);
+ Expect.equals(0, dt1.microsecond);
Expect.equals(false, dt1.isUtc);
dt1 = DateTime.parse("20120227");
Expect.equals(2012, dt1.year);
@@ -733,6 +1021,7 @@
Expect.equals(0, dt1.minute);
Expect.equals(0, dt1.second);
Expect.equals(0, dt1.millisecond);
+ Expect.equals(0, dt1.microsecond);
Expect.equals(false, dt1.isUtc);
dt1 = DateTime.parse("2012-02-27T14Z");
Expect.equals(2012, dt1.year);
@@ -742,6 +1031,7 @@
Expect.equals(0, dt1.minute);
Expect.equals(0, dt1.second);
Expect.equals(0, dt1.millisecond);
+ Expect.equals(0, dt1.microsecond);
Expect.equals(true, dt1.isUtc);
dt1 = DateTime.parse("-123450101 00:00:00 Z");
Expect.equals(-12345, dt1.year);
@@ -751,28 +1041,51 @@
Expect.equals(0, dt1.minute);
Expect.equals(0, dt1.second);
Expect.equals(0, dt1.millisecond);
+ Expect.equals(0, dt1.microsecond);
Expect.equals(true, dt1.isUtc);
- // We only support millisecond. If the user supplies more data (the "51"
- // here), we round.
- // If (eventually) we support more than just millisecond this test could
- // fail. Please update the test in this case.
dt1 = DateTime.parse("1999-01-02 23:59:59.99951");
- Expect.equals(1999, dt1.year);
- Expect.equals(1, dt1.month);
- Expect.equals(3, dt1.day);
- Expect.equals(0, dt1.hour);
- Expect.equals(0, dt1.minute);
- Expect.equals(0, dt1.second);
- Expect.equals(0, dt1.millisecond);
+ if (supportsMicroseconds) {
+ Expect.equals(1999, dt1.year);
+ Expect.equals(1, dt1.month);
+ Expect.equals(2, dt1.day);
+ Expect.equals(23, dt1.hour);
+ Expect.equals(59, dt1.minute);
+ Expect.equals(59, dt1.second);
+ Expect.equals(999, dt1.millisecond);
+ Expect.equals(510, dt1.microsecond);
+ } else {
+ // We only support millisecond. If the user supplies more data (the "51"
+ // here), we round.
+ Expect.equals(1999, dt1.year);
+ Expect.equals(1, dt1.month);
+ Expect.equals(3, dt1.day);
+ Expect.equals(0, dt1.hour);
+ Expect.equals(0, dt1.minute);
+ Expect.equals(0, dt1.second);
+ Expect.equals(0, dt1.millisecond);
+ Expect.equals(0, dt1.microsecond);
+ }
Expect.equals(false, dt1.isUtc);
dt1 = DateTime.parse("1999-01-02 23:58:59.99951Z");
- Expect.equals(1999, dt1.year);
- Expect.equals(1, dt1.month);
- Expect.equals(2, dt1.day);
- Expect.equals(23, dt1.hour);
- Expect.equals(59, dt1.minute);
- Expect.equals(0, dt1.second);
- Expect.equals(0, dt1.millisecond);
+ if (supportsMicroseconds) {
+ Expect.equals(1999, dt1.year);
+ Expect.equals(1, dt1.month);
+ Expect.equals(2, dt1.day);
+ Expect.equals(23, dt1.hour);
+ Expect.equals(58, dt1.minute);
+ Expect.equals(59, dt1.second);
+ Expect.equals(999, dt1.millisecond);
+ Expect.equals(510, dt1.microsecond);
+ } else {
+ Expect.equals(1999, dt1.year);
+ Expect.equals(1, dt1.month);
+ Expect.equals(2, dt1.day);
+ Expect.equals(23, dt1.hour);
+ Expect.equals(59, dt1.minute);
+ Expect.equals(0, dt1.second);
+ Expect.equals(0, dt1.millisecond);
+ Expect.equals(0, dt1.microsecond);
+ }
Expect.equals(true, dt1.isUtc);
dt1 = DateTime.parse("0009-09-09 09:09:09.009Z");
Expect.equals(9, dt1.year);
@@ -866,11 +1179,22 @@
(e) => e is FormatException);
Expect.throws(() => DateTime.parse("275760-09-13T00:00:00.001Z"),
(e) => e is FormatException);
+ if (supportsMicroseconds) {
+ Expect.throws(() => DateTime.parse("275760-09-13T00:00:00.000001Z"),
+ (e) => e is FormatException);
+ } else {
+ dt1 = DateTime.parse("275760-09-13T00:00:00.000001Z");
+ }
// first valid time; should not throw.
dt1 = DateTime.parse("-271821-04-20T00:00:00.000Z");
Expect.throws(() => DateTime.parse("-271821-04-19T23:59:59.999Z"),
(e) => e is FormatException);
+
+ if (supportsMicroseconds) {
+ Expect.throws(() => DateTime.parse("-271821-04-19T23:59:59.999999Z"),
+ (e) => e is FormatException);
+ }
}
void testWeekday() {
@@ -932,6 +1256,14 @@
test("1970-01-01", "00:00:00.000");
test("1969-12-31", "23:59:59.999");
test("1969-09-09", "00:09:09.009");
+
+ if (supportsMicroseconds) {
+ test("2000-01-01", "12:00:00.000001");
+ test("-2000-01-01", "12:00:00.000001");
+ test("1970-01-01", "00:00:00.000001");
+ test("1969-12-31", "23:59:59.999999");
+ test("1969-09-09", "00:09:09.009999");
+ }
}
void testIsoString() {
@@ -952,11 +1284,50 @@
Expect.equals("+010000-01-01T23:59:59.999Z", d.toIso8601String());
d = new DateTime.utc(-10000, 1, 1, 23, 59, 59, 999);
Expect.equals("-010000-01-01T23:59:59.999Z", d.toIso8601String());
+
+ if (!supportsMicroseconds) return;
+
+ d = new DateTime(9999, 1, 1, 23, 59, 59, 999, 999);
+ Expect.equals("9999-01-01T23:59:59.999999", d.toIso8601String());
+ d = new DateTime(-9999, 1, 1, 23, 59, 59, 999, 999);
+ Expect.equals("-9999-01-01T23:59:59.999999", d.toIso8601String());
+ d = new DateTime.utc(9999, 1, 1, 23, 59, 59, 999, 999);
+ Expect.equals("9999-01-01T23:59:59.999999Z", d.toIso8601String());
+ d = new DateTime.utc(-9999, 1, 1, 23, 59, 59, 999, 999);
+ Expect.equals("-9999-01-01T23:59:59.999999Z", d.toIso8601String());
+
+ d = new DateTime(10000, 1, 1, 23, 59, 59, 999, 999);
+ Expect.equals("+010000-01-01T23:59:59.999999", d.toIso8601String());
+ d = new DateTime(-10000, 1, 1, 23, 59, 59, 999, 999);
+ Expect.equals("-010000-01-01T23:59:59.999999", d.toIso8601String());
+ d = new DateTime.utc(10000, 1, 1, 23, 59, 59, 999, 999);
+ Expect.equals("+010000-01-01T23:59:59.999999Z", d.toIso8601String());
+ d = new DateTime.utc(-10000, 1, 1, 23, 59, 59, 999, 999);
+ Expect.equals("-010000-01-01T23:59:59.999999Z", d.toIso8601String());
+
+ d = new DateTime(9999, 1, 1, 23, 49, 59, 989, 979);
+ Expect.equals("9999-01-01T23:49:59.989979", d.toIso8601String());
+ d = new DateTime(-9999, 1, 1, 23, 49, 59, 989, 979);
+ Expect.equals("-9999-01-01T23:49:59.989979", d.toIso8601String());
+ d = new DateTime.utc(9999, 1, 1, 23, 49, 59, 989, 979);
+ Expect.equals("9999-01-01T23:49:59.989979Z", d.toIso8601String());
+ d = new DateTime.utc(-9999, 1, 1, 23, 49, 59, 989, 979);
+ Expect.equals("-9999-01-01T23:49:59.989979Z", d.toIso8601String());
+
+ d = new DateTime(10000, 1, 1, 23, 49, 59, 989, 979);
+ Expect.equals("+010000-01-01T23:49:59.989979", d.toIso8601String());
+ d = new DateTime(-10000, 1, 1, 23, 49, 59, 989, 979);
+ Expect.equals("-010000-01-01T23:49:59.989979", d.toIso8601String());
+ d = new DateTime.utc(10000, 1, 1, 23, 49, 59, 989, 979);
+ Expect.equals("+010000-01-01T23:49:59.989979Z", d.toIso8601String());
+ d = new DateTime.utc(-10000, 1, 1, 23, 49, 59, 989, 979);
+ Expect.equals("-010000-01-01T23:49:59.989979Z", d.toIso8601String());
}
void main() {
testNow();
- testValue();
+ testMillisecondsSinceEpoch();
+ testMicrosecondsSinceEpoch();
testConstructors();
testUTCGetters();
testLocalGetters();
diff --git a/tests/corelib/int_parse_radix_test.dart b/tests/corelib/int_parse_radix_test.dart
index ce68a79..fbe9205 100644
--- a/tests/corelib/int_parse_radix_test.dart
+++ b/tests/corelib/int_parse_radix_test.dart
@@ -20,7 +20,6 @@
for (int i = 0; i < whiteSpace.length; i++) {
var ws = whiteSpace[i];
- print(ws.codeUnitAt(0).toRadixString(16));
Expect.equals(0, int.parse("${ws}0${ws}", radix: 2));
}
@@ -55,8 +54,8 @@
Expect.equals(-result, int.parse("-$zeros$radixString", radix: radix), m);
}
- for (int i = 0; i <= 36 * 36; i++) {
- for (int r = 2; r <= 36; r++) {
+ for (int r = 2; r <= 36; r++) {
+ for (int i = 0; i <= r * r; i++) {
String radixString = i.toRadixString(r);
testParse(i, radixString, r);
}
@@ -89,13 +88,14 @@
void testFails(String source, int radix) {
Expect.throws(() { throw int.parse(source, radix: radix,
onError: (s) { throw "FAIL"; }); },
- (e) => e == "FAIL",
+ isFail,
"$source/$radix");
Expect.equals(-999, int.parse(source, radix: radix, onError: (s) => -999));
}
for (int i = 2; i < 36; i++) {
- testFails(i.toRadixString(36).toLowerCase(), i);
- testFails(i.toRadixString(36).toUpperCase(), i);
+ var char = i.toRadixString(36);
+ testFails(char.toLowerCase(), i);
+ testFails(char.toUpperCase(), i);
}
testFails("", 2);
testFails("+ 1", 2); // No space between sign and digits.
@@ -141,3 +141,5 @@
Expect.throws(() => int.parse("9", radix: 8, onError: () => 42));
Expect.throws(() => int.parse("9", radix: 8, onError: (v1, v2) => 42));
}
+
+bool isFail(e) => e == "FAIL";
diff --git a/tests/html/html.status b/tests/html/html.status
index b5f2cf3..afe5400 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -106,6 +106,10 @@
element_animate_test/omit_timing: RuntimeError # Also timing out on MacOS. Issue 23507
element_animate_test/timing_dict: RuntimeError # Also timing out on MacOS. Issue 23507
element_animate_test/simple_timing: RuntimeError # Please triage this failure
+element_types_test/supported_object: RuntimeError # Issue 25155
+element_types_test/supported_embed: RuntimeError # Issue 25155
+event_test: Pass, RuntimeError # Issue 25158 Passes on 46, fails on 47
+history_test/history: Pass, RuntimeError # Issue 25158, passes on 46 fails on 47
[ $runtime == chrome && $system == macos ]
canvasrenderingcontext2d_test/drawImage_video_element: Skip # Times out. Please triage this failure.
diff --git a/tests/html/websocket_test.dart b/tests/html/websocket_test.dart
index f8ba1ba..1715c88 100644
--- a/tests/html/websocket_test.dart
+++ b/tests/html/websocket_test.dart
@@ -35,6 +35,16 @@
return socket.onMessage.first.then((MessageEvent e) {
expect(e.data, 'hello!');
+ socket.close();
+ });
+ });
+
+ test('error handling', () {
+ var socket = new WebSocket('ws://${window.location.host}/ws');
+ socket.onOpen.first.then((_) => socket.send('close-with-error'));
+ return socket.onError.first.then((e) {
+ print('$e was caught, yay!');
+ socket.close();
});
});
}
diff --git a/tests/language/config_import_lib1a.dart b/tests/language/config_import_lib1a.dart
new file mode 100644
index 0000000..814c15e
--- /dev/null
+++ b/tests/language/config_import_lib1a.dart
@@ -0,0 +1,5 @@
+// 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.
+
+String lib1() => "a";
diff --git a/tests/language/config_import_lib1b.dart b/tests/language/config_import_lib1b.dart
new file mode 100644
index 0000000..59212de
--- /dev/null
+++ b/tests/language/config_import_lib1b.dart
@@ -0,0 +1,5 @@
+// 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.
+
+String lib1() => "b";
diff --git a/tests/language/config_import_lib1c.dart b/tests/language/config_import_lib1c.dart
new file mode 100644
index 0000000..86fd9e9
--- /dev/null
+++ b/tests/language/config_import_lib1c.dart
@@ -0,0 +1,5 @@
+// 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.
+
+String lib1() => "c";
diff --git a/tests/language/config_import_lib2a.dart b/tests/language/config_import_lib2a.dart
new file mode 100644
index 0000000..00665dd
--- /dev/null
+++ b/tests/language/config_import_lib2a.dart
@@ -0,0 +1,5 @@
+// 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.
+
+String lib2() => "a";
diff --git a/tests/language/config_import_lib2b.dart b/tests/language/config_import_lib2b.dart
new file mode 100644
index 0000000..6d91daf
--- /dev/null
+++ b/tests/language/config_import_lib2b.dart
@@ -0,0 +1,5 @@
+// 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.
+
+String lib2() => "b";
diff --git a/tests/language/config_import_lib2c.dart b/tests/language/config_import_lib2c.dart
new file mode 100644
index 0000000..6ed0235
--- /dev/null
+++ b/tests/language/config_import_lib2c.dart
@@ -0,0 +1,5 @@
+// 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.
+
+String lib2() => "c";
diff --git a/tests/language/config_import_lib3a.dart b/tests/language/config_import_lib3a.dart
new file mode 100644
index 0000000..c2f9fec
--- /dev/null
+++ b/tests/language/config_import_lib3a.dart
@@ -0,0 +1,5 @@
+// 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.
+
+String lib3() => "a";
diff --git a/tests/language/config_import_lib3b.dart b/tests/language/config_import_lib3b.dart
new file mode 100644
index 0000000..b6d5afc
--- /dev/null
+++ b/tests/language/config_import_lib3b.dart
@@ -0,0 +1,5 @@
+// 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.
+
+String lib3() => "b";
diff --git a/tests/language/config_import_lib3c.dart b/tests/language/config_import_lib3c.dart
new file mode 100644
index 0000000..b984783
--- /dev/null
+++ b/tests/language/config_import_lib3c.dart
@@ -0,0 +1,5 @@
+// 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.
+
+String lib3() => "c";
diff --git a/tests/language/config_import_lib4a.dart b/tests/language/config_import_lib4a.dart
new file mode 100644
index 0000000..1607f07
--- /dev/null
+++ b/tests/language/config_import_lib4a.dart
@@ -0,0 +1,5 @@
+// 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.
+
+String lib4() => "a";
diff --git a/tests/language/config_import_lib4b.dart b/tests/language/config_import_lib4b.dart
new file mode 100644
index 0000000..9e2f08c
--- /dev/null
+++ b/tests/language/config_import_lib4b.dart
@@ -0,0 +1,5 @@
+// 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.
+
+String lib4() => "b";
diff --git a/tests/language/config_import_lib4c.dart b/tests/language/config_import_lib4c.dart
new file mode 100644
index 0000000..f4a1972
--- /dev/null
+++ b/tests/language/config_import_lib4c.dart
@@ -0,0 +1,5 @@
+// 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.
+
+String lib4() => "c";
diff --git a/tests/language/config_import_test.dart b/tests/language/config_import_test.dart
new file mode 100644
index 0000000..5678e8e
--- /dev/null
+++ b/tests/language/config_import_test.dart
@@ -0,0 +1,30 @@
+// 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.
+//
+// DartOptions=-Did=true -Ddotted.id=some_string -Dlots.of.dots.In.id=false --conditional-directives
+
+import 'package:expect/expect.dart';
+
+import 'config_import_lib1a.dart'
+ if (id) 'config_import_lib1b.dart'
+ if (not.set.id) 'config_import_lib1c.dart';
+
+import 'config_import_lib2a.dart'
+ if (not.set.id) 'config_import_lib2b.dart'
+ if (not.set.either) 'config_import_lib2c.dart';
+
+import 'config_import_lib3a.dart'
+ if (dotted.id == "some_string") 'config_import_lib3b.dart'
+ if (id) 'config_import_lib3c.dart';
+
+import 'config_import_lib4a.dart'
+ if (lots.of.dots.In.id == "other") 'config_import_lib4b.dart'
+ if (lots.of.dots.In.id == "false") 'config_import_lib4c.dart';
+
+main() {
+ Expect.equals("b", lib1());
+ Expect.equals("a", lib2());
+ Expect.equals("b", lib3());
+ Expect.equals("c", lib4());
+}
diff --git a/tests/language/const_for_in_variable_test.dart b/tests/language/const_for_in_variable_test.dart
new file mode 100644
index 0000000..a12cd55
--- /dev/null
+++ b/tests/language/const_for_in_variable_test.dart
@@ -0,0 +1,12 @@
+// 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.
+
+main() {
+ for(
+ const /// 01: compile-time error
+ final /// 02: ok
+ int x in const [1, 2, 3]) {
+ break;
+ }
+}
\ No newline at end of file
diff --git a/tests/language/const_getter_test.dart b/tests/language/const_getter_test.dart
new file mode 100644
index 0000000..97717e8
--- /dev/null
+++ b/tests/language/const_getter_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// Check that const getters are not allowed.
+
+import 'package:expect/expect.dart';
+
+class C {
+ const C();
+
+ const /// 01: compile-time error
+ get x => 1;
+}
+
+const /// 02: compile-time error
+get y => 2;
+
+main() {
+ Expect.equals(1, const C().x);
+ Expect.equals(2, y);
+}
diff --git a/tests/language/const_map2_test.dart b/tests/language/const_map2_test.dart
index 6b599f7..d32ca5b 100644
--- a/tests/language/const_map2_test.dart
+++ b/tests/language/const_map2_test.dart
@@ -14,10 +14,8 @@
operator ==(o) => true; /// 00: compile-time error
}
-confuse(x) {
- if (new DateTime.now() == 42) return confuse(2);
- return x;
-}
+@NoInline() @AssumeDynamic()
+confuse(x) => x;
main() {
// It is a compile-time error if the key type overrides operator ==.
diff --git a/tests/language/const_map_test.dart b/tests/language/const_map_test.dart
index 96db1d6..9cc0d5b 100644
--- a/tests/language/const_map_test.dart
+++ b/tests/language/const_map_test.dart
@@ -7,11 +7,8 @@
/// Returns its argument.
///
/// Prevents static optimizations and inlining.
-confuse(x) {
- // DateTime.now() cannot be predicted statically.
- if (new DateTime.now() == 42) return confuse(2);
- return x;
-}
+@NoInline() @AssumeDynamic()
+confuse(x) => x;
main() {
// Make sure that const maps use the == operator and not identical. The
diff --git a/tests/language/language.status b/tests/language/language.status
index 8c5eb92..0d4a45c 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -31,6 +31,9 @@
async_star_cancel_while_paused_test: RuntimeError
async_star_await_pauses_test: Skip # Times out. Issue 23996
+# Unsupported configuration specific imports.
+config_import_test: Fail # Issue 24581
+
[ $compiler == none && $runtime == vm ]
class_keyword_test/02: MissingCompileTimeError # Issue 13627
unicode_bom_test: Fail # Issue 16067
@@ -135,6 +138,5 @@
tearoff_basic_test: RuntimeError, Crash # Conflicting flag.
vm/type_cast_vm_test: RuntimeError # Line number mismatch.
regress_23408_test: RuntimeError
-issue21159_test: Pass, Crash, Timeout # Issue 24659 - missing stack overflow check
stack_trace_test: Fail # Issue 24783 - inlined frames missing
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index a5f91bf..a6eb91c 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -63,7 +63,7 @@
# TBF: we should check conflicts not only for methods, but for accessors too
override_field_test/03: fail
-method_override7_test/03: Fail # Issue 11496
+method_override7_test/03: Fail # Issue 11497
external_test/21: Fail
external_test/24: Fail
@@ -85,6 +85,11 @@
multiline_newline_test/05: MissingCompileTimeError # Issue 23888
multiline_newline_test/06: MissingCompileTimeError # Issue 23888
+const_for_in_variable_test/01: MissingCompileTimeError # Issue 25161
+
+# Unsupported configuration specific imports.
+config_import_test: CompileTimeError # Issue 24579
+
# Please add new failing tests before this line.
# Section below is for invalid tests.
#
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index 27be7e0..ac93e88 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -22,7 +22,7 @@
# TBF: we should check conflicts not only for methods, but for accessors too
override_field_test/03: fail
-method_override7_test/03: Fail # Issue 11496
+method_override7_test/03: Fail # Issue 11497
external_test/21: Fail
external_test/24: Fail
@@ -37,6 +37,11 @@
multiline_newline_test/05: MissingCompileTimeError # Issue 23888
multiline_newline_test/06: MissingCompileTimeError # Issue 23888
+const_for_in_variable_test/01: MissingCompileTimeError # Issue 25161
+
+# Unsupported configuration specific imports.
+config_import_test: CompileTimeError # Issue 24579
+
# Please add new failing tests before this line.
# Section below is for invalid tests.
#
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 1767b22..e872f46 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -3,9 +3,6 @@
# BSD-style license that can be found in the LICENSE file.
[ $compiler == dart2js ]
-sync_generator2_test/07: MissingCompileTimeError # Issue 22324
-sync_generator2_test/08: MissingCompileTimeError # Issue 22324
-sync_generator2_test/10: MissingCompileTimeError # Issue 22324
getter_setter_in_lib_test: Fail # Issue 23288
async_star_cancel_while_paused_test: RuntimeError # Issue 22853
@@ -22,6 +19,9 @@
await_for_test: Skip # Jsshell does not provide periodic timers, Issue 7728
async_star_test: RuntimeError # Jsshell does not provide non-zero timers, Issue 7728
+[ $compiler == dart2js && $browser ]
+config_import_test: Fail # Test flag is not passed to the compiler.
+
[ $compiler == dart2js ]
invocation_mirror_empty_arguments_test: Fail # Issue 24331
nan_identical_test: Fail # Issue 11551
@@ -131,10 +131,6 @@
symbol_conflict_test: RuntimeError # Issue 23857
[ $compiler == dart2js ]
-async_await_syntax_test/a05h: Fail # 23716
-async_await_syntax_test/c11a: Fail # 23716
-async_await_syntax_test/c11b: Fail # 23716
-
malformed_test/none: Fail # Expect failure in lib/_internal/js_runtime/lib/preambles/d8.js
type_variable_conflict2_test/01: RuntimeError # Issue 19725
@@ -148,9 +144,7 @@
mint_arithmetic_test: RuntimeError # Issue 1533
left_shift_test: RuntimeError # Issue 1533
regress_24283_test: RuntimeError # Issue 1533
-bad_override_test/01: CompileTimeError # Issue 11496
-bad_override_test/02: CompileTimeError # Issue 11496
-constructor_named_arguments_test/01: CompileTimeError # Issue 5519
+constructor_named_arguments_test/01: CompileTimeError # Issue 25225
not_enough_positional_arguments_test/01: CompileTimeError # Issue 12838
not_enough_positional_arguments_test/02: CompileTimeError # Issue 12838
not_enough_positional_arguments_test/05: CompileTimeError # Issue 12838
@@ -224,7 +218,7 @@
generic_field_mixin5_test: Crash # Issue 18651
many_method_calls_test: Crash # Stack overflow in HGraphVisitor.visitPostDominatorTree.visitBasicBlockAndSuccessors
-[ $compiler == dart2js ]
+[ $compiler == dart2js && $runtime != drt && $runtime != dartium ]
issue23244_test: RuntimeError # 23244
[ $compiler == dart2js && $cps_ir ]
@@ -280,7 +274,6 @@
closure_in_constructor_test: RuntimeError # Please triage this failure.
closures_initializer_test: RuntimeError # Please triage this failure.
constructor12_test: RuntimeError # Please triage this failure.
-crash_6725_test/01: Crash # unsupported operation on erroneous element
deferred_call_empty_before_load_test: Crash # (lib1.thefun()): deferred access is not implemented
deferred_closurize_load_library_test: RuntimeError # D.loadLibrary is not a function
deferred_constant_list_test: RuntimeError # K.loadLibrary is not a function
diff --git a/tests/language/null_test.dart b/tests/language/null_test.dart
index 83ffd7b..ecb2e00 100644
--- a/tests/language/null_test.dart
+++ b/tests/language/null_test.dart
@@ -36,13 +36,9 @@
// Magic incantation to avoid the compiler recognizing the constant values
// at compile time. If the result is computed at compile time, the dynamic code
// will not be tested.
-confuse(x) {
- try {
- if (new DateTime.now().millisecondsSinceEpoch == 42) x = 42;
- throw [x];
- } on dynamic catch (e) { return e[0]; }
- return 42;
-}
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
void main() {
for (int i = 0; i < 10; i++) {
diff --git a/tests/language/range_analysis3_test.dart b/tests/language/range_analysis3_test.dart
index 5628e46..8777212 100644
--- a/tests/language/range_analysis3_test.dart
+++ b/tests/language/range_analysis3_test.dart
@@ -4,14 +4,9 @@
import "package:expect/expect.dart";
-confuse(x) {
- if (new DateTime.now().millisecondsSinceEpoch == 0) {
- return confuse(x + 1);
- } else if (new DateTime.now().millisecondsSinceEpoch == 0) {
- return confuse(x - 1);
- }
- return x;
-}
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x is int ? x : 0;
test1() {
int x = 0;
@@ -207,4 +202,4 @@
test3b();
test4a();
test4b();
-}
\ No newline at end of file
+}
diff --git a/tests/language/regress_25122_test.dart b/tests/language/regress_25122_test.dart
new file mode 100644
index 0000000..b7d4068
--- /dev/null
+++ b/tests/language/regress_25122_test.dart
@@ -0,0 +1,10 @@
+// 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.
+
+main() {}
+
+class AbstractListMember<E, M extends AbstractListMember<E, M>> {}
+
+class RepoListMember<M extends RepoListMember<M>>
+ extends AbstractListMember<String, M> {}
diff --git a/tests/language/syncstar_less_than_test.dart b/tests/language/syncstar_less_than_test.dart
index b0551a8..db2f6f3 100644
--- a/tests/language/syncstar_less_than_test.dart
+++ b/tests/language/syncstar_less_than_test.dart
@@ -4,7 +4,8 @@
import "package:expect/expect.dart";
-confuse(x) => [1, 'x', true, null, x].last;
+@NoInline() @AssumeDynamic()
+confuse(x) => x;
Iterable<int> foo() sync* {
var a = confuse(1);
@@ -15,4 +16,4 @@
main() {
Expect.listEquals(foo().toList(), [2]);
-}
\ No newline at end of file
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 079fa14..12ceb29 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -64,12 +64,6 @@
mirrors/load_library_test: RuntimeError # Issue 6335
mirrors/local_function_is_static_test: RuntimeError # Issue 6335
mirrors/lru_test: Skip # dart2js_native/lru_test is used instead
-mirrors/metadata_allowed_values_test/01: MissingCompileTimeError # Issue 14548
-mirrors/metadata_allowed_values_test/05: MissingCompileTimeError # Issue 14548
-mirrors/metadata_allowed_values_test/10: MissingCompileTimeError # Issue 14548
-mirrors/metadata_allowed_values_test/11: MissingCompileTimeError # Issue 14548
-mirrors/metadata_allowed_values_test/13: MissingCompileTimeError # Issue 14548
-mirrors/metadata_allowed_values_test/14: MissingCompileTimeError # Issue 14548
mirrors/metadata_scope_test/none: CompileTimeError # Issue 10905
mirrors/method_mirror_name_test: RuntimeError # Issue 6335
mirrors/method_mirror_properties_test: RuntimeError # Issue 11861
diff --git a/tests/standalone/array_bounds_check_generalization_test.dart b/tests/standalone/array_bounds_check_generalization_test.dart
index bfd0cce..2b6099d 100644
--- a/tests/standalone/array_bounds_check_generalization_test.dart
+++ b/tests/standalone/array_bounds_check_generalization_test.dart
@@ -2,7 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
-// VMOptions=--optimization_counter_threshold=10 --no-use-osr
+// We are using --complete-timeline below to ensure that we get timeline events
+// generated during all phases of compilation and deoptimization.
+// VMOptions=--optimization_counter_threshold=10 --no-use-osr --complete-timeline
import "package:expect/expect.dart";
diff --git a/tests/try/poi/serialize_test.dart b/tests/try/poi/serialize_test.dart
index b77327e..c890b8b 100644
--- a/tests/try/poi/serialize_test.dart
+++ b/tests/try/poi/serialize_test.dart
@@ -519,15 +519,15 @@
"kind": "class"
},
{
+ "name": "Match",
+ "kind": "class"
+ },
+ {
"name": "print",
"kind": "function",
"type": "(Object) -> void"
},
{
- "name": "Match",
- "kind": "class"
- },
- {
"name": "RegExp",
"kind": "class"
},
diff --git a/tests/try/try.status b/tests/try/try.status
index e256bca..d6d7ca7 100644
--- a/tests/try/try.status
+++ b/tests/try/try.status
@@ -39,9 +39,6 @@
[ $compiler == dart2js ]
poi/*: Skip # Issue 20031
-[ $compiler == dart2js && $runtime == none ]
-poi/serialize_test: RuntimeError # Issue 25125
-
[ $compiler == dart2js ]
# Compilation is slow, test fails at runtime due to time out, but
# unpredictably.
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index 5b2f041..1f6c520 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -10,9 +10,6 @@
recursive_import_test: Slow, Pass
source_mirrors_test: Slow, Pass
-[ $compiler == none && $runtime == drt ]
-dummy_compiler_test: Skip # Issue 7233
-
[ $compiler == dart2js && $browser ]
*: Skip
diff --git a/tools/VERSION b/tools/VERSION
index 7d5050b..433c092 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 1
MINOR 14
PATCH 0
-PRERELEASE 3
+PRERELEASE 4
PRERELEASE_PATCH 0
diff --git a/tools/bots/bot_utils.py b/tools/bots/bot_utils.py
index da166aa..53bd1ca 100644
--- a/tools/bots/bot_utils.py
+++ b/tools/bots/bot_utils.py
@@ -71,7 +71,7 @@
Under every base path, the following structure is used:
- /VERSION
- - /api-docs/{dart-api-docs.zip,dartdocs-gen-api.zip}
+ - /api-docs/dartdocs-gen-api.zip
- /dartium/{chromedriver,content_shell,dartium}
-{linux,macos,windows}-{ia32,x64}-release.zip
- /sdk/dartsdk-{linux,macos,windows}-{ia32,x64}-release.zip
@@ -119,6 +119,10 @@
return '/'.join([self.dartium_directory(revision),
self.dartium_variant_zipfilename(name, system, arch, mode)])
+ def apidocs_zipfilepath(self, revision):
+ return '/'.join([self.apidocs_directory(revision),
+ self.dartdocs_zipfilename()])
+
def dartium_android_apk_filepath(self, revision, name, arch, mode):
return '/'.join([self.dartium_android_directory(revision),
self.dartium_android_apk_filename(name, arch, mode)])
@@ -162,9 +166,6 @@
def dartium_android_apk_filename(self, name, arch, mode):
return '%s-%s-%s.apk' % (name, arch, mode)
- def apidocs_zipfilename(self):
- return 'dart-api-docs.zip'
-
def dartdocs_zipfilename(self):
return 'dartdocs-gen-api.zip'
diff --git a/tools/dom/dom.py b/tools/dom/dom.py
index e0bbfdd..c69d065 100755
--- a/tools/dom/dom.py
+++ b/tools/dom/dom.py
@@ -139,7 +139,7 @@
return call(cmd)
def test_server():
- start_test_server(5400, os.path.join('out', 'ReleaseIA32'))
+ start_test_server(5400, os.path.join('out', 'ReleaseX64'))
def test_server_dartium():
start_test_server(5500, os.path.join('..', 'out', 'Release'))
diff --git a/tools/promote.py b/tools/promote.py
index d3013ab..81ab402 100644
--- a/tools/promote.py
+++ b/tools/promote.py
@@ -131,11 +131,10 @@
remove_gs_directory(to_loc)
Gsutil(['-m', 'cp', '-a', 'public-read', '-R', from_loc, to_loc])
- # Copy api-docs directory.
- from_loc = raw_namer.apidocs_directory(revision)
- to_loc = release_namer.apidocs_directory(to_revision)
- remove_gs_directory(to_loc)
- Gsutil(['-m', 'cp', '-a', 'public-read', '-R', from_loc, to_loc])
+ # Copy api-docs zipfile.
+ from_loc = raw_namer.apidocs_zipfilepath(revision)
+ to_loc = release_namer.apidocs_zipfilepath(to_revision)
+ Gsutil(['-m', 'cp', '-a', 'public-read', from_loc, to_loc])
# Copy dartium directory.
from_loc = raw_namer.dartium_directory(revision)
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index 7f5fae7..843aaaf 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -260,7 +260,13 @@
websocket.done.catchError((_) {});
websocket.listen((data) {
websocket.add(data);
- websocket.close();
+ if (data == 'close-with-error') {
+ // Note: according to the web-sockets spec, a reason longer than 123
+ // bytes will produce a SyntaxError on the client.
+ websocket.close(WebSocketStatus.UNSUPPORTED_DATA, 'X' * 124);
+ } else {
+ websocket.close();
+ }
}, onError: (e) {
DebugLogger.warning('HttpServer: error while echoing to WebSocket', e);
});